Index: src/gpu/GrDrawState.h |
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h |
index dcd6ff9aaf8459f03ee68ec12b65c7e38311c02c..bbc8cc8cbb2068749cd6896914d29027388a3b23 100644 |
--- a/src/gpu/GrDrawState.h |
+++ b/src/gpu/GrDrawState.h |
@@ -8,9 +8,9 @@ |
#ifndef GrDrawState_DEFINED |
#define GrDrawState_DEFINED |
-#include "GrRODrawState.h" |
- |
#include "GrBlend.h" |
+#include "GrOptDrawState.h" |
+#include "GrRODrawState.h" |
#include "effects/GrSimpleTextureEffect.h" |
/** |
@@ -23,12 +23,12 @@ class GrDrawState : public GrRODrawState { |
public: |
SK_DECLARE_INST_COUNT(GrDrawState) |
- GrDrawState() { |
+ GrDrawState() : fCachedOptState(NULL) { |
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
this->reset(); |
} |
- GrDrawState(const SkMatrix& initialViewMatrix) { |
+ GrDrawState(const SkMatrix& initialViewMatrix) : fCachedOptState(NULL) { |
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
this->reset(initialViewMatrix); |
} |
@@ -36,7 +36,7 @@ public: |
/** |
* Copies another draw state. |
**/ |
- GrDrawState(const GrDrawState& state) : INHERITED() { |
+ GrDrawState(const GrDrawState& state) : INHERITED(), fCachedOptState(NULL) { |
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
*this = state; |
} |
@@ -46,7 +46,10 @@ public: |
**/ |
GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix); |
- virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); } |
+ virtual ~GrDrawState() { |
+ SkSafeUnref(fCachedOptState); |
+ SkASSERT(0 == fBlockEffectRemovalCnt); |
+ } |
/** |
* Resets to the default state. GrEffects will be removed from all stages. |
@@ -131,8 +134,10 @@ public: |
* @param color the color to set. |
*/ |
void setColor(GrColor color) { |
- fColor = color; |
- this->invalidateBlendOptFlags(); |
+ if (color != fColor) { |
+ fColor = color; |
+ this->invalidateOptState(); |
+ } |
} |
/** |
@@ -155,8 +160,10 @@ public: |
* coverage is ignored when per-vertex coverage is provided. |
*/ |
void setCoverage(uint8_t coverage) { |
- fCoverage = coverage; |
- this->invalidateBlendOptFlags(); |
+ if (coverage != fCoverage) { |
+ fCoverage = coverage; |
+ this->invalidateOptState(); |
+ } |
} |
/// @} |
@@ -184,14 +191,14 @@ public: |
const GrEffect* addColorEffect(const GrEffect* effect, int attr0 = -1, int attr1 = -1) { |
SkASSERT(NULL != effect); |
SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1)); |
- this->invalidateBlendOptFlags(); |
+ this->invalidateOptState(); |
return effect; |
} |
const GrEffect* addCoverageEffect(const GrEffect* effect, int attr0 = -1, int attr1 = -1) { |
SkASSERT(NULL != effect); |
SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1)); |
- this->invalidateBlendOptFlags(); |
+ this->invalidateOptState(); |
return effect; |
} |
@@ -262,9 +269,11 @@ public: |
* @param dstCoef coefficient applied to the dst color. |
*/ |
void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { |
- fSrcBlend = srcCoeff; |
- fDstBlend = dstCoeff; |
- this->invalidateBlendOptFlags(); |
+ if (srcCoeff != fSrcBlend || dstCoeff != fDstBlend) { |
+ fSrcBlend = srcCoeff; |
+ fDstBlend = dstCoeff; |
+ this->invalidateOptState(); |
+ } |
#ifdef SK_DEBUG |
if (GrBlendCoeffRefsDst(dstCoeff)) { |
GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n"); |
@@ -286,8 +295,10 @@ public: |
* @param constant the constant to set |
*/ |
void setBlendConstant(GrColor constant) { |
- fBlendConstant = constant; |
- this->invalidateBlendOptFlags(); |
+ if (constant != fBlendConstant) { |
+ fBlendConstant = constant; |
+ this->invalidateOptState(); |
+ } |
} |
/** |
@@ -374,7 +385,10 @@ public: |
* |
* @param target The render target to set. |
*/ |
- void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); } |
+ void setRenderTarget(GrRenderTarget* target) { |
+ fRenderTarget.reset(SkSafeRef(target)); |
+ this->invalidateOptState(); |
+ } |
class AutoRenderTargetRestore : public ::SkNoncopyable { |
public: |
@@ -424,16 +438,20 @@ public: |
* @param settings the stencil settings to use. |
*/ |
void setStencil(const GrStencilSettings& settings) { |
- fStencilSettings = settings; |
- this->invalidateBlendOptFlags(); |
+ if (settings != fStencilSettings) { |
+ fStencilSettings = settings; |
+ this->invalidateOptState(); |
+ } |
} |
/** |
* Shortcut to disable stencil testing and ops. |
*/ |
void disableStencil() { |
- fStencilSettings.setDisabled(); |
- this->invalidateBlendOptFlags(); |
+ if (!fStencilSettings.isDisabled()) { |
+ fStencilSettings.setDisabled(); |
+ this->invalidateOptState(); |
+ } |
} |
GrStencilSettings* stencil() { return &fStencilSettings; } |
@@ -445,8 +463,10 @@ public: |
//// |
void resetStateFlags() { |
- fFlagBits = 0; |
- this->invalidateBlendOptFlags(); |
+ if (0 != fFlagBits) { |
+ fFlagBits = 0; |
+ this->invalidateOptState(); |
+ } |
} |
/** |
@@ -455,8 +475,10 @@ public: |
* @param stateBits bitfield of StateBits specifying the states to enable |
*/ |
void enableState(uint32_t stateBits) { |
- fFlagBits |= stateBits; |
- this->invalidateBlendOptFlags(); |
+ if (stateBits & ~fFlagBits) { |
+ fFlagBits |= stateBits; |
+ this->invalidateOptState(); |
+ } |
} |
/** |
@@ -465,8 +487,10 @@ public: |
* @param stateBits bitfield of StateBits specifying the states to disable |
*/ |
void disableState(uint32_t stateBits) { |
- fFlagBits &= ~(stateBits); |
- this->invalidateBlendOptFlags(); |
+ if (stateBits & fFlagBits) { |
+ fFlagBits &= ~(stateBits); |
+ this->invalidateOptState(); |
+ } |
} |
/** |
@@ -509,6 +533,8 @@ public: |
void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); } |
+ bool vertexColorsAreOpaque() const { return kVertexColorsAreOpaque_Hint & fHints; } |
+ |
/// @} |
/////////////////////////////////////////////////////////////////////////// |
@@ -534,7 +560,24 @@ public: |
GrDrawState& operator= (const GrDrawState& that); |
+ /** |
+ * Returns a snapshot of the current optimized state. If the current drawState has a valid |
+ * cached optimiezed state it will simply return a pointer to it otherwise it will create a new |
+ * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the |
+ * caller. |
+ */ |
+ GrOptDrawState* createOptState() const; |
+ |
private: |
+ void invalidateBlendOptFlags() const { |
+ fBlendOptFlags = kInvalid_BlendOptFlag; |
+ } |
+ |
+ void invalidateOptState() const { |
+ SkSafeSetNull(fCachedOptState); |
+ this->invalidateBlendOptFlags(); |
+ } |
+ |
void onReset(const SkMatrix* initialViewMatrix); |
/** |
@@ -567,6 +610,8 @@ private: |
*/ |
void setVertexAttribs(const GrVertexAttrib attribs[], int count); |
+ mutable GrOptDrawState* fCachedOptState; |
+ |
typedef GrRODrawState INHERITED; |
}; |