aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-28 14:10:15 +0000
committerGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-28 14:10:15 +0000
commitc077d1eaa8322087f3cc954c3b2e9af7fef103fc (patch)
tree686f1341f0eaba197fca4fefe32c13516c48a5ef
parentab303ef6e86089ae28f30a52149f1dae177e1468 (diff)
Rolling back 4053
git-svn-id: http://skia.googlecode.com/svn/trunk@4054 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/gpu/GrContext.h11
-rw-r--r--src/gpu/GrContext.cpp6
-rw-r--r--src/gpu/GrDrawState.h139
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp19
-rw-r--r--src/gpu/SkGpuDevice.cpp4
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()) {