diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-06-28 18:57:35 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-06-28 18:57:35 +0000 |
commit | 0a208a117b2d7f2c2231aa357f1db4864dbdcba3 (patch) | |
tree | 0263de23dcf967bc20b09ce86bdded12fad5c363 | |
parent | ab03e6816b22ea1d8d12b74b7b077d77ff366d5d (diff) |
Add flag bits for partial GrContext reset
BUG=248728
R=bsalomon@google.com
Committed: https://code.google.com/p/skia/source/detail?r=9802
Review URL: https://codereview.chromium.org/17027003
git-svn-id: http://skia.googlecode.com/svn/trunk@9814 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/gpu/GrContext.h | 4 | ||||
-rw-r--r-- | include/gpu/GrTypes.h | 25 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 14 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 150 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 2 |
7 files changed, 127 insertions, 76 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 5c796b26c0..c59c4d4243 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -61,8 +61,10 @@ public: * within the underlying 3D API's context/device/whatever. This call informs * the context that the state was modified and it should resend. Shouldn't * be called frequently for good performance. + * The flag bits, state, is dpendent on which backend is used by the + * context, either GL or D3D (possible in future). */ - void resetContext(); + void resetContext(uint32_t state = kAll_GrBackendState); /** * Callback function to allow classes to cleanup on GrContext destruction. diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 970e0c7b2f..18aedc5e89 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -600,6 +600,31 @@ struct GrBackendRenderTargetDesc { GrBackendObject fRenderTargetHandle; }; +/** + * The GrContext's cache of backend context state can be partially invalidated. + * These enums are specific to the GL backend and we'd add a new set for an alternative backend. + */ +enum GrGLBackendState { + kRenderTarget_GrGLBackendState = 1 << 0, + kTextureBinding_GrGLBackendState = 1 << 1, + // View state stands for scissor and viewport + kView_GrGLBackendState = 1 << 2, + kBlend_GrGLBackendState = 1 << 3, + kAA_GrGLBackendState = 1 << 4, + kVertex_GrGLBackendState = 1 << 5, + kStencil_GrGLBackendState = 1 << 6, + kPixelStore_GrGLBackendState = 1 << 7, + kProgram_GrGLBackendState = 1 << 8, + kPathStencil_GrGLBackendState = 1 << 9, + kMisc_GrGLBackendState = 1 << 10, + kALL_GrGLBackendState = 0xffff +}; + +/** + * This value translates to reseting all the context state for any backend. + */ +static const uint32_t kAll_GrBackendState = 0xffffffff; + /////////////////////////////////////////////////////////////////////////////// #endif diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index c94c1a925b..fe8f4fdedd 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -204,8 +204,8 @@ void GrContext::contextDestroyed() { fGpu->markContextDirty(); } -void GrContext::resetContext() { - fGpu->markContextDirty(); +void GrContext::resetContext(uint32_t state) { + fGpu->markContextDirty(state); } void GrContext::freeGpuResources() { diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index ae98b54bea..5d6c62fc93 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -30,12 +30,12 @@ static const int INDEX_POOL_IB_COUNT = 4; GrGpu::GrGpu(GrContext* context) : GrDrawTarget(context) , fResetTimestamp(kExpiredTimestamp+1) + , fResetBits(kAll_GrBackendState) , fVertexPool(NULL) , fIndexPool(NULL) , fVertexPoolUseCnt(0) , fIndexPoolUseCnt(0) - , fQuadIndexBuffer(NULL) - , fContextIsDirty(true) { + , fQuadIndexBuffer(NULL) { fClipMaskManager.setGpu(this); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 3acfac2703..85e398807b 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -66,7 +66,9 @@ public: * the GrGpu that the state was modified and it shouldn't make assumptions * about the state. */ - void markContextDirty() { fContextIsDirty = true; } + void markContextDirty(uint32_t state = kAll_GrBackendState) { + fResetBits |= state; + } void unimpl(const char[]); @@ -426,7 +428,7 @@ private: // called when the 3D context state is unknown. Subclass should emit any // assumed 3D context state and dirty any state cache. - virtual void onResetContext() = 0; + virtual void onResetContext(uint32_t resetBits) = 0; // overridden by backend-specific derived class to create objects. virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, @@ -507,14 +509,14 @@ private: // stencil buffer. Perhaps we should detect whether it is a // internally created stencil buffer and if so skip the invalidate. fClipMaskManager.invalidateStencilMask(); - this->onResetContext(); + this->onResetContext(fResetBits); + fResetBits = 0; ++fResetTimestamp; } void handleDirtyContext() { - if (fContextIsDirty) { + if (fResetBits) { this->resetContext(); - fContextIsDirty = false; } } @@ -524,6 +526,7 @@ private: typedef SkTInternalLList<GrResource> ResourceList; SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true> fGeomPoolStateStack; ResetTimestamp fResetTimestamp; + uint32_t fResetBits; GrVertexBufferAllocPool* fVertexPool; GrIndexBufferAllocPool* fIndexPool; // counts number of uses of vertex/index pool in the geometry stack @@ -531,7 +534,6 @@ private: int fIndexPoolUseCnt; // these are mutable so they can be created on-demand mutable GrIndexBuffer* fQuadIndexBuffer; - bool fContextIsDirty; // Used to abandon/release all resources created by this GrGpu. TODO: Move this // functionality to GrResourceCache. ResourceList fResourceList; diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index d96ea395e6..0ffcc27222 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -153,6 +153,7 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) GrAssert(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt); fLastSuccessfulStencilFmtIdx = 0; + fHWProgramID = 0; } GrGpuGL::~GrGpuGL() { @@ -282,88 +283,109 @@ bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const { return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL); } -void GrGpuGL::onResetContext() { - +void GrGpuGL::onResetContext(uint32_t resetBits) { // we don't use the zb at all - GL_CALL(Disable(GR_GL_DEPTH_TEST)); - GL_CALL(DepthMask(GR_GL_FALSE)); - - fHWDrawFace = GrDrawState::kInvalid_DrawFace; - fHWDitherEnabled = kUnknown_TriState; - - if (kDesktop_GrGLBinding == this->glBinding()) { - // Desktop-only state that we never change - if (!this->glCaps().isCoreProfile()) { - GL_CALL(Disable(GR_GL_POINT_SMOOTH)); - GL_CALL(Disable(GR_GL_LINE_SMOOTH)); - GL_CALL(Disable(GR_GL_POLYGON_SMOOTH)); - GL_CALL(Disable(GR_GL_POLYGON_STIPPLE)); - GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP)); - GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP)); - } - // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a core - // profile. This seems like a bug since the core spec removes any mention of GL_ARB_imaging. - if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) { - GL_CALL(Disable(GR_GL_COLOR_TABLE)); + if (resetBits & kMisc_GrGLBackendState) { + GL_CALL(Disable(GR_GL_DEPTH_TEST)); + GL_CALL(DepthMask(GR_GL_FALSE)); + + fHWDrawFace = GrDrawState::kInvalid_DrawFace; + fHWDitherEnabled = kUnknown_TriState; + + if (kDesktop_GrGLBinding == this->glBinding()) { + // Desktop-only state that we never change + if (!this->glCaps().isCoreProfile()) { + GL_CALL(Disable(GR_GL_POINT_SMOOTH)); + GL_CALL(Disable(GR_GL_LINE_SMOOTH)); + GL_CALL(Disable(GR_GL_POLYGON_SMOOTH)); + GL_CALL(Disable(GR_GL_POLYGON_STIPPLE)); + GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP)); + GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP)); + } + // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a + // core profile. This seems like a bug since the core spec removes any mention of + // GL_ARB_imaging. + if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) { + GL_CALL(Disable(GR_GL_COLOR_TABLE)); + } + GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL)); + // Since ES doesn't support glPointSize at all we always use the VS to + // set the point size + GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE)); + + // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't + // currently part of our gl interface. There are probably others as + // well. } - GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL)); - // Since ES doesn't support glPointSize at all we always use the VS to - // set the point size - GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE)); - - // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't - // currently part of our gl interface. There are probably others as - // well. + fHWWriteToColor = kUnknown_TriState; + // we only ever use lines in hairline mode + GL_CALL(LineWidth(1)); } - fHWAAState.invalidate(); - fHWWriteToColor = kUnknown_TriState; - // we only ever use lines in hairline mode - GL_CALL(LineWidth(1)); + if (resetBits & kAA_GrGLBackendState) { + fHWAAState.invalidate(); + } // invalid - fHWActiveTextureUnitIdx = -1; - - fHWBlendState.invalidate(); - - for (int s = 0; s < fHWBoundTextures.count(); ++s) { - fHWBoundTextures[s] = NULL; + if (resetBits & kTextureBinding_GrGLBackendState) { + fHWActiveTextureUnitIdx = -1; + for (int s = 0; s < fHWBoundTextures.count(); ++s) { + fHWBoundTextures[s] = NULL; + } } - fHWScissorSettings.invalidate(); + if (resetBits & kBlend_GrGLBackendState) { + fHWBlendState.invalidate(); + } - fHWViewport.invalidate(); + if (resetBits & kView_GrGLBackendState) { + fHWScissorSettings.invalidate(); + fHWViewport.invalidate(); + } - fHWStencilSettings.invalidate(); - fHWStencilTestEnabled = kUnknown_TriState; + if (resetBits & kStencil_GrGLBackendState) { + fHWStencilSettings.invalidate(); + fHWStencilTestEnabled = kUnknown_TriState; + } - fHWGeometryState.invalidate(); + // Vertex + if (resetBits & kVertex_GrGLBackendState) { + fHWGeometryState.invalidate(); + } - fHWBoundRenderTarget = NULL; + if (resetBits & kRenderTarget_GrGLBackendState) { + fHWBoundRenderTarget = NULL; + } - fHWPathStencilMatrixState.invalidate(); - if (this->caps()->pathStencilingSupport()) { - // we don't use the model view matrix. - GL_CALL(MatrixMode(GR_GL_MODELVIEW)); - GL_CALL(LoadIdentity()); + if (resetBits & kPathStencil_GrGLBackendState) { + fHWPathStencilMatrixState.invalidate(); + if (this->caps()->pathStencilingSupport()) { + // we don't use the model view matrix. + GL_CALL(MatrixMode(GR_GL_MODELVIEW)); + GL_CALL(LoadIdentity()); + } } // we assume these values - if (this->glCaps().unpackRowLengthSupport()) { - GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); - } - if (this->glCaps().packRowLengthSupport()) { - GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); - } - if (this->glCaps().unpackFlipYSupport()) { - GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); - } - if (this->glCaps().packFlipYSupport()) { - GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); + if (resetBits & kPixelStore_GrGLBackendState) { + if (this->glCaps().unpackRowLengthSupport()) { + GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); + } + if (this->glCaps().packRowLengthSupport()) { + GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0)); + } + if (this->glCaps().unpackFlipYSupport()) { + GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); + } + if (this->glCaps().packFlipYSupport()) { + GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); + } } - fHWProgramID = 0; - fSharedGLProgramState.invalidate(); + if (resetBits & kProgram_GrGLBackendState) { + fHWProgramID = 0; + fSharedGLProgramState.invalidate(); + } } namespace { diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index c644fbbac8..38e5842dce 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -102,7 +102,7 @@ protected: private: // GrGpu overrides - virtual void onResetContext() SK_OVERRIDE; + virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE; virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, const void* srcData, |