diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h index fff40fb147..d3c6c9d663 100644 --- a/gpu/include/GrGpu.h +++ b/gpu/include/GrGpu.h @@ -493,6 +493,8 @@ protected: // GrGpu subclass removes the clip from the stencil buffer virtual void clearStencilClip(const GrIRect& rect) = 0; + // clears the entire stencil buffer to 0 + virtual void clearStencil() = 0; private: GrContext* fContext; // not reffed (context refs gpu) diff --git a/gpu/src/GrGLProgram.cpp b/gpu/src/GrGLProgram.cpp index 40506f0946..fe42855fd0 100644 --- a/gpu/src/GrGLProgram.cpp +++ b/gpu/src/GrGLProgram.cpp @@ -1082,7 +1082,8 @@ void GrGLProgram::genStageCode(int stageNum, kernelName.c_str(), desc.fKernelWidth); segments->fFSUnis.appendf("uniform vec2 %s;\n", imageIncrementName.c_str()); - segments->fVSUnis.appendf("uniform vec2 %s;\n", + segments->fVSUnis.appendf("uniform %s vec2 %s;\n", + GrPrecision(), imageIncrementName.c_str()); locations->fKernelUni = kUseUniform; locations->fImageIncrementUni = kUseUniform; diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp index be84e270d5..4672cff3f4 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -156,8 +156,23 @@ GrTexture* GrGpu::createTexture(const GrTextureDesc& desc, bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { // TODO: use a cache of stencil buffers rather than create per-rt. - return this->createStencilBufferForRenderTarget(rt, rt->width(), - rt->height()); + bool ret = this->createStencilBufferForRenderTarget(rt, rt->width(), + rt->height()); + if (ret) { + // 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. + GrRenderTarget* oldRT = fCurrDrawState.fRenderTarget; + fCurrDrawState.fRenderTarget = rt; + this->clearStencil(); + fCurrDrawState.fRenderTarget = oldRT; + } + return ret; } GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() { diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp index 7916a91754..4c6c60e821 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -516,14 +516,9 @@ GrGpuGL::GrGpuGL() } fLastSuccessfulStencilFmtIdx = 0; - - fStencilClearFBO = 0; } GrGpuGL::~GrGpuGL() { - if (fStencilClearFBO) { - GR_GL(DeleteFramebuffers(1, &fStencilClearFBO)); - } } void GrGpuGL::resetContext() { @@ -595,21 +590,6 @@ void GrGpuGL::resetContext() { fHWDrawState.fRenderTarget = NULL; } -void GrGpuGL::abandonResources() { - INHERITED::abandonResources(); - - fStencilClearFBO = 0; -} - -void GrGpuGL::releaseResources() { - INHERITED::releaseResources(); - - if (fStencilClearFBO) { - GR_GL(DeleteFramebuffers(1, &fStencilClearFBO)); - fStencilClearFBO = 0; - } -} - GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) { bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType || @@ -1374,56 +1354,6 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, if (this->attachStencilBufferToRenderTarget(sb, rt)) { fLastSuccessfulStencilFmtIdx = sIdx; sb->unref(); - fHWDrawState.fRenderTarget = NULL; - // initial clear zeros the entire sb by attaching it alone - // to an fbo (that we create here on demand). - if (!fStencilClearFBO) { - GR_GL(GenFramebuffers(1, &fStencilClearFBO)); - if (0 == fStencilClearFBO) { - rt->setStencilBuffer(NULL); - return false; - } - GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBO)); - if (GR_GL_SUPPORT_DESKTOP) { - // We won't be binding a color buffer, set the draw - // buffer to NONE to avoid - // FRAMEBUFFER_INCOMPLETE_READ_BUFFER. - GR_GL(DrawBuffer(GR_GL_NONE)); - // We bind to FRAMEBUFFER not DRAW_FRAMEBUFFER or - // READ_FRAMEBUFFER because earlier versions of desktop - // GL and unextended ES only have FRAMEBUFFER. But this - // means we're binding both READ and DRAW when - // FramebufferBlit is supported. So to avoid - // FRAMEBUFFER_INCOMPLETE_READ_BUFFER status we also set - // the read buffer to none. - GR_GL(ReadBuffer(GR_GL_NONE)); - // DrawBuffer and ReadBuffer are framebuffer state so - // we only have to set these the first time. - } - } else { - GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBO)); - } - GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_STENCIL_ATTACHMENT, - GR_GL_RENDERBUFFER, sbID)); - if (fStencilFormats[sIdx].fPacked) { - GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_DEPTH_ATTACHMENT, - GR_GL_RENDERBUFFER, sbID)); - } else { - GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_DEPTH_ATTACHMENT, - GR_GL_RENDERBUFFER, 0)); - } -#if GR_DEBUG - GrGLenum status = - GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); - GrAssert(GR_GL_FRAMEBUFFER_COMPLETE == status); -#endif - - this->flushScissor(NULL); - GR_GL(ClearStencil(0)); - GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT)); return true; } sb->abandon(); // otherwise we lose sbID @@ -1600,7 +1530,7 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { GR_GL(Clear(GR_GL_COLOR_BUFFER_BIT)); } -void GrGpuGL::clearStencil(uint32_t value, uint32_t mask) { +void GrGpuGL::clearStencil() { if (NULL == fCurrDrawState.fRenderTarget) { return; } @@ -1611,8 +1541,8 @@ void GrGpuGL::clearStencil(uint32_t value, uint32_t mask) { GR_GL(Disable(GR_GL_SCISSOR_TEST)); fHWBounds.fScissorEnabled = false; } - GR_GL(StencilMask(mask)); - GR_GL(ClearStencil(value)); + GR_GL(StencilMask(0xffffffff)); + GR_GL(ClearStencil(0)); GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT)); fHWDrawState.fStencilSettings.invalidate(); } diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index 6dbc9d7dd5..0f0181c452 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -70,8 +70,6 @@ protected: // GrGpu overrides virtual void resetContext(); - virtual void abandonResources(); - virtual void releaseResources(); virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, const void* srcData, @@ -104,7 +102,7 @@ protected: uint32_t vertexCount, uint32_t numVertices); virtual void flushScissor(const GrIRect* rect); - void clearStencil(uint32_t value, uint32_t mask); + virtual void clearStencil(); virtual void clearStencilClip(const GrIRect& rect); virtual int getMaxEdges() const;