diff options
author | bsalomon <bsalomon@google.com> | 2015-02-23 09:27:45 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-23 09:27:45 -0800 |
commit | dd3143b0079f01980ca4886f00c39b3caa3fee6a (patch) | |
tree | 1ccd265c2e2dd594ba73eecc4c6c34fdb8126a38 /src/gpu/gl | |
parent | 6bc1b5fab8554a9cb643277b4867965dd4535cd6 (diff) |
clear stencil buffer using special purpose FBO
Review URL: https://codereview.chromium.org/941383003
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 40 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 2 |
2 files changed, 41 insertions, 1 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 8710931301..9c0f772f41 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -153,6 +153,7 @@ GrGLGpu::GrGLGpu(const GrGLContext& ctx, GrContext* context) fHWProgramID = 0; fTempSrcFBOID = 0; fTempDstFBOID = 0; + fStencilClearFBOID = 0; if (this->glCaps().pathRenderingSupport()) { fPathRendering.reset(new GrGLPathRendering(this)); @@ -173,6 +174,9 @@ GrGLGpu::~GrGLGpu() { if (0 != fTempDstFBOID) { GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); } + if (0 != fStencilClearFBOID) { + GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); + } delete fProgramCache; } @@ -183,6 +187,7 @@ void GrGLGpu::contextAbandoned() { fHWProgramID = 0; fTempSrcFBOID = 0; fTempDstFBOID = 0; + fStencilClearFBOID = 0; if (this->glCaps().pathRenderingSupport()) { this->glPathRendering()->abandonGpuResources(); } @@ -1172,11 +1177,44 @@ bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, int width, // whatever sizes GL gives us. In that case we query for the size. GrGLStencilBuffer::Format format = sFmt; get_stencil_rb_sizes(this->glInterface(), &format); - SkAutoTUnref<GrStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, + SkAutoTUnref<GrGLStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, (this, sbDesc, width, height, samples, format))); if (this->attachStencilBufferToRenderTarget(sb, rt)) { fLastSuccessfulStencilFmtIdx = sIdx; rt->renderTargetPriv().didAttachStencilBuffer(sb); + + // Clear the stencil buffer. We use a special purpose FBO for this so that the + // entire stencil buffer is cleared, even if it is attached to an FBO with a + // smaller color target. + if (0 == fStencilClearFBOID) { + GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); + } + + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); + fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; + fStats.incRenderTargetBinds(); + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_STENCIL_ATTACHMENT, + GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); + if (sFmt.fPacked) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_DEPTH_ATTACHMENT, + GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); + } + + GL_CALL(ClearStencil(0)); + GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); + + // Unbind the SB from the FBO so that we don't keep it alive. + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_STENCIL_ATTACHMENT, + GR_GL_RENDERBUFFER, 0)); + if (sFmt.fPacked) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_DEPTH_ATTACHMENT, + GR_GL_RENDERBUFFER, 0)); + } + return true; } // Remove the scratch key from this resource so we don't grab it from the cache ever diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 7cbca0108d..b93080b700 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -312,6 +312,8 @@ private: GrGLuint fTempSrcFBOID; GrGLuint fTempDstFBOID; + GrGLuint fStencilClearFBOID; + // last scissor / viewport scissor state seen by the GL. struct { TriState fEnabled; |