Make flush discardable and lazily reset context

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



git-svn-id: http://skia.googlecode.com/svn/trunk@914 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index b43375c..1f90603 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -147,7 +147,7 @@
     /**
      * Wraps an externally-created rendertarget in a GrRenderTarget.
      * @param platformRenderTarget  3D API-specific render target identifier
-     *                              e.g. in GL platforamRenderTarget is an FBO 
+     *                              e.g. in GL platforamRenderTarget is an FBO
      *                              id.
      * @param stencilBits           the number of stencil bits that the render
      *                              target has.
@@ -383,15 +383,33 @@
     // Misc.
 
     /**
+     * Flags that affect flush() behavior.
+     */
+    enum FlushBits {
+        /**
+         * A client may want Gr to bind a GrRenderTarget in the 3D API so that
+         * it can be rendered to directly. However, Gr lazily sets state. Simply
+         * calling setRenderTarget() followed by flush() without flags may not
+         * bind the render target. This flag forces the context to bind the last
+         * set render target in the 3D API.
+         */
+        kForceCurrentRenderTarget_FlushBit   = 0x1,
+        /**
+         * A client may reach a point where it has partially rendered a frame
+         * through a GrContext that it knows the user will never see. This flag
+         * causes the flush to skip submission of deferred content to the 3D API
+         * during the flush.
+         */
+        kDiscard_FlushBit                    = 0x2,
+    };
+
+    /**
      * Call to ensure all drawing to the context has been issued to the
      * underlying 3D API.
-     * if flushRenderTarget is true then after the call the last
-     * rendertarget set will be current in the underlying 3D API, otherwise
-     * it may not be. It is useful to set if the caller plans to use the 3D
-     * context outside of Ganesh to render into the current RT.
+     * @param flagsBitfield     flags that control the flushing behavior. See
+     *                          FlushBits.
      */
-    void flush(bool flushRenderTarget);
-
+    void flush(int flagsBitfield);
     /**
      *  Return true on success, i.e. if we could copy the specified range of
      *  pixels from the current render-target into the buffer, converting into
@@ -473,7 +491,7 @@
     static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
 
     bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
-    
+
     GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
 
     void drawClipIntoStencil();
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 5a88ef4..16fbb93 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -14,7 +14,6 @@
     limitations under the License.
  */
 
-
 #ifndef GrGpu_DEFINED
 #define GrGpu_DEFINED
 
@@ -144,10 +143,10 @@
     /**
      * The GrGpu object normally assumes that no outsider is setting state
      * within the underlying 3D API's context/device/whatever. This call informs
-     * the GrGpu that the state was modified and it should resend. Shouldn't
-     * be called frequently for good performance.
+     * the GrGpu that the state was modified and it shouldn't make assumptions
+     * about the state.
      */
-    virtual void resetContext();
+    void markContextDirty() { fContextIsDirty = true; }
 
     void unimpl(const char[]);
 
@@ -164,8 +163,8 @@
      *
      * @return    The texture object if successful, otherwise NULL.
      */
-    virtual GrTexture* createTexture(const TextureDesc& desc,
-                                     const void* srcData, size_t rowBytes) = 0;
+    GrTexture* createTexture(const TextureDesc& desc,
+                             const void* srcData, size_t rowBytes);
     /**
      * Wraps an externally-created rendertarget in a GrRenderTarget.
      * @param platformRenderTarget  handle to the the render target in the
@@ -178,7 +177,7 @@
     virtual GrRenderTarget* createPlatformRenderTarget(
                                                 intptr_t platformRenderTarget,
                                                 int stencilBits,
-                                                int width, int height) = 0;
+                                                int width, int height);
 
     /**
      * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
@@ -189,7 +188,7 @@
      *
      * @return the newly created GrRenderTarget
      */
-    virtual GrRenderTarget* createRenderTargetFrom3DApiState() = 0;
+    GrRenderTarget* createRenderTargetFrom3DApiState();
 
     /**
      * Creates a vertex buffer.
@@ -201,7 +200,7 @@
      *
      * @return    The vertex buffer if successful, otherwise NULL.
      */
-    virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic) = 0;
+    GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
 
     /**
      * Creates an index buffer.
@@ -213,14 +212,14 @@
      *
      * @return The index buffer if successful, otherwise NULL.
      */
