aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-02-23 09:27:45 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-23 09:27:45 -0800
commitdd3143b0079f01980ca4886f00c39b3caa3fee6a (patch)
tree1ccd265c2e2dd594ba73eecc4c6c34fdb8126a38 /src/gpu/gl
parent6bc1b5fab8554a9cb643277b4867965dd4535cd6 (diff)
clear stencil buffer using special purpose FBO
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLGpu.cpp40
-rw-r--r--src/gpu/gl/GrGLGpu.h2
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;