From a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 10 Mar 2011 14:13:19 +0000 Subject: 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 --- gpu/include/GrContext.h | 34 ++++++++++++++----- gpu/include/GrGpu.h | 80 ++++++++++++++++++++++++++++++++++++--------- gpu/src/GrContext.cpp | 13 +++++--- gpu/src/GrGpu.cpp | 60 ++++++++++++++++++++++++++++++++-- gpu/src/GrGpuGL.cpp | 34 ++++++++----------- gpu/src/GrGpuGL.h | 51 +++++++++++++++-------------- gpu/src/GrGpuGLFixed.cpp | 8 ++--- gpu/src/GrGpuGLFixed.h | 4 +-- gpu/src/GrGpuGLShaders2.cpp | 6 +--- gpu/src/GrGpuGLShaders2.h | 4 +-- 10 files changed, 201 insertions(+), 93 deletions(-) diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h index b43375cb48..1f90603f5d 100644 --- a/gpu/include/GrContext.h +++ b/gpu/include/GrContext.h @@ -147,7 +147,7 @@ public: /** * 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. @@ -382,16 +382,34 @@ public: /////////////////////////////////////////////////////////////////////////// // 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 @@ private: 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 5a88ef481f..16fbb93a25 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 @@ public: /** * 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 @@ public: * * @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 @@ public: 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 @@ public: * * @return the newly created GrRenderTarget */ - virtual GrRenderTarget* createRenderTargetFrom3DApiState() = 0; + GrRenderTarget* createRenderTargetFrom3DApiState(); /** * Creates a vertex buffer. @@ -201,7 +200,7 @@ public: * * @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 @@ public: * * @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 @@ public: * 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 @@ protected: // 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 @@ protected: 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 @@ protected: 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 @@ private: GrPathRenderer* getPathRenderer(); + void handleDirtyContext() { + if (fContextIsDirty) { + this->resetContext(); + fContextIsDirty = false; + } + } + GrVertexBufferAllocPool* fVertexPool; GrIndexBufferAllocPool* fIndexPool; @@ -463,6 +509,8 @@ private: 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 a047895ced..c6fa618920 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -560,9 +560,14 @@ void GrContext::drawPath(const GrPaint& paint, //////////////////////////////////////////////////////////////////////////////// -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 @@ GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, //////////////////////////////////////////////////////////////////////////////// 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 045dcd00b6..d41005b531 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -71,6 +71,7 @@ GrGpu::GrGpu() : f8bitPaletteSupport(false), fQuadIndexBuffer(NULL), fUnitSquareVertexBuffer(NULL), fPathRenderer(NULL), + fContextIsDirty(true), fVertexPoolInUse(false), fIndexPoolInUse(false) { #if GR_DEBUG @@ -98,6 +99,54 @@ void GrGpu::unimpl(const char msg[]) { //////////////////////////////////////////////////////////////////////////////// +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 @@ const GrStencilSettings GrGpu::gClipStencilSettings = { 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 @@ void GrGpu::drawIndexed(GrPrimitiveType type, GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc || fReservedGeometry.fLocked); - if (!setupClipAndFlushState(type)) { + this->handleDirtyContext(); + + if (!this->setupClipAndFlushState(type)) { return; } @@ -469,7 +521,9 @@ void GrGpu::drawNonIndexed(GrPrimitiveType type, 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 3ee524b74b..b0d5e73bc9 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -152,8 +152,6 @@ GrGpuGL::GrGpuGL() { GrGLInitExtensions(&fExts); - resetContextHelper(); - resetDirtyFlags(); GLint maxTextureUnits; @@ -427,8 +425,8 @@ GrGpuGL::GrGpuGL() { 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 @@ void GrGpuGL::resetContextHelper() { 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 @@ GrRenderTarget* GrGpuGL::createPlatformRenderTarget( return new GrGLRenderTarget(rtIDs, stencilBits, viewport, NULL, this); } -GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiState() { +GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() { GrGLRenderTarget::GLRenderTargetIDs rtIDs; @@ -575,8 +568,9 @@ static size_t as_size_t(int x) { } #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 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc, 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 @@ GrVertexBuffer* GrGpuGL::createVertexBuffer(uint32_t size, bool dynamic) { 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::flushScissor(const GrIRect* rect) { } } -void GrGpuGL::eraseColor(GrColor color) { +void GrGpuGL::eraseColorHelper(GrColor color) { if (NULL == fCurrDrawState.fRenderTarget) { return; } @@ -1121,12 +1115,12 @@ void GrGpuGL::eraseStencilClip(const GrIRect& rect) { 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 @@ GLenum gPrimitiveType2GLMode[] = { #define SWAP_PER_DRAW 0 -#if SWAP_PER_DRAW +#if SWAP_PER_DRAW #if GR_MAC_BUILD #include #elif GR_WIN32_BUILD diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index a2905c5d30..ab504adbb2 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -31,28 +31,6 @@ public: 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 @@ protected: 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 @@ protected: 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 @@ private: typedef GrGpu INHERITED; }; -#endif \ No newline at end of file +#endif diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp index 516381e308..695b22c156 100644 --- a/gpu/src/GrGpuGLFixed.cpp +++ b/gpu/src/GrGpuGLFixed.cpp @@ -58,7 +58,6 @@ static const GLenum gMatrixMode2Enum[] = { /////////////////////////////////////////////////////////////////////////////// GrGpuGLFixed::GrGpuGLFixed() { - resetContextHelper(); } GrGpuGLFixed::~GrGpuGLFixed() { @@ -66,10 +65,7 @@ GrGpuGLFixed::~GrGpuGLFixed() { 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 @@ bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) { } 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 5b81ea616d..077b6e2a38 100644 --- a/gpu/src/GrGpuGLFixed.h +++ b/gpu/src/GrGpuGLFixed.h @@ -26,8 +26,6 @@ public: GrGpuGLFixed(); virtual ~GrGpuGLFixed(); - virtual void resetContext(); - protected: // overrides from GrGpu virtual bool flushGraphicsState(GrPrimitiveType type); @@ -37,7 +35,7 @@ protected: 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 77847e9fba..f79e9c883a 100644 --- a/gpu/src/GrGpuGLShaders2.cpp +++ b/gpu/src/GrGpuGLShaders2.cpp @@ -1088,8 +1088,6 @@ void GrGpuGLShaders2::DeleteProgram(Program* program) { GrGpuGLShaders2::GrGpuGLShaders2() { - resetContextHelper(); - fProgram = NULL; fProgramCache = new ProgramCache(); @@ -1119,11 +1117,9 @@ void GrGpuGLShaders2::recordHWSamplerMatrix(int stage, const GrMatrix& matrix){ } void GrGpuGLShaders2::resetContext() { + INHERITED::resetContext(); - resetContextHelper(); -} -void GrGpuGLShaders2::resetContextHelper() { 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 e8785c9677..4c501be69e 100644 --- a/gpu/src/GrGpuGLShaders2.h +++ b/gpu/src/GrGpuGLShaders2.h @@ -26,8 +26,6 @@ public: GrGpuGLShaders2(); virtual ~GrGpuGLShaders2(); - virtual void resetContext(); - protected: // overrides from GrGpu virtual bool flushGraphicsState(GrPrimitiveType type); @@ -38,7 +36,7 @@ protected: private: - void resetContextHelper(); + virtual void resetContext(); // Helpers to make code more readable const GrMatrix& getHWSamplerMatrix(int stage); -- cgit v1.2.3