-    virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
+    GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
 
     /**
      * Erase the entire render target, ignoring any clips/scissors.
      *
      * This is issued to the GPU driver immediately.
      */
-    virtual void eraseColor(GrColor color) = 0;
+    void eraseColor(GrColor color);
 
     /**
      * Are 8 bit paletted textures supported.
@@ -322,10 +321,22 @@
      * underlying 3D API. Used when client wants to use 3D API to directly
      * render to the RT.
      */
-    virtual void forceRenderTargetFlush() = 0;
+    void forceRenderTargetFlush();
 
-    virtual bool readPixels(int left, int top, int width, int height,
-                            GrTexture::PixelConfig, void* buffer) = 0;
+    /**
+     * Reads a rectangle of pixels from the current render target.
+     * @param left      left edge of the rectangle to read (inclusive)
+     * @param top       top edge of the rectangle to read (inclusive)
+     * @param width     width of rectangle to read in pixels.
+     * @param height    height of rectangle to read in pixels.
+     * @param buffer    memory to read the rectangle into.
+     *
+     * @return true if the read succeeded, false if not. The read can fail
+     *              because of a unsupported pixel config or because no render
+     *              target is currently set.
+     */
+    bool readPixels(int left, int top, int width, int height,
+                    GrTexture::PixelConfig, void* buffer);
 
 
     const Stats& getStats() const;
@@ -357,7 +368,7 @@
 
     // Functions used to map clip-respecting stencil tests into normal
     // stencil funcs supported by GPUs.
-    static GrStencilFunc ConvertStencilFunc(bool stencilInClip, 
+    static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
                                             GrStencilFunc func);
     static void ConvertStencilFuncAndMask(GrStencilFunc func,
                                           bool clipInStencil,
@@ -412,7 +423,28 @@
     void finalizeReservedVertices();
     void finalizeReservedIndices();
 
-    // overridden by API specific GrGpu-derived class to perform the draw call.
+    // overridden by API-specific derived class to handle re-emitting 3D API
+    // preample and dirtying state cache.
+    virtual void resetContext() = 0;
+
+    // overridden by API-specific derived class to create objects.
+    virtual GrTexture* createTextureHelper(const TextureDesc& desc,
+                                           const void* srcData,
+                                           size_t rowBytes) = 0;
+    virtual GrRenderTarget* createPlatformRenderTargetHelper(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width, int height) = 0;
+    virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper() = 0;
+    virtual GrVertexBuffer* createVertexBufferHelper(uint32_t size,
+                                                     bool dynamic) = 0;
+    virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size,
+                                                   bool dynamic) = 0;
+
+    // overridden by API-specific derivated class to perform the erase.
+    virtual void eraseColorHelper(GrColor color) = 0;
+
+    // overridden by API-specific derived class to perform the draw call.
     virtual void drawIndexedHelper(GrPrimitiveType type,
                                    uint32_t startVertex,
                                    uint32_t startIndex,
@@ -423,6 +455,13 @@
                                       uint32_t vertexCount,
                                       uint32_t numVertices) = 0;
 
+    // overridden by API-specific derived class to perform flush
+    virtual void forceRenderTargetFlushHelper() = 0;
+
+    // overridden by API-specific derived class to perform the read pixels.
+    virtual bool readPixelsHelper(int left, int top, int width, int height,
+                                  GrTexture::PixelConfig, void* buffer) = 0;
+
     // called to program the vertex data, indexCount will be 0 if drawing non-
     // indexed geometry. The subclass may adjust the startVertex and/or
     // startIndex since it may have already accounted for these in the setup.
@@ -451,6 +490,13 @@
 
     GrPathRenderer* getPathRenderer();
 
+    void handleDirtyContext() {
+        if (fContextIsDirty) {
+            this->resetContext();
+            fContextIsDirty = false;
+        }
+    }
+
     GrVertexBufferAllocPool*    fVertexPool;
 
     GrIndexBufferAllocPool*     fIndexPool;
@@ -463,6 +509,8 @@
 
     GrPathRenderer*             fPathRenderer;
 
