Fixes for iOS / Ganesh (consistent fs/vs uni precision decl and don't use stencil-only fbo for clear)

Review URL: http://codereview.appspot.com/4850043/


git-svn-id: http://skia.googlecode.com/svn/trunk@2050 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGLProgram.cpp b/gpu/src/GrGLProgram.cpp
index 40506f0..fe42855 100644
--- a/gpu/src/GrGLProgram.cpp
+++ b/gpu/src/GrGLProgram.cpp
@@ -1082,7 +1082,8 @@
                                   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 be84e27..4672cff 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -156,8 +156,23 @@
 
 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 7916a91..4c6c60e 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -516,14 +516,9 @@
     }
 
     fLastSuccessfulStencilFmtIdx = 0;
-
-    fStencilClearFBO = 0;
 }
 
 GrGpuGL::~GrGpuGL() {
-    if (fStencilClearFBO) {
-        GR_GL(DeleteFramebuffers(1, &fStencilClearFBO));
-    }
 }
 
 void GrGpuGL::resetContext() {
@@ -595,21 +590,6 @@
     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 @@
             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 @@
     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 @@
         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 6dbc9d7..0f0181c 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -70,8 +70,6 @@
 
     // GrGpu overrides
     virtual void resetContext();
-    virtual void abandonResources();
-    virtual void releaseResources();
 
     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
                                        const void* srcData,
@@ -104,7 +102,7 @@
                                      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;