Chromium Code Reviews| Index: src/gpu/GrDrawState.cpp |
| diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp |
| index a6b3d68238cdc18a20f527c9f7a3dccd5b05b8c9..a59130ae822a5a58fcbc5debef32eb679bdf5acf 100644 |
| --- a/src/gpu/GrDrawState.cpp |
| +++ b/src/gpu/GrDrawState.cpp |
| @@ -6,8 +6,22 @@ |
| */ |
| #include "GrDrawState.h" |
| -#include "GrPaint.h" |
| + |
| #include "GrDrawTargetCaps.h" |
| +#include "GrOptDrawState.h" |
| +#include "GrPaint.h" |
| + |
| +//////////////////////////////////////////////////////////////////////////////s |
| + |
| +GrOptDrawState* GrDrawState::createOptState() const { |
| + if (NULL == fCachedOptState) { |
| + fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this)); |
| + } else { |
| + SkASSERT(GrOptDrawState(*this) == *fCachedOptState); |
| + } |
| + fCachedOptState->ref(); |
| + return fCachedOptState; |
| +} |
| //////////////////////////////////////////////////////////////////////////////s |
| @@ -50,7 +64,8 @@ GrDrawState::CombinedState GrDrawState::CombineIfPossible( |
| //////////////////////////////////////////////////////////////////////////////s |
| -GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) { |
| +GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) |
| + : fCachedOptState(NULL) { |
| SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
| *this = state; |
| if (!preConcatMatrix.isIdentity()) { |
| @@ -60,7 +75,7 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr |
| for (int i = 0; i < this->numCoverageStages(); ++i) { |
| fCoverageStages[i].localCoordChange(preConcatMatrix); |
| } |
| - this->invalidateBlendOptFlags(); |
| + this->invalidateOptState(); |
| } |
| } |
| @@ -87,6 +102,8 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { |
| fHints = that.fHints; |
| + SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState); |
| + |
| memcpy(fFixedFunctionVertexAttribIndices, |
| that.fFixedFunctionVertexAttribIndices, |
| sizeof(fFixedFunctionVertexAttribIndices)); |
| @@ -118,7 +135,7 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { |
| fHints = 0; |
| - this->invalidateBlendOptFlags(); |
| + this->invalidateOptState(); |
| } |
| bool GrDrawState::setIdentityViewMatrix() { |
| @@ -173,7 +190,7 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende |
| this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| this->setCoverage(paint.getCoverage()); |
| - this->invalidateBlendOptFlags(); |
| + this->invalidateOptState(); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -231,7 +248,7 @@ void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { |
| overlapCheck |= (mask << offsetShift); |
| #endif |
| } |
| - this->invalidateBlendOptFlags(); |
| + this->invalidateOptState(); |
| // Positions must be specified. |
| SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]); |
| } |
| @@ -251,7 +268,7 @@ void GrDrawState::setDefaultVertexAttribs() { |
| 0xff, |
| sizeof(fFixedFunctionVertexAttribIndices)); |
| fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; |
| - this->invalidateBlendOptFlags(); |
| + this->invalidateOptState(); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -273,8 +290,7 @@ bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
| ////////////////////////////////////////////////////////////////////////////// |
| -GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( |
| - GrDrawState* drawState) { |
| +GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawState) { |
| SkASSERT(NULL != drawState); |
| fDrawState = drawState; |
| fVAPtr = drawState->fVAPtr; |
| @@ -294,7 +310,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
| SkASSERT(n >= 0); |
| fDrawState->fCoverageStages.pop_back_n(n); |
| if (m + n > 0) { |
| - fDrawState->invalidateBlendOptFlags(); |
| + fDrawState->invalidateOptState(); |
| } |
| SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
| } |
| @@ -308,118 +324,6 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
| //////////////////////////////////////////////////////////////////////////////// |
| -GrRODrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
| - GrBlendCoeff* srcCoeff, |
| - GrBlendCoeff* dstCoeff) const { |
| - GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; |
| - if (NULL == srcCoeff) { |
| - srcCoeff = &bogusSrcCoeff; |
| - } |
| - if (NULL == dstCoeff) { |
| - dstCoeff = &bogusDstCoeff; |
| - } |
| - |
| - if (forceCoverage) { |
| - return this->calcBlendOpts(true, srcCoeff, dstCoeff); |
| - } |
| - |
| - if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) { |
| - *srcCoeff = fOptSrcBlend; |
| - *dstCoeff = fOptDstBlend; |
| - return fBlendOptFlags; |
| - } |
| - |
| - fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff); |
| - fOptSrcBlend = *srcCoeff; |
| - fOptDstBlend = *dstCoeff; |
| - |
| - return fBlendOptFlags; |
| -} |
| - |
| -GrRODrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, |
| - GrBlendCoeff* srcCoeff, |
| - GrBlendCoeff* dstCoeff) const { |
| - *srcCoeff = this->getSrcBlendCoeff(); |
| - *dstCoeff = this->getDstBlendCoeff(); |
| - |
| - if (this->isColorWriteDisabled()) { |
| - *srcCoeff = kZero_GrBlendCoeff; |
| - *dstCoeff = kOne_GrBlendCoeff; |
| - } |
| - |
| - bool srcAIsOne = this->srcAlphaWillBeOne(); |
| - bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || |
| - (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| - bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || |
| - (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| - |
| - // When coeffs are (0,1) there is no reason to draw at all, unless |
| - // stenciling is enabled. Having color writes disabled is effectively |
| - // (0,1). |
| - if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { |
| - if (this->getStencil().doesWrite()) { |
| - return kEmitCoverage_BlendOptFlag; |
| - } else { |
| - return kSkipDraw_BlendOptFlag; |
| - } |
| - } |
| - |
| - bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); |
| - |
| - // if we don't have coverage we can check whether the dst |
| - // has to read at all. If not, we'll disable blending. |
| - if (!hasCoverage) { |
| - if (dstCoeffIsZero) { |
| - if (kOne_GrBlendCoeff == *srcCoeff) { |
| - // if there is no coverage and coeffs are (1,0) then we |
| - // won't need to read the dst at all, it gets replaced by src |
| - *dstCoeff = kZero_GrBlendCoeff; |
| - return kNone_BlendOpt; |
| - } else if (kZero_GrBlendCoeff == *srcCoeff) { |
| - // if the op is "clear" then we don't need to emit a color |
| - // or blend, just write transparent black into the dst. |
| - *srcCoeff = kOne_GrBlendCoeff; |
| - *dstCoeff = kZero_GrBlendCoeff; |
| - return kEmitTransBlack_BlendOptFlag; |
| - } |
| - } |
| - } else if (this->isCoverageDrawing()) { |
| - // we have coverage but we aren't distinguishing it from alpha by request. |
| - return kCoverageAsAlpha_BlendOptFlag; |
| - } else { |
| - // check whether coverage can be safely rolled into alpha |
| - // of if we can skip color computation and just emit coverage |
| - if (this->canTweakAlphaForCoverage()) { |
| - return kCoverageAsAlpha_BlendOptFlag; |
| - } |
| - if (dstCoeffIsZero) { |
| - if (kZero_GrBlendCoeff == *srcCoeff) { |
| - // the source color is not included in the blend |
| - // the dst coeff is effectively zero so blend works out to: |
| - // (c)(0)D + (1-c)D = (1-c)D. |
| - *dstCoeff = kISA_GrBlendCoeff; |
| - return kEmitCoverage_BlendOptFlag; |
| - } else if (srcAIsOne) { |
| - // the dst coeff is effectively zero so blend works out to: |
| - // cS + (c)(0)D + (1-c)D = cS + (1-c)D. |
| - // If Sa is 1 then we can replace Sa with c |
| - // and set dst coeff to 1-Sa. |
| - *dstCoeff = kISA_GrBlendCoeff; |
| - return kCoverageAsAlpha_BlendOptFlag; |
| - } |
| - } else if (dstCoeffIsOne) { |
| - // the dst coeff is effectively one so blend works out to: |
| - // cS + (c)(1)D + (1-c)D = cS + D. |
| - *dstCoeff = kOne_GrBlendCoeff; |
| - return kCoverageAsAlpha_BlendOptFlag; |
| - } |
| - } |
| - |
| - return kNone_BlendOpt; |
| -} |
| - |
| -//////////////////////////////////////////////////////////////////////////////// |
| - |
| void GrDrawState::AutoViewMatrixRestore::restore() { |
| if (NULL != fDrawState) { |
| SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
| @@ -435,6 +339,7 @@ void GrDrawState::AutoViewMatrixRestore::restore() { |
| for (int s = 0; s < numCoverageStages; ++s, ++i) { |
| fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]); |
| } |
| + fDrawState->invalidateOptState(); |
|
bsalomon
2014/08/28 13:49:27
Again, could be more optimal here... There are pro
egdaniel
2014/08/28 14:39:38
Again feel like this one doesn't gain much from si
bsalomon
2014/08/28 15:05:02
See comment above, but definitely don't want to do
|
| fDrawState = NULL; |
| } |
| } |
| @@ -454,6 +359,7 @@ void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
| this->doEffectCoordChanges(preconcatMatrix); |
| SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
| + drawState->invalidateOptState(); |
| } |
| bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
| @@ -467,6 +373,7 @@ bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
| return true; |
| } |
| + drawState->invalidateOptState(); |
| fViewMatrix = drawState->getViewMatrix(); |
| if (0 == drawState->numTotalStages()) { |
| drawState->fViewMatrix.reset(); |
| @@ -505,66 +412,3 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co |
| } |
| } |
| -bool GrDrawState::srcAlphaWillBeOne() const { |
| - uint32_t validComponentFlags; |
| - GrColor color; |
| - // Check if per-vertex or constant color may have partial alpha |
| - if (this->hasColorVertexAttribute()) { |
| - if (fHints & kVertexColorsAreOpaque_Hint) { |
| - validComponentFlags = kA_GrColorComponentFlag; |
| - color = 0xFF << GrColor_SHIFT_A; |
| - } else { |
| - validComponentFlags = 0; |
| - color = 0; // not strictly necessary but we get false alarms from tools about uninit. |
| - } |
| - } else { |
| - validComponentFlags = kRGBA_GrColorComponentFlags; |
| - color = this->getColor(); |
| - } |
| - |
| - // Run through the color stages |
| - for (int s = 0; s < this->numColorStages(); ++s) { |
| - const GrEffect* effect = this->getColorStage(s).getEffect(); |
| - effect->getConstantColorComponents(&color, &validComponentFlags); |
| - } |
| - |
| - // Check whether coverage is treated as color. If so we run through the coverage computation. |
| - if (this->isCoverageDrawing()) { |
| - // The shader generated for coverage drawing runs the full coverage computation and then |
| - // makes the shader output be the multiplication of color and coverage. We mirror that here. |
| - GrColor coverage; |
| - uint32_t coverageComponentFlags; |
| - if (this->hasCoverageVertexAttribute()) { |
| - coverageComponentFlags = 0; |
| - coverage = 0; // suppresses any warnings. |
| - } else { |
| - coverageComponentFlags = kRGBA_GrColorComponentFlags; |
| - coverage = this->getCoverageColor(); |
| - } |
| - |
| - // Run through the coverage stages |
| - for (int s = 0; s < this->numCoverageStages(); ++s) { |
| - const GrEffect* effect = this->getCoverageStage(s).getEffect(); |
| - effect->getConstantColorComponents(&coverage, &coverageComponentFlags); |
| - } |
| - |
| - // Since the shader will multiply coverage and color, the only way the final A==1 is if |
| - // coverage and color both have A==1. |
| - return (kA_GrColorComponentFlag & validComponentFlags & coverageComponentFlags) && |
| - 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage); |
| - |
| - } |
| - |
| - return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color); |
| -} |
| - |
| -//////////////////////////////////////////////////////////////////////////////// |
| - |
| -bool GrDrawState::canIgnoreColorAttribute() const { |
| - if (fBlendOptFlags & kInvalid_BlendOptFlag) { |
| - this->getBlendOpts(); |
| - } |
| - return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFlag | |
| - GrRODrawState::kEmitCoverage_BlendOptFlag)); |
| -} |
| - |