| Index: src/gpu/GrDrawState.cpp
|
| diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
|
| index ffec6627ca4c9687b473faf6a09ce7b21bf36da0..642ec2669ff9e348f49153b400c75009587dc7cc 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()) {
|
| @@ -63,7 +78,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();
|
| }
|
| }
|
|
|
| @@ -97,6 +112,8 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
|
|
|
| fHints = that.fHints;
|
|
|
| + SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState);
|
| +
|
| memcpy(fFixedFunctionVertexAttribIndices,
|
| that.fFixedFunctionVertexAttribIndices,
|
| sizeof(fFixedFunctionVertexAttribIndices));
|
| @@ -131,7 +148,7 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
|
|
|
| fHints = 0;
|
|
|
| - this->invalidateBlendOptFlags();
|
| + this->invalidateOptState();
|
| }
|
|
|
| bool GrDrawState::setIdentityViewMatrix() {
|
| @@ -151,6 +168,7 @@ bool GrDrawState::setIdentityViewMatrix() {
|
| fCoverageStages[s].localCoordChange(invVM);
|
| }
|
| }
|
| + this->invalidateOptState();
|
| fViewMatrix.reset();
|
| return true;
|
| }
|
| @@ -190,7 +208,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();
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -247,7 +265,7 @@ void GrDrawState::internalSetVertexAttribs(const GrVertexAttrib* attribs, int co
|
| overlapCheck |= (mask << offsetShift);
|
| #endif
|
| }
|
| - this->invalidateBlendOptFlags();
|
| + this->invalidateOptState();
|
| // Positions must be specified.
|
| SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
|
| }
|
| @@ -267,7 +285,7 @@ void GrDrawState::setDefaultVertexAttribs() {
|
| 0xff,
|
| sizeof(fFixedFunctionVertexAttribIndices));
|
| fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
|
| - this->invalidateBlendOptFlags();
|
| + this->invalidateOptState();
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -289,8 +307,7 @@ bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
|
|
|
| //////////////////////////////////////////////////////////////////////////////
|
|
|
| -GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(
|
| - GrDrawState* drawState) {
|
| +GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawState) {
|
| SkASSERT(drawState);
|
| fDrawState = drawState;
|
| fVAPtr = drawState->fVAPtr;
|
| @@ -320,7 +337,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;)
|
| }
|
| @@ -338,118 +355,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 (fDrawState) {
|
| SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
|
| @@ -469,6 +374,7 @@ void GrDrawState::AutoViewMatrixRestore::restore() {
|
| for (int s = 0; s < numCoverageStages; ++s, ++i) {
|
| fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
|
| }
|
| + fDrawState->invalidateOptState();
|
| fDrawState = NULL;
|
| }
|
| }
|
| @@ -488,6 +394,7 @@ void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
|
|
|
| this->doEffectCoordChanges(preconcatMatrix);
|
| SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
|
| + drawState->invalidateOptState();
|
| }
|
|
|
| bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
|
| @@ -501,6 +408,7 @@ bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
|
| return true;
|
| }
|
|
|
| + drawState->invalidateOptState();
|
| fViewMatrix = drawState->getViewMatrix();
|
| if (0 == drawState->numTotalStages()) {
|
| drawState->fViewMatrix.reset();
|
| @@ -547,69 +455,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
|
| - if (this->hasGeometryProcessor()) {
|
| - const GrEffect* effect = fGeometryProcessor->getEffect();
|
| - effect->getConstantColorComponents(&coverage, &coverageComponentFlags);
|
| - }
|
| - 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));
|
| -}
|
|
|