aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-28 18:57:35 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-28 18:57:35 +0000
commit0a208a117b2d7f2c2231aa357f1db4864dbdcba3 (patch)
tree0263de23dcf967bc20b09ce86bdded12fad5c363
parentab03e6816b22ea1d8d12b74b7b077d77ff366d5d (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.h4
-rw-r--r--include/gpu/GrTypes.h25
-rw-r--r--src/gpu/GrContext.cpp4
-rw-r--r--src/gpu/GrGpu.cpp4
-rw-r--r--src/gpu/GrGpu.h14
-rw-r--r--src/gpu/gl/GrGpuGL.cpp150
-rw-r--r--src/gpu/gl/GrGpuGL.h2
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,