+    bool                        fContextIsDirty;
+
     // when in an internal draw these indicate whether the pools are in use
     // by one of the outer draws. If false then it is safe to reset the
     // pool.
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index a047895..c6fa618 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -560,9 +560,14 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrContext::flush(bool flushRenderTarget) {
-    flushDrawBuffer();
-    if (flushRenderTarget) {
+void GrContext::flush(int flagsBitfield) {
+    if (kDiscard_FlushBit & flagsBitfield) {
+        fDrawBuffer->reset();
+    } else {
+        flushDrawBuffer();
+    }
+
+    if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) {
         fGpu->forceRenderTargetFlush();
     }
 }
@@ -683,7 +688,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrContext::resetContext() {
-    fGpu->resetContext();
+    fGpu->markContextDirty();
 }
 
 void GrContext::setRenderTarget(GrRenderTarget* target) {
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 045dcd0..d41005b 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -71,6 +71,7 @@
                  fQuadIndexBuffer(NULL),
                  fUnitSquareVertexBuffer(NULL),
                  fPathRenderer(NULL),
+                 fContextIsDirty(true),
                  fVertexPoolInUse(false),
                  fIndexPoolInUse(false) {
 #if GR_DEBUG
@@ -98,6 +99,54 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+GrTexture* GrGpu::createTexture(const TextureDesc& desc,
+                                const void* srcData, size_t rowBytes) {
+    this->handleDirtyContext();
+    return this->createTextureHelper(desc, srcData, rowBytes);
+}
+
+GrRenderTarget* GrGpu::createPlatformRenderTarget(intptr_t platformRenderTarget,
+                                                  int stencilBits,
+                                                  int width, int height) {
+    this->handleDirtyContext();
+    return this->createPlatformRenderTargetHelper(platformRenderTarget,
+                                                  stencilBits,
+                                                  width, height);
+}
+
+GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {
+    this->handleDirtyContext();
+    return this->createRenderTargetFrom3DApiStateHelper();
+}
+
+GrVertexBuffer* GrGpu::createVertexBuffer(uint32_t size, bool dynamic) {
+    this->handleDirtyContext();
+    return this->createVertexBufferHelper(size, dynamic);
+}
+
+GrIndexBuffer* GrGpu::createIndexBuffer(uint32_t size, bool dynamic) {
+    this->handleDirtyContext();
+    return this->createIndexBufferHelper(size, dynamic);
+}
+
+void GrGpu::eraseColor(GrColor color) {
+    this->handleDirtyContext();
+    this->eraseColorHelper(color);
+}
+
+void GrGpu::forceRenderTargetFlush() {
+    this->handleDirtyContext();
+    this->forceRenderTargetFlushHelper();
+}
+
+bool GrGpu::readPixels(int left, int top, int width, int height,
+                       GrTexture::PixelConfig config, void* buffer) {
+    this->handleDirtyContext();
+    return this->readPixelsHelper(left, top, width, height, config, buffer);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
 
 GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535);
@@ -184,7 +233,8 @@
     0,                           0
 };
 
-// converts special stencil func to
+// mapping of clip-respecting stencil funcs to normal stencil funcs
+// mapping depends on whether stencil-clipping is in effect.
 static const GrStencilFunc gGrClipToNormalStencilFunc[2][kClipStencilFuncCount] = {
     {// Stencil-Clipping is DISABLED, effectively always inside the clip
         // In the Clip Funcs
@@ -445,7 +495,9 @@
     GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
              fReservedGeometry.fLocked);
 
-    if (!setupClipAndFlushState(type)) {
+    this->handleDirtyContext();
+
+    if (!this->setupClipAndFlushState(type)) {
         return;
     }
 
@@ -469,7 +521,9 @@
     GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
              fReservedGeometry.fLocked);
 
-    if (!setupClipAndFlushState(type)) {
+    this->handleDirtyContext();
+
+    if (!this->setupClipAndFlushState(type)) {
         return;
     }
 #if GR_COLLECT_STATS
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 3ee524b..b0d5e73 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -152,8 +152,6 @@
 
     GrGLInitExtensions(&fExts);
 
-    resetContextHelper();
-
     resetDirtyFlags();
 
     GLint maxTextureUnits;
@@ -427,8 +425,8 @@
 GrGpuGL::~GrGpuGL() {
 }
 
-void GrGpuGL::resetContextHelper() {
-// We detect cases when blending is effectively off
+void GrGpuGL::resetContext() {
+    // We detect cases when blending is effectively off
     fHWBlendDisabled = false;
     GR_GL(Enable(GL_BLEND));
 
@@ -491,12 +489,7 @@
     fHWDrawState.fRenderTarget = NULL;
 }
 
-void GrGpuGL::resetContext() {
-    INHERITED::resetContext();
-    resetContextHelper();
-}
-
-GrRenderTarget* GrGpuGL::createPlatformRenderTarget(
+GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper(
                                                 intptr_t platformRenderTarget,
                                                 int stencilBits,
                                                 int width,
@@ -520,7 +513,7 @@
     return new GrGLRenderTarget(rtIDs, stencilBits, viewport, NULL, this);
 }
 
-GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiState() {
+GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
 
     GrGLRenderTarget::GLRenderTargetIDs rtIDs;
 
@@ -575,8 +568,9 @@
 }
 #endif
 
-GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
-                                  const void* srcData, size_t rowBytes) {
+GrTexture* GrGpuGL::createTextureHelper(const TextureDesc& desc,
+                                        const void* srcData,
+                                        size_t rowBytes) {
 
 #if GR_COLLECT_STATS
     ++fStats.fTextureCreateCnt;
@@ -988,7 +982,7 @@
     return tex;
 }
 
-GrVertexBuffer* GrGpuGL::createVertexBuffer(uint32_t size, bool dynamic) {
+GrVertexBuffer* GrGpuGL::createVertexBufferHelper(uint32_t size, bool dynamic) {
     GLuint id;
     GR_GL(GenBuffers(1, &id));
     if (id) {
@@ -1012,7 +1006,7 @@
     return NULL;
 }
 
-GrIndexBuffer* GrGpuGL::createIndexBuffer(uint32_t size, bool dynamic) {
+GrIndexBuffer* GrGpuGL::createIndexBufferHelper(uint32_t size, bool dynamic) {
     GLuint id;
     GR_GL(GenBuffers(1, &id));
     if (id) {
@@ -1066,7 +1060,7 @@
     }
 }
 
-void GrGpuGL::eraseColor(GrColor color) {
+void GrGpuGL::eraseColorHelper(GrColor color) {
     if (NULL == fCurrDrawState.fRenderTarget) {
         return;
     }
@@ -1121,12 +1115,12 @@
     fHWDrawState.fStencilSettings.invalidate();
 }
 
-void GrGpuGL::forceRenderTargetFlush() {
+void GrGpuGL::forceRenderTargetFlushHelper() {
     flushRenderTarget();
 }
 
-bool GrGpuGL::readPixels(int left, int top, int width, int height,
-                         GrTexture::PixelConfig config, void* buffer) {
+bool GrGpuGL::readPixelsHelper(int left, int top, int width, int height,
+                               GrTexture::PixelConfig config, void* buffer) {
     GLenum internalFormat;  // we don't use this for glReadPixels
     GLenum format;
     GLenum type;
@@ -1207,7 +1201,7 @@
 
 #define SWAP_PER_DRAW 0
 
-#if SWAP_PER_DRAW 
+#if SWAP_PER_DRAW
     #if GR_MAC_BUILD
         #include <AGL/agl.h>
     #elif GR_WIN32_BUILD
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index a2905c5..ab504ad 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -31,28 +31,6 @@
             GrGpuGL();
     virtual ~GrGpuGL();
 
-    // overrides from GrGpu
-    virtual void resetContext();
-
-    virtual GrTexture* createTexture(const TextureDesc& desc,
-                                     const void* srcData, size_t rowBytes);
-    virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
-    virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
-
-    virtual GrRenderTarget* createPlatformRenderTarget(
-                                                 intptr_t platformRenderTarget,
-                                                 int stencilBits,
-                                                 int width, int height);
-
-    virtual GrRenderTarget* createRenderTargetFrom3DApiState();
-
-    virtual void eraseColor(GrColor color);
-
-    virtual void forceRenderTargetFlush();
-
-    virtual bool readPixels(int left, int top, int width, int height,
-                            GrTexture::PixelConfig, void* buffer);
-
     /**
      * Gets the struct containing the GL extensions for the context
      * underlying the GrGpuGL
@@ -97,6 +75,31 @@
     GrGLExts fExts;
 
     // GrGpu overrides
+    // overrides from GrGpu
+    virtual void resetContext();
+
+    virtual GrTexture* createTextureHelper(const TextureDesc& desc,
+                                           const void* srcData,
+                                           size_t rowBytes);
+    virtual GrVertexBuffer* createVertexBufferHelper(uint32_t size,
+                                                     bool dynamic);
+    virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size,
+                                                   bool dynamic);
+
+    virtual GrRenderTarget* createPlatformRenderTargetHelper(
+                                                 intptr_t platformRenderTarget,
+                                                 int stencilBits,
+                                                 int width, int height);
+
+    virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper();
+
+    virtual void eraseColorHelper(GrColor color);
+
+    virtual void forceRenderTargetFlushHelper();
+
+    virtual bool readPixelsHelper(int left, int top, int width, int height,
+                                  GrTexture::PixelConfig, void* buffer);
+
     virtual void drawIndexedHelper(GrPrimitiveType type,
                                    uint32_t startVertex,
                                    uint32_t startIndex,
@@ -140,8 +143,6 @@
                                         const GrSamplerState& sampler);
 
 private:
-    void resetContextHelper();
-
     // notify callbacks to update state tracking when related
     // objects are bound to GL or deleted outside of the class
     void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
@@ -190,4 +191,4 @@
     typedef GrGpu INHERITED;
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
index 516381e..695b22c 100644
--- a/gpu/src/GrGpuGLFixed.cpp
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -58,7 +58,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGpuGLFixed::GrGpuGLFixed() {
-    resetContextHelper();
 }
 
 GrGpuGLFixed::~GrGpuGLFixed() {
@@ -66,10 +65,7 @@
 
 void GrGpuGLFixed::resetContext() {
     INHERITED::resetContext();
-    resetContextHelper();
-}
 
-void GrGpuGLFixed::resetContextHelper() {
     GR_GL(Disable(GL_TEXTURE_2D));
 
     for (int s = 0; s < kNumStages; ++s) {
@@ -204,11 +200,11 @@
                 }
 
                 if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
-                    (fHWDrawState.fSamplerStates[s].getMatrix() != 
+                    (fHWDrawState.fSamplerStates[s].getMatrix() !=
                      getSamplerMatrix(s))) {
 
                     GrMatrix texMat = getSamplerMatrix(s);
-                    AdjustTextureMatrix(texture, 
+                    AdjustTextureMatrix(texture,
                                         GrSamplerState::kNormal_SampleMode,
                                         &texMat);
                     GrGpuMatrix glm;
diff --git a/gpu/src/GrGpuGLFixed.h b/gpu/src/GrGpuGLFixed.h
index 5b81ea6..077b6e2 100644
--- a/gpu/src/GrGpuGLFixed.h
+++ b/gpu/src/GrGpuGLFixed.h
@@ -26,8 +26,6 @@
              GrGpuGLFixed();
     virtual ~GrGpuGLFixed();
 
-    virtual void resetContext();
-
 protected:
     // overrides from GrGpu
     virtual bool flushGraphicsState(GrPrimitiveType type);
@@ -37,7 +35,7 @@
                                int indexCount);
 
 private:
-    void resetContextHelper();
+    virtual void resetContext();
 
     // Helpers to make code more readable
     const GrMatrix& getHWSamplerMatrix(int stage) const {
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
index 77847e9..f79e9c8 100644
--- a/gpu/src/GrGpuGLShaders2.cpp
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -1088,8 +1088,6 @@
 
 GrGpuGLShaders2::GrGpuGLShaders2() {
 
-    resetContextHelper();
-
     fProgram = NULL;
     fProgramCache = new ProgramCache();
 
@@ -1119,11 +1117,9 @@
 }
 
 void GrGpuGLShaders2::resetContext() {
-    INHERITED::resetContext();
-    resetContextHelper();
-}
 
-void GrGpuGLShaders2::resetContextHelper() {
+    INHERITED::resetContext();
+
     fHWGeometryState.fVertexLayout = 0;
     fHWGeometryState.fVertexOffset  = ~0;
     GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h
index e8785c9..4c501be 100644
--- a/gpu/src/GrGpuGLShaders2.h
+++ b/gpu/src/GrGpuGLShaders2.h
@@ -26,8 +26,6 @@
              GrGpuGLShaders2();
     virtual ~GrGpuGLShaders2();
 
-    virtual void resetContext();
-
 protected:
     // overrides from GrGpu
     virtual bool flushGraphicsState(GrPrimitiveType type);
@@ -38,7 +36,7 @@
 
 private:
 
-    void resetContextHelper();
+    virtual void resetContext();
 
     // Helpers to make code more readable
     const GrMatrix& getHWSamplerMatrix(int stage);