clear stencil buffer using special purpose FBO
Review URL: https://codereview.chromium.org/941383003
This commit is contained in:
parent
6bc1b5fab8
commit
dd3143b007
@ -97,15 +97,6 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this->createStencilBufferForRenderTarget(rt, width, height)) {
|
if (this->createStencilBufferForRenderTarget(rt, width, height)) {
|
||||||
// Right now we're clearing the stencil buffer here after it is
|
|
||||||
// attached to an RT for the first time. When we start matching
|
|
||||||
// stencil buffers with smaller color targets this will no longer
|
|
||||||
// be correct because it won't be guaranteed to clear the entire
|
|
||||||
// sb.
|
|
||||||
// We used to clear down in the GL subclass using a special purpose
|
|
||||||
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
|
|
||||||
// FBO status.
|
|
||||||
this->clearStencil(rt);
|
|
||||||
GrStencilBuffer* sb = rt->renderTargetPriv().getStencilBuffer();
|
GrStencilBuffer* sb = rt->renderTargetPriv().getStencilBuffer();
|
||||||
sb->resourcePriv().setUniqueKey(sbKey);
|
sb->resourcePriv().setUniqueKey(sbKey);
|
||||||
return true;
|
return true;
|
||||||
|
@ -153,6 +153,7 @@ GrGLGpu::GrGLGpu(const GrGLContext& ctx, GrContext* context)
|
|||||||
fHWProgramID = 0;
|
fHWProgramID = 0;
|
||||||
fTempSrcFBOID = 0;
|
fTempSrcFBOID = 0;
|
||||||
fTempDstFBOID = 0;
|
fTempDstFBOID = 0;
|
||||||
|
fStencilClearFBOID = 0;
|
||||||
|
|
||||||
if (this->glCaps().pathRenderingSupport()) {
|
if (this->glCaps().pathRenderingSupport()) {
|
||||||
fPathRendering.reset(new GrGLPathRendering(this));
|
fPathRendering.reset(new GrGLPathRendering(this));
|
||||||
@ -173,6 +174,9 @@ GrGLGpu::~GrGLGpu() {
|
|||||||
if (0 != fTempDstFBOID) {
|
if (0 != fTempDstFBOID) {
|
||||||
GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
|
GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
|
||||||
}
|
}
|
||||||
|
if (0 != fStencilClearFBOID) {
|
||||||
|
GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
|
||||||
|
}
|
||||||
|
|
||||||
delete fProgramCache;
|
delete fProgramCache;
|
||||||
}
|
}
|
||||||
@ -183,6 +187,7 @@ void GrGLGpu::contextAbandoned() {
|
|||||||
fHWProgramID = 0;
|
fHWProgramID = 0;
|
||||||
fTempSrcFBOID = 0;
|
fTempSrcFBOID = 0;
|
||||||
fTempDstFBOID = 0;
|
fTempDstFBOID = 0;
|
||||||
|
fStencilClearFBOID = 0;
|
||||||
if (this->glCaps().pathRenderingSupport()) {
|
if (this->glCaps().pathRenderingSupport()) {
|
||||||
this->glPathRendering()->abandonGpuResources();
|
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.
|
// whatever sizes GL gives us. In that case we query for the size.
|
||||||
GrGLStencilBuffer::Format format = sFmt;
|
GrGLStencilBuffer::Format format = sFmt;
|
||||||
get_stencil_rb_sizes(this->glInterface(), &format);
|
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)));
|
(this, sbDesc, width, height, samples, format)));
|
||||||
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
||||||
fLastSuccessfulStencilFmtIdx = sIdx;
|
fLastSuccessfulStencilFmtIdx = sIdx;
|
||||||
rt->renderTargetPriv().didAttachStencilBuffer(sb);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
// Remove the scratch key from this resource so we don't grab it from the cache ever
|
// Remove the scratch key from this resource so we don't grab it from the cache ever
|
||||||
|
@ -312,6 +312,8 @@ private:
|
|||||||
GrGLuint fTempSrcFBOID;
|
GrGLuint fTempSrcFBOID;
|
||||||
GrGLuint fTempDstFBOID;
|
GrGLuint fTempDstFBOID;
|
||||||
|
|
||||||
|
GrGLuint fStencilClearFBOID;
|
||||||
|
|
||||||
// last scissor / viewport scissor state seen by the GL.
|
// last scissor / viewport scissor state seen by the GL.
|
||||||
struct {
|
struct {
|
||||||
TriState fEnabled;
|
TriState fEnabled;
|
||||||
|
Loading…
Reference in New Issue
Block a user