| Index: src/gpu/GrDrawState.h
|
| diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
|
| index 2fe56a3d3431157151514a35495ad19e2b8cf3cc..4850fc911c8dc35e1c9172172055cf8c33242d76 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();
|
| + }
|
| }
|
|
|
| /// @}
|
| @@ -175,7 +184,7 @@ public:
|
| SkASSERT(effect);
|
| SkASSERT(!this->hasGeometryProcessor());
|
| fGeometryProcessor.reset(new GrEffectStage(effect, attr0, attr1));
|
| - this->invalidateBlendOptFlags();
|
| + this->invalidateOptState();
|
| return effect;
|
| }
|
|
|
| @@ -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,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;
|
| -
|
| -
|
| /// @}
|
|
|
| ///////////////////////////////////////////////////////////////////////////
|
| @@ -416,6 +405,7 @@ public:
|
| */
|
| void setRenderTarget(GrRenderTarget* target) {
|
| fRenderTarget.setResource(SkSafeRef(target), GrProgramResource::kWrite_IOType);
|
| + this->invalidateOptState();
|
| }
|
|
|
| /// @}
|
| @@ -432,16 +422,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 +447,10 @@ public:
|
| ////
|
|
|
| void resetStateFlags() {
|
| - fFlagBits = 0;
|
| - this->invalidateBlendOptFlags();
|
| + if (0 != fFlagBits) {
|
| + fFlagBits = 0;
|
| + this->invalidateOptState();
|
| + }
|
| }
|
|
|
| /**
|
| @@ -463,8 +459,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 +471,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 +513,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 +540,34 @@ 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 invalidateOptState() const {
|
| + SkSafeSetNull(fCachedOptState);
|
| + fBlendOptFlags = kInvalid_BlendOptFlag;
|
| + }
|
| +
|
| + 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;
|
| };
|
|
|
|
|