Chromium Code Reviews| Index: src/gpu/GrDrawState.h |
| diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h |
| index 2fe56a3d3431157151514a35495ad19e2b8cf3cc..24b213148876deb92282faba681946c5e76ef5b2 100644 |
| --- a/src/gpu/GrDrawState.h |
| +++ b/src/gpu/GrDrawState.h |
| @@ -9,6 +9,7 @@ |
| #define GrDrawState_DEFINED |
| #include "GrBlend.h" |
| +#include "GrOptDrawState.h" |
| #include "GrProgramResource.h" |
| #include "GrRODrawState.h" |
| #include "effects/GrSimpleTextureEffect.h" |
| @@ -23,12 +24,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 +37,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 +47,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. |
| @@ -100,7 +104,8 @@ public: |
| public: |
| AutoVertexAttribRestore(GrDrawState* drawState); |
| - ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount, fVAStride); } |
| + ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount, |
| + fVAStride); } |
| private: |
| GrDrawState* fDrawState; |
| @@ -135,8 +140,10 @@ public: |
| * @param color the color to set. |
| */ |
| void setColor(GrColor color) { |
| - fColor = color; |
| - this->invalidateBlendOptFlags(); |
| + if (color != fColor) { |
| + fColor = color; |
| + this->invalidateOptState(); |
| + } |
| } |
| /** |
| @@ -159,8 +166,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(); |
| + } |
| } |
| /// @} |
| @@ -202,14 +211,14 @@ public: |
| const GrEffect* addColorEffect(const GrEffect* effect, int attr0 = -1, int attr1 = -1) { |
| SkASSERT(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(effect); |
| SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1)); |
| - this->invalidateBlendOptFlags(); |
| + this->invalidateOptState(); |
| return effect; |
| } |
| @@ -301,9 +310,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"); |
| @@ -325,34 +336,13 @@ public: |
| * @param constant the constant to set |
| */ |
| void setBlendConstant(GrColor constant) { |
| - fBlendConstant = constant; |
| - this->invalidateBlendOptFlags(); |
| + if (constant != fBlendConstant) { |
| + fBlendConstant = constant; |
| + // TODO: we should copy new blend |
|
bsalomon
2014/09/08 20:59:03
incomplete comment?
egdaniel
2014/09/11 15:35:42
removed
On 2014/09/08 20:59:03, bsalomon wrote:
|
| + this->invalidateOptState(); |
| + } |
| } |
| - /** |
| - * Determines what optimizations can be applied based on the blend. The coefficients may have |
| - * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional |
| - * params that receive the tweaked coefficients. Normally the function looks at the current |
| - * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively |
| - * determine the blend optimizations that would be used if there was partial pixel coverage. |
| - * |
| - * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for |
| - * playback) must call this function and respect the flags that replace the output color. |
| - * |
| - * If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will |
| - * simply returned the cached flags and coefficients. Otherwise it will calculate the values. |
| - */ |
| - BlendOptFlags getBlendOpts(bool forceCoverage = false, |
| - GrBlendCoeff* srcCoeff = NULL, |
| - GrBlendCoeff* dstCoeff = NULL) const; |
| - |
| - /** |
| - * We don't use suplied vertex color attributes if our blend mode is EmitCoverage or |
| - * EmitTransBlack |
| - */ |
| - bool canIgnoreColorAttribute() const; |
| - |
| - |
| /// @} |
| /////////////////////////////////////////////////////////////////////////// |
| @@ -416,6 +406,7 @@ public: |
| */ |
| void setRenderTarget(GrRenderTarget* target) { |
| fRenderTarget.setResource(SkSafeRef(target), GrProgramResource::kWrite_IOType); |
| + this->invalidateOptState(); |
| } |
| /// @} |
| @@ -432,16 +423,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; } |
| @@ -453,8 +448,10 @@ public: |
| //// |
| void resetStateFlags() { |
| - fFlagBits = 0; |
| - this->invalidateBlendOptFlags(); |
| + if (0 != fFlagBits) { |
| + fFlagBits = 0; |
| + this->invalidateOptState(); |
| + } |
| } |
| /** |
| @@ -463,8 +460,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(); |
| + } |
| } |
| /** |
| @@ -473,8 +472,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(); |
| + } |
| } |
| /** |
| @@ -513,8 +514,6 @@ public: |
| /// Hints that when provided can enable optimizations. |
| //// |
| - enum Hints { kVertexColorsAreOpaque_Hint = 0x1, }; |
| - |
| void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); } |
| /// @} |
| @@ -542,33 +541,38 @@ public: |
| GrDrawState& operator= (const GrDrawState& that); |
| -private: |
| - void onReset(const SkMatrix* initialViewMatrix); |
| - |
| /** |
| - * Determines whether src alpha is guaranteed to be one for all src pixels |
| + * 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. |
| */ |
| - bool srcAlphaWillBeOne() const; |
| + GrOptDrawState* createOptState() const; |
| - /** |
| - * Helper function for getBlendOpts. |
| - */ |
| - BlendOptFlags calcBlendOpts(bool forceCoverage = false, |
| - GrBlendCoeff* srcCoeff = NULL, |
| - GrBlendCoeff* dstCoeff = NULL) const; |
| +private: |
| + void invalidateBlendOptFlags() const { |
|
bsalomon
2014/09/08 20:59:03
if invalidateOptState() is the only caller of this
egdaniel
2014/09/11 15:35:42
Merged together
On 2014/09/08 20:59:03, bsalomon w
|
| + fBlendOptFlags = kInvalid_BlendOptFlag; |
| + } |
| + |
| + void invalidateOptState() const { |
| + SkSafeSetNull(fCachedOptState); |
| + this->invalidateBlendOptFlags(); |
| + } |
| + |
| + void onReset(const SkMatrix* initialViewMatrix); |
| void invalidateBlendOptFlags() { |
| fBlendOptFlags = kInvalid_BlendOptFlag; |
| } |
| - uint32_t fHints; |
| - |
| // Some of the auto restore objects assume that no effects are removed during their lifetime. |
| // This is used to assert that this condition holds. |
| SkDEBUGCODE(int fBlockEffectRemovalCnt;) |
| void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride); |
| + mutable GrOptDrawState* fCachedOptState; |
| + |
| typedef GrRODrawState INHERITED; |
| }; |