From c077d1eaa8322087f3cc954c3b2e9af7fef103fc Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Mon, 28 May 2012 14:10:15 +0000 Subject: Rolling back 4053 git-svn-id: http://skia.googlecode.com/svn/trunk@4054 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/gpu/GrContext.h | 11 ++-- src/gpu/GrContext.cpp | 6 -- src/gpu/GrDrawState.h | 139 +++++++++++++++++----------------------- src/gpu/GrInOrderDrawBuffer.cpp | 19 ++++++ src/gpu/SkGpuDevice.cpp | 4 -- 5 files changed, 81 insertions(+), 98 deletions(-) diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 470741e7d5..c9c15dfcac 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -857,13 +857,8 @@ public: } ~GrAutoScratchTexture() { - this->reset(); - } - - void reset() { if (NULL != fContext) { fContext->unlockTexture(fEntry); - fEntry.reset(); } } @@ -871,8 +866,10 @@ public: const GrTextureDesc& desc, GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) { - this->reset(); - + if (NULL != fContext) { + fContext->unlockTexture(fEntry); + fEntry.reset(); + } fContext = context; if (NULL != fContext) { fEntry = fContext->lockScratchTexture(desc, match); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index e0307f5e19..80dd25ebee 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -69,12 +69,6 @@ GrContext* GrContext::Create(GrEngine engine, GrContext::~GrContext() { this->flush(); - // the context's drawstate can be holding onto texture/render target refs. - // Relinquish them before the texture cache is freed lest a cached - // texture/RT not be freed in the right order - fDrawState->reset(); - // The gpu refs textures in its drawstate. - fGpu->setDrawState(NULL); // Since the gpu can hold scratch textures, give it a chance to let go // of them before freeing the texture cache fGpu->purgeResources(); diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index a568ca776b..79d6d483f1 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -14,10 +14,11 @@ #include "GrRefCnt.h" #include "GrSamplerState.h" #include "GrStencil.h" -#include "GrRenderTarget.h" #include "SkXfermode.h" +class GrRenderTarget; +class GrTexture; class GrDrawState : public GrRefCnt { @@ -52,52 +53,18 @@ public: typedef uint32_t StageMask; GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages); - GrDrawState() - : fRenderTarget(NULL) { - - for (int i = 0; i < kNumStages; ++i) { - fTextures[i] = NULL; - } - + GrDrawState() { this->reset(); } - GrDrawState(const GrDrawState& state) - : fRenderTarget(NULL) { - - for (int i = 0; i < kNumStages; ++i) { - fTextures[i] = NULL; - } - + GrDrawState(const GrDrawState& state) { *this = state; } - virtual ~GrDrawState() { - for (int i = 0; i < kNumStages; ++i) { - GrSafeSetNull(fTextures[i]); - } - GrSafeSetNull(fRenderTarget); - } - /** * Resets to the default state. Sampler states will not be modified. */ void reset() { - - for (int i = 0; i < kNumStages; ++i) { - // just as in setTexture we have to detach the texture before - // unreffing it because, if a texture is actually freed here, - // GrGLTexture's onRelease method will try to remove it from all - // possible owner's (including this one) via setTexture(NULL) - GrTexture* temp = fTextures[i]; - fTextures[i] = NULL; - GrSafeUnref(temp); - } - - GrRenderTarget* temp = fRenderTarget; - fRenderTarget = NULL; - GrSafeUnref(temp); - // make sure any pad is zero for memcmp // all GrDrawState members should default to something valid by the // the memset except those initialized individually below. There should @@ -118,13 +85,14 @@ public: fSrcBlend = kOne_BlendCoeff; fDstBlend = kZero_BlendCoeff; fViewMatrix.reset(); + fBehaviorBits = 0; // ensure values that will be memcmp'ed in == but not memset in reset() // are tightly packed GrAssert(this->memsetSize() + sizeof(fColor) + sizeof(fCoverage) + sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) + - sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(fTextures) + - sizeof(fRenderTarget) == this->podSize()); + sizeof(fSrcBlend) + sizeof(fDstBlend) == + this->podSize()); } /////////////////////////////////////////////////////////////////////////// @@ -206,14 +174,16 @@ public: void setTexture(int stage, GrTexture* texture) { GrAssert((unsigned)stage < kNumStages); - // If we don't clear out the current texture before unreffing - // it we can get into an infinite loop as the GrGLTexture's - // onRelease method recursively calls setTexture - GrTexture* temp = fTextures[stage]; - fTextures[stage] = NULL; + if (isBehaviorEnabled(kTexturesNeedRef_BehaviorBit)) { + // If we don't clear out the current texture before unreffing + // it we can get into an infinite loop as the GrGLTexture's + // onRelease method recursively calls setTexture + GrTexture* temp = fTextures[stage]; + fTextures[stage] = NULL; - SkSafeRef(texture); - SkSafeUnref(temp); + SkSafeRef(texture); + SkSafeUnref(temp); + } fTextures[stage] = texture; } @@ -491,18 +461,7 @@ public: * * @param target The render target to set. */ - void setRenderTarget(GrRenderTarget* target) { - - // If we don't clear out the current render target before unreffing - // it we can get into an infinite loop as the GrGLRenderTarget's - // onRelease method recursively calls setTexture - GrRenderTarget* temp = fRenderTarget; - fRenderTarget = NULL; - - SkSafeRef(target); - SkSafeUnref(temp); - fRenderTarget = target; - } + void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; } /** * Retrieves the currently set rendertarget. @@ -520,26 +479,16 @@ public: fSavedTarget = NULL; this->set(ds, newTarget); } - ~AutoRenderTargetRestore() { this->restore(); } - - void restore() { + ~AutoRenderTargetRestore() { this->set(NULL, NULL); } + void set(GrDrawState* ds, GrRenderTarget* newTarget) { if (NULL != fDrawState) { fDrawState->setRenderTarget(fSavedTarget); - fDrawState = NULL; } - GrSafeSetNull(fSavedTarget); - } - - void set(GrDrawState* ds, GrRenderTarget* newTarget) { - this->restore(); - if (NULL != ds) { - GrAssert(NULL == fSavedTarget); fSavedTarget = ds->getRenderTarget(); - SkSafeRef(fSavedTarget); ds->setRenderTarget(newTarget); - fDrawState = ds; } + fDrawState = ds; } private: GrDrawState* fDrawState; @@ -732,6 +681,28 @@ public: fFlagBits = ds.fFlagBits; } + /** + * Flags that do not affect rendering. + */ + enum GrBehaviorBits { + /** + * Calls to setTexture will ref/unref the texture + */ + kTexturesNeedRef_BehaviorBit = 0x01, + }; + + void enableBehavior(uint32_t behaviorBits) { + fBehaviorBits |= behaviorBits; + } + + void disableBehavior(uint32_t behaviorBits) { + fBehaviorBits &= ~(behaviorBits); + } + + bool isBehaviorEnabled(uint32_t behaviorBits) const { + return 0 != (behaviorBits & fBehaviorBits); + } + /// @} /////////////////////////////////////////////////////////////////////////// @@ -777,6 +748,14 @@ public: return false; } + // kTexturesNeedRef is an internal flag for altering the draw state's + // behavior rather than a property that will impact drawing - ignore it + // here + if ((fBehaviorBits & ~kTexturesNeedRef_BehaviorBit) != + (s.fBehaviorBits & ~kTexturesNeedRef_BehaviorBit)) { + return false; + } + for (int i = 0; i < kNumStages; i++) { if (fTextures[i] && this->fSamplerStates[i] != s.fSamplerStates[i]) { @@ -801,16 +780,13 @@ public: memcpy(this->podStart(), s.podStart(), this->podSize()); fViewMatrix = s.fViewMatrix; + fBehaviorBits = s.fBehaviorBits; for (int i = 0; i < kNumStages; i++) { - SkSafeRef(fTextures[i]); // already copied by memcpy if (s.fTextures[i]) { this->fSamplerStates[i] = s.fSamplerStates[i]; } } - - SkSafeRef(fRenderTarget); // already copied by memcpy - if (kColorMatrix_StateBit & s.fFlagBits) { memcpy(this->fColorMatrix, s.fColorMatrix, sizeof(fColorMatrix)); } @@ -844,13 +820,15 @@ private: GrColor fBlendConstant; GrColor fPodStartMarker; }; + GrTexture* fTextures[kNumStages]; GrColor fColorFilterColor; uint32_t fFlagBits; DrawFace fDrawFace; + VertexEdgeType fVertexEdgeType; GrStencilSettings fStencilSettings; union { - VertexEdgeType fVertexEdgeType; - VertexEdgeType fMemsetEndMarker; + GrRenderTarget* fRenderTarget; + GrRenderTarget* fMemsetEndMarker; }; // @} @@ -861,14 +839,13 @@ private: int fFirstCoverageStage; SkXfermode::Mode fColorFilterMode; GrBlendCoeff fSrcBlend; - GrBlendCoeff fDstBlend; - GrTexture* fTextures[kNumStages]; union { - GrRenderTarget* fRenderTarget; - GrRenderTarget* fPodEndMarker; + GrBlendCoeff fDstBlend; + GrBlendCoeff fPodEndMarker; }; // @} + uint32_t fBehaviorBits; GrMatrix fViewMatrix; // This field must be last; it will not be copied or compared diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index c608013678..7b3b04f75b 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -460,7 +460,17 @@ void GrInOrderDrawBuffer::reset() { GrAssert(1 == fGeoPoolStateStack.count()); this->resetVertexSource(); this->resetIndexSource(); + uint32_t numStates = fStates.count(); + for (uint32_t i = 0; i < numStates; ++i) { + for (int s = 0; s < GrDrawState::kNumStages; ++s) { + GrSafeUnref(fStates[i].getTexture(s)); + } + GrSafeUnref(fStates[i].getRenderTarget()); + // GrInOrderDrawBuffer is no longer managing the refs/unrefs + // for the stored GrDrawStates + fStates[i].disableBehavior(GrDrawState::kTexturesNeedRef_BehaviorBit); + } int numDraws = fDraws.count(); for (int d = 0; d < numDraws; ++d) { // we always have a VB, but not always an IB @@ -770,7 +780,16 @@ bool GrInOrderDrawBuffer::needsNewState() const { } void GrInOrderDrawBuffer::pushState() { + const GrDrawState& drawState = this->getDrawState(); + for (int s = 0; s < GrDrawState::kNumStages; ++s) { + GrSafeRef(drawState.getTexture(s)); + } + GrSafeRef(drawState.getRenderTarget()); fStates.push_back(this->getDrawState()); + + // Any textures that are added to the stored state need to be + // reffed so the unref in reset doesn't inappropriately free them + fStates.back().enableBehavior(GrDrawState::kTexturesNeedRef_BehaviorBit); } bool GrInOrderDrawBuffer::needsNewClip() const { diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index d6dc010e81..411b2c5b8f 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -258,10 +258,6 @@ SkGpuDevice::~SkGpuDevice() { delete fDrawProcs; } - // The SkGpuDevice gives the context the render target (e.g., in gainFocus) - // This call gives the context a chance to relinquish it - fContext->setRenderTarget(NULL); - SkSafeUnref(fTexture); SkSafeUnref(fRenderTarget); if (fCache.texture()) { -- cgit v1.2.3