| Index: src/gpu/gl/GrGLGpu.cpp
|
| diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
|
| index e8b575584933a19ad8e89d03eb510f8936a52244..f9d0f985cc476ba5539f624130d12caaf41f41ce 100644
|
| --- a/src/gpu/gl/GrGLGpu.cpp
|
| +++ b/src/gpu/gl/GrGLGpu.cpp
|
| @@ -194,6 +194,7 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
|
| , fTempSrcFBOID(0)
|
| , fTempDstFBOID(0)
|
| , fStencilClearFBOID(0)
|
| + , fHWMaxUsedBufferTextureUnit(-1)
|
| , fHWPLSEnabled(false)
|
| , fPLSHasBeenUsed(false)
|
| , fHWMinSampleShading(0.0) {
|
| @@ -223,6 +224,10 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
|
| }
|
| GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState));
|
|
|
| + if (this->caps()->shaderCaps()->texelBufferSupport()) {
|
| + fHWBufferTextures.reset(this->glCaps().glslCaps()->maxCombinedSamplers());
|
| + }
|
| +
|
| if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
|
| fPathRendering.reset(new GrGLPathRendering(this));
|
| }
|
| @@ -522,6 +527,10 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
|
| for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) {
|
| fHWBoundTextureUniqueIDs[s] = SK_InvalidUniqueID;
|
| }
|
| + for (int b = 0; b < fHWBufferTextures.count(); ++b) {
|
| + SkASSERT(this->caps()->shaderCaps()->texelBufferSupport());
|
| + fHWBufferTextures[b].fKnownBound = false;
|
| + }
|
| }
|
|
|
| if (resetBits & kBlend_GrGLBackendState) {
|
| @@ -2052,14 +2061,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
|
| this->flushBlend(blendInfo, swizzle);
|
| }
|
|
|
| - SkSTArray<8, const GrTextureAccess*> textureAccesses;
|
| - program->setData(primProc, pipeline, &textureAccesses);
|
| -
|
| - int numTextureAccesses = textureAccesses.count();
|
| - for (int i = 0; i < numTextureAccesses; i++) {
|
| - this->bindTexture(i, textureAccesses[i]->getParams(), pipeline.getAllowSRGBInputs(),
|
| - static_cast<GrGLTexture*>(textureAccesses[i]->getTexture()));
|
| - }
|
| + program->setData(primProc, pipeline, pipeline.getAllowSRGBInputs());
|
|
|
| GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
|
| this->flushStencil(pipeline.getStencil());
|
| @@ -2147,6 +2149,31 @@ GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrGLBuffer* buffer) {
|
| return bufferState.fGLTarget;
|
| }
|
|
|
| +void GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) {
|
| + if (buffer->hasAttachedToTexture()) {
|
| + // Detach this buffer from any textures to ensure the underlying memory is freed.
|
| + uint32_t uniqueID = buffer->getUniqueID();
|
| + for (int i = fHWMaxUsedBufferTextureUnit; i >= 0; --i) {
|
| + auto& buffTex = fHWBufferTextures[i];
|
| + if (uniqueID != buffTex.fAttachedBufferUniqueID) {
|
| + continue;
|
| + }
|
| + if (i == fHWMaxUsedBufferTextureUnit) {
|
| + --fHWMaxUsedBufferTextureUnit;
|
| + }
|
| +
|
| + this->setTextureUnit(i);
|
| + if (!buffTex.fKnownBound) {
|
| + SkASSERT(buffTex.fTextureID);
|
| + GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID));
|
| + buffTex.fKnownBound = true;
|
| + }
|
| + GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER,
|
| + this->glCaps().configSizedInternalFormat(buffTex.fTexelConfig), 0));
|
| + }
|
| + }
|
| +}
|
| +
|
| void GrGLGpu::disableScissor() {
|
| if (kNo_TriState != fHWScissorSettings.fEnabled) {
|
| GL_CALL(Disable(GR_GL_SCISSOR_TEST));
|
| @@ -3264,21 +3291,78 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, bool dstCo
|
| (setAll || memcmp(newTexParams.fSwizzleRGBA,
|
| oldTexParams.fSwizzleRGBA,
|
| sizeof(newTexParams.fSwizzleRGBA)))) {
|
| + this->setTextureSwizzle(unitIdx, target, newTexParams.fSwizzleRGBA);
|
| + }
|
| + texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
|
| +}
|
| +
|
| +void GrGLGpu::bindTexelBuffer(int unitIdx, intptr_t offsetInBytes, GrPixelConfig texelConfig,
|
| + GrGLBuffer* buffer) {
|
| + SkASSERT(this->glCaps().canUseConfigWithTexelBuffer(texelConfig));
|
| + SkASSERT(unitIdx >= 0 && unitIdx < fHWBufferTextures.count());
|
| + SkASSERT(offsetInBytes >= 0 && offsetInBytes < (intptr_t) buffer->glSizeInBytes());
|
| +
|
| + BufferTexture& buffTex = fHWBufferTextures[unitIdx];
|
| +
|
| + if (!buffTex.fKnownBound) {
|
| + if (!buffTex.fTextureID) {
|
| + GL_CALL(GenTextures(1, &buffTex.fTextureID));
|
| + if (!buffTex.fTextureID) {
|
| + return;
|
| + }
|
| + }
|
| +
|
| this->setTextureUnit(unitIdx);
|
| - if (this->glStandard() == kGLES_GrGLStandard) {
|
| - // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
|
| - const GrGLenum* swizzle = newTexParams.fSwizzleRGBA;
|
| - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
|
| - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
|
| - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
|
| - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
|
| - } else {
|
| - GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGLint));
|
| - const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexParams.fSwizzleRGBA);
|
| - GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle));
|
| + GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID));
|
| +
|
| + buffTex.fKnownBound = true;
|
| + }
|
| +
|
| + if (buffer->getUniqueID() != buffTex.fAttachedBufferUniqueID ||
|
| + buffTex.fOffsetInBytes != offsetInBytes ||
|
| + buffTex.fTexelConfig != texelConfig ||
|
| + buffTex.fAttachedSizeInBytes != buffer->glSizeInBytes() - offsetInBytes) {
|
| +
|
| + size_t attachmentSizeInBytes = buffer->glSizeInBytes() - offsetInBytes;
|
| +
|
| + this->setTextureUnit(unitIdx);
|
| + GL_CALL(TexBufferRange(GR_GL_TEXTURE_BUFFER,
|
| + this->glCaps().configSizedInternalFormat(texelConfig),
|
| + buffer->bufferID(),
|
| + offsetInBytes,
|
| + attachmentSizeInBytes));
|
| +
|
| + buffTex.fOffsetInBytes = offsetInBytes;
|
| + buffTex.fTexelConfig = texelConfig;
|
| + buffTex.fAttachedSizeInBytes = attachmentSizeInBytes;
|
| + buffTex.fAttachedBufferUniqueID = buffer->getUniqueID();
|
| +
|
| + if (this->glCaps().textureSwizzleSupport() &&
|
| + this->glCaps().configSwizzle(texelConfig) != buffTex.fSwizzle) {
|
| + GrGLenum glSwizzle[4];
|
| + get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle);
|
| + this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle);
|
| + buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig);
|
| }
|
| +
|
| + buffer->setHasAttachedToTexture();
|
| + fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUnit);
|
| + }
|
| +}
|
| +
|
| +void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]) {
|
| + this->setTextureUnit(unitIdx);
|
| + if (this->glStandard() == kGLES_GrGLStandard) {
|
| + // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
|
| + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
|
| + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
|
| + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
|
| + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
|
| + } else {
|
| + GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint));
|
| + GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA,
|
| + reinterpret_cast<const GrGLint*>(swizzle)));
|
| }
|
| - texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
|
| }
|
|
|
| void GrGLGpu::flushColorWrite(bool writeColor) {
|
|
|