diff options
Diffstat (limited to 'src/gpu/gl/GrGLGpu.cpp')
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 124 |
1 files changed, 104 insertions, 20 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index e8b5755849..af5955014a 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); 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) { |