| Index: src/gpu/GrDrawState.h
|
| diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
|
| index dcd6ff9aaf8459f03ee68ec12b65c7e38311c02c..a810a61af06498a0ed1d501a1e202044a5b7856c 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,34 +295,12 @@ public:
|
| * @param constant the constant to set
|
| */
|
| void setBlendConstant(GrColor constant) {
|
| - fBlendConstant = constant;
|
| - this->invalidateBlendOptFlags();
|
| + if (constant != fBlendConstant) {
|
| + fBlendConstant = constant;
|
| + 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;
|
| -
|
| -
|
| /// @}
|
|
|
| ///////////////////////////////////////////////////////////////////////////
|
| @@ -374,7 +361,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 +414,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 +439,10 @@ public:
|
| ////
|
|
|
| void resetStateFlags() {
|
| - fFlagBits = 0;
|
| - this->invalidateBlendOptFlags();
|
| + if (0 != fFlagBits) {
|
| + fFlagBits = 0;
|
| + this->invalidateOptState();
|
| + }
|
| }
|
|
|
| /**
|
| @@ -455,8 +451,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 +463,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();
|
| + }
|
| }
|
|
|
| /**
|
| @@ -505,8 +505,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); }
|
|
|
| /// @}
|
| @@ -534,27 +532,30 @@ 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 {
|
| + 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;)
|
| @@ -567,6 +568,8 @@ private:
|
| */
|
| void setVertexAttribs(const GrVertexAttrib attribs[], int count);
|
|
|
| + mutable GrOptDrawState* fCachedOptState;
|
| +
|
| typedef GrRODrawState INHERITED;
|
| };
|
|
|
|
|