aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-23 19:53:46 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-23 19:53:46 +0000
commitca43208e4aaac817fbc8265542f995f24a3fb7bf (patch)
tree9fd08c7548afb896dc361e438f77f23c98b6c0b6
parent58f9ae1c7aa6e0a04c48ae907ad78f849ae14836 (diff)
Reland r7342 with fixes.
git-svn-id: http://skia.googlecode.com/svn/trunk@7346 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/gpu/GrEffect.h40
-rw-r--r--include/gpu/GrEffectStage.h58
-rw-r--r--src/gpu/GrDrawState.h294
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp21
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h12
5 files changed, 266 insertions, 159 deletions
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 4d9202fe3e..96702049e3 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -120,19 +120,7 @@ public:
effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
*/
bool isEqual(const GrEffectRef& other) const {
- if (&this->getFactory() != &other->getFactory()) {
- return false;
- }
- bool result = this->onIsEqual(*other.get());
-#if GR_DEBUG
- if (result) {
- GrAssert(this->numTextures() == other->numTextures());
- for (int i = 0; i < this->numTextures(); ++i) {
- GrAssert(*fTextureAccesses[i] == *other->fTextureAccesses[i]);
- }
- }
-#endif
- return result;
+ return this->isEqual(*other.get());
}
/** Human-meaningful string to identify this effect; may be embedded
@@ -162,8 +150,8 @@ public:
/** These use non-standard names because GrEffects should only be ref'ed an unref'ed deep in
the bowels. Rendering code should use GrEffectRef. */
- void addRef() { this->ref(); }
- void subRef() { this->unref(); }
+ void addRef() const { this->ref(); }
+ void subRef() const { this->unref(); }
protected:
/**
@@ -182,11 +170,14 @@ protected:
effect->fEffectRef = SkNEW_ARGS(GrEffectRef, (effect));
} else {
effect->fEffectRef->ref();
- GrCrash("This function should only be called once per effect currently.");
}
return effect->fEffectRef;
}
+ static const GrEffectRef* CreateEffectRef(const GrEffect* effect) {
+ return CreateEffectRef(const_cast<GrEffect*>(effect));
+ }
+
/** Helper used in subclass factory functions to unref the effect after it has been wrapped in a
GrEffectRef. E.g.:
@@ -214,6 +205,21 @@ protected:
}
private:
+ bool isEqual(const GrEffect& other) const {
+ if (&this->getFactory() != &other.getFactory()) {
+ return false;
+ }
+ bool result = this->onIsEqual(other);
+#if GR_DEBUG
+ if (result) {
+ GrAssert(this->numTextures() == other.numTextures());
+ for (int i = 0; i < this->numTextures(); ++i) {
+ GrAssert(*fTextureAccesses[i] == *other.fTextureAccesses[i]);
+ }
+ }
+#endif
+ return result;
+ }
/** Subclass implements this to support isEqual(). It will only be called if it is known that
the two effects are of the same subclass (i.e. they return the same object from
@@ -223,6 +229,8 @@ private:
void EffectRefDestroyed() { fEffectRef = NULL; }
friend class GrEffectRef; // to call GrEffectRef destroyed
+ friend class GrEffectStage; // to rewrap GrEffect in GrEffectRef when restoring an effect-stage
+ // from deferred state. And to call isEqual on naked GrEffects.
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
GrEffectRef* fEffectRef;
diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h
index c09cd450a7..b561aaac25 100644
--- a/include/gpu/GrEffectStage.h
+++ b/include/gpu/GrEffectStage.h
@@ -20,7 +20,6 @@
class GrEffectStage {
public:
-
GrEffectStage()
: fEffectRef (NULL) {
GR_DEBUGCODE(fSavedCoordChangeCnt = 0;)
@@ -96,6 +95,63 @@ public:
}
/**
+ * Used when storing a deferred GrDrawState. The DeferredStage allows resources owned by its
+ * GrEffect to be recycled through the cache.
+ */
+ class DeferredStage {
+ public:
+ DeferredStage() : fEffect(NULL) {
+ SkDEBUGCODE(fInitialized = false;)
+ }
+
+ void saveFrom(const GrEffectStage& stage) {
+ GrAssert(!fInitialized);
+ if (NULL != stage.fEffectRef) {
+ stage.fEffectRef->get()->addRef();
+ fEffect = stage.fEffectRef->get();
+ fCoordChangeMatrix = stage.fCoordChangeMatrix;
+ }
+ SkDEBUGCODE(fInitialized = true;)
+ }
+
+ void restoreTo(GrEffectStage* stage) {
+ GrAssert(fInitialized);
+ const GrEffectRef* oldEffectRef = stage->fEffectRef;
+ if (NULL != fEffect) {
+ stage->fEffectRef = GrEffect::CreateEffectRef(fEffect);
+ stage->fCoordChangeMatrix = fCoordChangeMatrix;
+ } else {
+ stage->fEffectRef = NULL;
+ }
+ SkSafeUnref(oldEffectRef);
+ }
+
+ bool isEqual(const GrEffectStage& stage) const {
+ if (NULL == stage.fEffectRef) {
+ return NULL == fEffect;
+ } else if (NULL == fEffect) {
+ return false;
+ }
+
+ if (!(*stage.getEffect())->isEqual(*fEffect)) {
+ return false;
+ }
+
+ return fCoordChangeMatrix == stage.fCoordChangeMatrix;
+ }
+
+ ~DeferredStage() {
+ if (NULL != fEffect) {
+ fEffect->subRef();
+ }
+ }
+ private:
+ const GrEffect* fEffect;
+ SkMatrix fCoordChangeMatrix;
+ SkDEBUGCODE(bool fInitialized;)
+ };
+
+ /**
* Gets the matrix representing all changes of coordinate system since the GrEffect was
* installed in the stage.
*/
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 4a99ecb942..820f79a6de 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -57,21 +57,16 @@ public:
kMaxTexCoords = kNumStages
};
- GrDrawState()
- : fRenderTarget(NULL) {
-
+ GrDrawState() {
this->reset();
}
- GrDrawState(const GrDrawState& state)
- : fRenderTarget(NULL) {
-
+ GrDrawState(const GrDrawState& state) {
*this = state;
}
virtual ~GrDrawState() {
this->disableStages();
- GrSafeSetNull(fRenderTarget);
}
/**
@@ -82,20 +77,21 @@ public:
this->disableStages();
- fColor = 0xffffffff;
- fViewMatrix.reset();
- GrSafeSetNull(fRenderTarget);
- fSrcBlend = kOne_GrBlendCoeff;
- fDstBlend = kZero_GrBlendCoeff;
- fBlendConstant = 0x0;
- fFlagBits = 0x0;
- fVertexEdgeType = kHairLine_EdgeType;
- fStencilSettings.setDisabled();
- fFirstCoverageStage = kNumStages;
- fCoverage = 0xffffffff;
- fColorFilterMode = SkXfermode::kDst_Mode;
- fColorFilterColor = 0x0;
- fDrawFace = kBoth_DrawFace;
+ fRenderTarget.reset(NULL);
+
+ fCommon.fColor = 0xffffffff;
+ fCommon.fViewMatrix.reset();
+ fCommon.fSrcBlend = kOne_GrBlendCoeff;
+ fCommon.fDstBlend = kZero_GrBlendCoeff;
+ fCommon.fBlendConstant = 0x0;
+ fCommon.fFlagBits = 0x0;
+ fCommon.fVertexEdgeType = kHairLine_EdgeType;
+ fCommon.fStencilSettings.setDisabled();
+ fCommon.fFirstCoverageStage = kNumStages;
+ fCommon.fCoverage = 0xffffffff;
+ fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
+ fCommon.fColorFilterColor = 0x0;
+ fCommon.fDrawFace = kBoth_DrawFace;
}
/**
@@ -115,9 +111,9 @@ public:
*
* @param color the color to set.
*/
- void setColor(GrColor color) { fColor = color; }
+ void setColor(GrColor color) { fCommon.fColor = color; }
- GrColor getColor() const { return fColor; }
+ GrColor getColor() const { return fCommon.fColor; }
/**
* Sets the color to be used for the next draw to be
@@ -134,12 +130,12 @@ public:
* after color-computing texture stages.
*/
void setColorFilter(GrColor c, SkXfermode::Mode mode) {
- fColorFilterColor = c;
- fColorFilterMode = mode;
+ fCommon.fColorFilterColor = c;
+ fCommon.fColorFilterMode = mode;
}
- GrColor getColorFilterColor() const { return fColorFilterColor; }
- SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
+ GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
+ SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
/**
* Constructor sets the color to be 'color' which is undone by the destructor.
@@ -171,7 +167,7 @@ public:
* coverage is ignored when per-vertex coverage is provided.
*/
void setCoverage(uint8_t coverage) {
- fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
+ fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
}
/**
@@ -179,11 +175,11 @@ public:
* should be premultiplied.
*/
void setCoverage4(GrColor coverage) {
- fCoverage = coverage;
+ fCommon.fCoverage = coverage;
}
GrColor getCoverage() const {
- return fCoverage;
+ return fCommon.fCoverage;
}
/// @}
@@ -315,14 +311,14 @@ public:
*/
void setFirstCoverageStage(int firstCoverageStage) {
GrAssert((unsigned)firstCoverageStage <= kNumStages);
- fFirstCoverageStage = firstCoverageStage;
+ fCommon.fFirstCoverageStage = firstCoverageStage;
}
/**
* Gets the index of the first coverage-computing stage.
*/
int getFirstCoverageStage() const {
- return fFirstCoverageStage;
+ return fCommon.fFirstCoverageStage;
}
///@}
@@ -345,8 +341,8 @@ public:
* @param dstCoef coefficient applied to the dst color.
*/
void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
- fSrcBlend = srcCoeff;
- fDstBlend = dstCoeff;
+ fCommon.fSrcBlend = srcCoeff;
+ fCommon.fDstBlend = dstCoeff;
#if GR_DEBUG
switch (dstCoeff) {
case kDC_GrBlendCoeff:
@@ -373,13 +369,13 @@ public:
#endif
}
- GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
- GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
+ GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
+ GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
GrBlendCoeff* dstBlendCoeff) const {
- *srcBlendCoeff = fSrcBlend;
- *dstBlendCoeff = fDstBlend;
+ *srcBlendCoeff = fCommon.fSrcBlend;
+ *dstBlendCoeff = fCommon.fDstBlend;
}
/**
@@ -392,13 +388,13 @@ public:
*
* @param constant the constant to set
*/
- void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
+ void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
/**
* Retrieves the last value set by setBlendConstant()
* @return the blending constant value
*/
- GrColor getBlendConstant() const { return fBlendConstant; }
+ GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
/// @}
@@ -411,14 +407,14 @@ public:
*
* In the post-view-matrix space the rectangle [0,w]x[0,h]
* fully covers the render target. (w and h are the width and height of the
- * the rendertarget.)
+ * the render-target.)
*/
- void setViewMatrix(const SkMatrix& m) { fViewMatrix = m; }
+ void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
/**
* Gets a writable pointer to the view matrix.
*/
- SkMatrix* viewMatrix() { return &fViewMatrix; }
+ SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
/**
* Multiplies the current view matrix by a matrix
@@ -430,7 +426,7 @@ public:
*
* @param m the matrix used to modify the view matrix.
*/
- void preConcatViewMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); }
+ void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
/**
* Multiplies the current view matrix by a matrix
@@ -442,13 +438,13 @@ public:
*
* @param m the matrix used to modify the view matrix.
*/
- void postConcatViewMatrix(const SkMatrix& m) { fViewMatrix.postConcat(m); }
+ void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
/**
* Retrieves the current view matrix
* @return the current view matrix.
*/
- const SkMatrix& getViewMatrix() const { return fViewMatrix; }
+ const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
/**
* Retrieves the inverse of the current view matrix.
@@ -463,7 +459,7 @@ public:
// TODO: determine whether we really need to leave matrix unmodified
// at call sites when inversion fails.
SkMatrix inverse;
- if (fViewMatrix.invert(&inverse)) {
+ if (fCommon.fViewMatrix.invert(&inverse)) {
if (matrix) {
*matrix = inverse;
}
@@ -570,21 +566,21 @@ public:
////
/**
- * Sets the rendertarget used at the next drawing call
+ * Sets the render-target used at the next drawing call
*
* @param target The render target to set.
*/
void setRenderTarget(GrRenderTarget* target) {
- GrSafeAssign(fRenderTarget, target);
+ fRenderTarget.reset(SkSafeRef(target));
}
/**
- * Retrieves the currently set rendertarget.
+ * Retrieves the currently set render-target.
*
* @return The currently set render target.
*/
- const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
- GrRenderTarget* getRenderTarget() { return fRenderTarget; }
+ const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
+ GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
class AutoRenderTargetRestore : public ::GrNoncopyable {
public:
@@ -634,19 +630,19 @@ public:
* @param settings the stencil settings to use.
*/
void setStencil(const GrStencilSettings& settings) {
- fStencilSettings = settings;
+ fCommon.fStencilSettings = settings;
}
/**
* Shortcut to disable stencil testing and ops.
*/
void disableStencil() {
- fStencilSettings.setDisabled();
+ fCommon.fStencilSettings.setDisabled();
}
- const GrStencilSettings& getStencil() const { return fStencilSettings; }
+ const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
- GrStencilSettings* stencil() { return &fStencilSettings; }
+ GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
/// @}
@@ -695,10 +691,10 @@ public:
*/
void setVertexEdgeType(VertexEdgeType type) {
GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
- fVertexEdgeType = type;
+ fCommon.fVertexEdgeType = type;
}
- VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
+ VertexEdgeType getVertexEdgeType() const { return fCommon.fVertexEdgeType; }
/// @}
@@ -747,7 +743,7 @@ public:
};
void resetStateFlags() {
- fFlagBits = 0;
+ fCommon.fFlagBits = 0;
}
/**
@@ -756,7 +752,7 @@ public:
* @param stateBits bitfield of StateBits specifying the states to enable
*/
void enableState(uint32_t stateBits) {
- fFlagBits |= stateBits;
+ fCommon.fFlagBits |= stateBits;
}
/**
@@ -765,7 +761,7 @@ public:
* @param stateBits bitfield of StateBits specifying the states to disable
*/
void disableState(uint32_t stateBits) {
- fFlagBits &= ~(stateBits);
+ fCommon.fFlagBits &= ~(stateBits);
}
/**
@@ -783,27 +779,27 @@ public:
}
bool isDitherState() const {
- return 0 != (fFlagBits & kDither_StateBit);
+ return 0 != (fCommon.fFlagBits & kDither_StateBit);
}
bool isHWAntialiasState() const {
- return 0 != (fFlagBits & kHWAntialias_StateBit);
+ return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
}
bool isClipState() const {
- return 0 != (fFlagBits & kClip_StateBit);
+ return 0 != (fCommon.fFlagBits & kClip_StateBit);
}
bool isColorWriteDisabled() const {
- return 0 != (fFlagBits & kNoColorWrites_StateBit);
+ return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
}
bool isCoverageDrawing() const {
- return 0 != (fFlagBits & kCoverageDrawing_StateBit);
+ return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
}
bool isStateFlagEnabled(uint32_t stateBit) const {
- return 0 != (stateBit & fFlagBits);
+ return 0 != (stateBit & fCommon.fFlagBits);
}
/// @}
@@ -826,7 +822,7 @@ public:
*/
void setDrawFace(DrawFace face) {
GrAssert(kInvalid_DrawFace != face);
- fDrawFace = face;
+ fCommon.fDrawFace = face;
}
/**
@@ -834,7 +830,7 @@ public:
* or both faces.
* @return the current draw face(s).
*/
- DrawFace getDrawFace() const { return fDrawFace; }
+ DrawFace getDrawFace() const { return fCommon.fDrawFace; }
/// @}
@@ -848,20 +844,7 @@ public:
// Most stages are usually not used, so conditionals here
// reduce the expected number of bytes touched by 50%.
bool operator ==(const GrDrawState& s) const {
- if (fColor != s.fColor ||
- !s.fViewMatrix.cheapEqualTo(fViewMatrix) ||
- fRenderTarget != s.fRenderTarget ||
- fSrcBlend != s.fSrcBlend ||
- fDstBlend != s.fDstBlend ||
- fBlendConstant != s.fBlendConstant ||
- fFlagBits != s.fFlagBits ||
- fVertexEdgeType != s.fVertexEdgeType ||
- fStencilSettings != s.fStencilSettings ||
- fFirstCoverageStage != s.fFirstCoverageStage ||
- fCoverage != s.fCoverage ||
- fColorFilterMode != s.fColorFilterMode ||
- fColorFilterColor != s.fColorFilterColor ||
- fDrawFace != s.fDrawFace) {
+ if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
return false;
}
@@ -878,54 +861,123 @@ public:
}
bool operator !=(const GrDrawState& s) const { return !(*this == s); }
- // Most stages are usually not used, so conditionals here
- // reduce the expected number of bytes touched by 50%.
- GrDrawState& operator =(const GrDrawState& s) {
- fColor = s.fColor;
- fViewMatrix = s.fViewMatrix;
- SkRefCnt_SafeAssign(fRenderTarget, s.fRenderTarget);
- fSrcBlend = s.fSrcBlend;
- fDstBlend = s.fDstBlend;
- fBlendConstant = s.fBlendConstant;
- fFlagBits = s.fFlagBits;
- fVertexEdgeType = s.fVertexEdgeType;
- fStencilSettings = s.fStencilSettings;
- fFirstCoverageStage = s.fFirstCoverageStage;
- fCoverage = s.fCoverage;
- fColorFilterMode = s.fColorFilterMode;
- fColorFilterColor = s.fColorFilterColor;
- fDrawFace = s.fDrawFace;
-
+ GrDrawState& operator= (const GrDrawState& s) {
+ this->setRenderTarget(s.fRenderTarget.get());
+ fCommon = s.fCommon;
for (int i = 0; i < kNumStages; i++) {
if (s.isStageEnabled(i)) {
this->fStages[i] = s.fStages[i];
}
}
-
return *this;
}
private:
- // These fields are roughly sorted by decreasing likelihood of being different in op==
- GrColor fColor;
- SkMatrix fViewMatrix;
- GrRenderTarget* fRenderTarget;
- GrBlendCoeff fSrcBlend;
- GrBlendCoeff fDstBlend;
- GrColor fBlendConstant;
- uint32_t fFlagBits;
- VertexEdgeType fVertexEdgeType;
- GrStencilSettings fStencilSettings;
- int fFirstCoverageStage;
- GrColor fCoverage;
- SkXfermode::Mode fColorFilterMode;
- GrColor fColorFilterColor;
- DrawFace fDrawFace;
-
- // This field must be last; it will not be copied or compared
- // if the corresponding fTexture[] is NULL.
- GrEffectStage fStages[kNumStages];
+ /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
+ struct CommonState {
+ // These fields are roughly sorted by decreasing likelihood of being different in op==
+ GrColor fColor;
+ SkMatrix fViewMatrix;
+ GrBlendCoeff fSrcBlend;
+ GrBlendCoeff fDstBlend;
+ GrColor fBlendConstant;
+ uint32_t fFlagBits;
+ VertexEdgeType fVertexEdgeType;
+ GrStencilSettings fStencilSettings;
+ int fFirstCoverageStage;
+ GrColor fCoverage;
+ SkXfermode::Mode fColorFilterMode;
+ GrColor fColorFilterColor;
+ DrawFace fDrawFace;
+ bool operator== (const CommonState& other) const {
+ return fColor == other.fColor &&
+ fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
+ fSrcBlend == other.fSrcBlend &&
+ fDstBlend == other.fDstBlend &&
+ fBlendConstant == other.fBlendConstant &&
+ fFlagBits == other.fFlagBits &&
+ fVertexEdgeType == other.fVertexEdgeType &&
+ fStencilSettings == other.fStencilSettings &&
+ fFirstCoverageStage == other.fFirstCoverageStage &&
+ fCoverage == other.fCoverage &&
+ fColorFilterMode == other.fColorFilterMode &&
+ fColorFilterColor == other.fColorFilterColor &&
+ fDrawFace == other.fDrawFace;
+ }
+ bool operator!= (const CommonState& other) const { return !(*this == other); }
+ };
+
+ /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
+ DeferredState must directly reference GrEffects, however. */
+ struct SavedEffectStage {
+ SavedEffectStage() : fEffect(NULL) {}
+ const GrEffect* fEffect;
+ GrEffectStage::SavedCoordChange fCoordChange;
+ };
+
+public:
+ /**
+ * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
+ * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
+ * dispose mechanism returns them to the cache. This allows recycling resources through the
+ * the cache while they are in a deferred draw queue.
+ */
+ class DeferredState {
+ public:
+ DeferredState() : fRenderTarget(NULL) {
+ GR_DEBUGCODE(fInitialized = false;)
+ }
+ // TODO: Remove this when DeferredState no longer holds a ref to the RT
+ ~DeferredState() { SkSafeUnref(fRenderTarget); }
+
+ void saveFrom(const GrDrawState& drawState) {
+ fCommon = drawState.fCommon;
+ // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
+ fRenderTarget = drawState.fRenderTarget.get();
+ SkSafeRef(fRenderTarget);
+ // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
+ // ref gets fully unref'ed it will cause the underlying effect to unref its resources
+ // and recycle them to the cache (if no one else is holding a ref to the resources).
+ for (int i = 0; i < kNumStages; ++i) {
+ fStages[i].saveFrom(drawState.fStages[i]);
+ }
+ GR_DEBUGCODE(fInitialized = true;)
+ }
+
+ void restoreTo(GrDrawState* drawState) {
+ GrAssert(fInitialized);
+ drawState->fCommon = fCommon;
+ drawState->setRenderTarget(fRenderTarget);
+ for (int i = 0; i < kNumStages; ++i) {
+ fStages[i].restoreTo(&drawState->fStages[i]);
+ }
+ }
+
+ bool isEqual(const GrDrawState& state) const {
+ if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
+ return false;
+ }
+ for (int i = 0; i < kNumStages; ++i) {
+ if (fStages[i].isEqual(state.fStages[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private:
+ GrRenderTarget* fRenderTarget;
+ CommonState fCommon;
+ GrEffectStage::DeferredStage fStages[kNumStages];
+
+ GR_DEBUGCODE(bool fInitialized;)
+ };
+
+private:
+ SkAutoTUnref<GrRenderTarget> fRenderTarget;
+ CommonState fCommon;
+ GrEffectStage fStages[kNumStages];
typedef GrRefCnt INHERITED;
};
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index e327413226..87ecc8579f 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -570,8 +570,11 @@ bool GrInOrderDrawBuffer::flushTo(GrDrawTarget* target) {
GrDrawTarget::AutoClipRestore acr(target);
AutoGeometryPush agp(target);
+
+ GrDrawState playbackState;
GrDrawState* prevDrawState = target->drawState();
prevDrawState->ref();
+ target->setDrawState(&playbackState);
GrClipData clipData;
@@ -581,6 +584,7 @@ bool GrInOrderDrawBuffer::flushTo(GrDrawTarget* target) {
int currDraw = 0;
int currStencilPath = 0;
+
for (int c = 0; c < numCmds; ++c) {
switch (fCmds[c]) {
case kDraw_Cmd: {
@@ -611,7 +615,7 @@ bool GrInOrderDrawBuffer::flushTo(GrDrawTarget* target) {
break;
}
case kSetState_Cmd:
- target->setDrawState(&fStates[currState]);
+ fStates[currState].restoreTo(&playbackState);
++currState;
break;
case kSetClip_Cmd:
@@ -860,7 +864,7 @@ void GrInOrderDrawBuffer::geometrySourceWillPop(
}
bool GrInOrderDrawBuffer::needsNewState() const {
- return fStates.empty() || fStates.back() != this->getDrawState();
+ return fStates.empty() || !fStates.back().isEqual(this->getDrawState());
}
bool GrInOrderDrawBuffer::needsNewClip() const {
@@ -883,19 +887,8 @@ void GrInOrderDrawBuffer::recordClip() {
fCmds.push_back(kSetClip_Cmd);
}
-void GrInOrderDrawBuffer::recordDefaultClip() {
- fClips.push_back() = SkClipStack();
- fClipOrigins.push_back() = SkIPoint::Make(0, 0);
- fCmds.push_back(kSetClip_Cmd);
-}
-
void GrInOrderDrawBuffer::recordState() {
- fStates.push_back(this->getDrawState());
- fCmds.push_back(kSetState_Cmd);
-}
-
-void GrInOrderDrawBuffer::recordDefaultState() {
- fStates.push_back(GrDrawState());
+ fStates.push_back().saveFrom(this->getDrawState());
fCmds.push_back(kSetState_Cmd);
}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 1b893accd9..35cccbd48c 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -184,9 +184,7 @@ private:
// these functions record a command
void recordState();
- void recordDefaultState();
void recordClip();
- void recordDefaultClip();
Draw* recordDraw();
StencilPath* recordStencilPath();
Clear* recordClear();
@@ -205,11 +203,11 @@ private:
kGeoPoolStatePreAllocCnt = 4,
};
- SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
- GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
- GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths;
- GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
- GrSTAllocator<kClearPreallocCnt, Clear> fClears;
+ SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
+ GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
+ GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths;
+ GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState> fStates;
+ GrSTAllocator<kClearPreallocCnt, Clear> fClears;
GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips;
GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins;