From 776bdbde26217cc9afc2e83983ad863b8bb4d3b8 Mon Sep 17 00:00:00 2001 From: egdaniel Date: Wed, 6 Aug 2014 11:07:02 -0700 Subject: [PATCH] Create struct in GrDrawState to hold key DrawState data. Eventually this struct will be used to easily set values for a reduced, optimized drawstate BUG=skia: R=bsalomon@google.com Author: egdaniel@google.com Review URL: https://codereview.chromium.org/448453002 --- src/gpu/GrDrawState.cpp | 138 +++++++++++++++++++++------------------- src/gpu/GrDrawState.h | 65 +++++++++++++------ 2 files changed, 119 insertions(+), 84 deletions(-) diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 3189a0a07..a0dc426d7 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -10,6 +10,29 @@ //////////////////////////////////////////////////////////////////////////////s +bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b, + bool explicitLocalCoords) { + if (a.fColorStages.count() != b.fColorStages.count() || + a.fCoverageStages.count() != b.fCoverageStages.count() || + a.fSrcBlend != b.fSrcBlend || + a.fDstBlend != b.fDstBlend) { + return false; + } + for (int i = 0; i < a.fColorStages.count(); i++) { + if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i], + explicitLocalCoords)) { + return false; + } + } + for (int i = 0; i < a.fCoverageStages.count(); i++) { + if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStages[i], + explicitLocalCoords)) { + return false; + } + } + return true; +} +//////////////////////////////////////////////////////////////////////////////s GrDrawState::CombinedState GrDrawState::CombineIfPossible( const GrDrawState& a, const GrDrawState& b) { @@ -19,11 +42,7 @@ GrDrawState::CombinedState GrDrawState::CombineIfPossible( } if (a.fRenderTarget.get() != b.fRenderTarget.get() || - a.fColorStages.count() != b.fColorStages.count() || - a.fCoverageStages.count() != b.fCoverageStages.count() || !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) || - a.fSrcBlend != b.fSrcBlend || - a.fDstBlend != b.fDstBlend || a.fBlendConstant != b.fBlendConstant || a.fFlagBits != b.fFlagBits || a.fVACount != b.fVACount || @@ -39,21 +58,13 @@ GrDrawState::CombinedState GrDrawState::CombineIfPossible( } bool explicitLocalCoords = a.hasLocalCoordAttribute(); - for (int i = 0; i < a.fColorStages.count(); i++) { - if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i], - explicitLocalCoords)) { - return kIncompatible_CombinedState; - } - } - for (int i = 0; i < a.fCoverageStages.count(); i++) { - if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStages[i], - explicitLocalCoords)) { - return kIncompatible_CombinedState; - } - } + SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices, b.fFixedFunctionVertexAttribIndices, sizeof(a.fFixedFunctionVertexAttribIndices))); + if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) { + return kIncompatible_CombinedState; + } return kAOrB_CombinedState; } @@ -64,11 +75,11 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) *this = state; if (!preConcatMatrix.isIdentity()) { - for (int i = 0; i < fColorStages.count(); ++i) { - fColorStages[i].localCoordChange(preConcatMatrix); + for (int i = 0; i < this->numColorStages(); ++i) { + fState.fColorStages[i].localCoordChange(preConcatMatrix); } - for (int i = 0; i < fCoverageStages.count(); ++i) { - fCoverageStages[i].localCoordChange(preConcatMatrix); + for (int i = 0; i < this->numCoverageStages(); ++i) { + fState.fCoverageStages[i].localCoordChange(preConcatMatrix); } this->invalidateBlendOptFlags(); } @@ -79,8 +90,6 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { this->setRenderTarget(that.fRenderTarget.get()); fColor = that.fColor; fViewMatrix = that.fViewMatrix; - fSrcBlend = that.fSrcBlend; - fDstBlend = that.fDstBlend; fBlendConstant = that.fBlendConstant; fFlagBits = that.fFlagBits; fVACount = that.fVACount; @@ -88,12 +97,12 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { fStencilSettings = that.fStencilSettings; fCoverage = that.fCoverage; fDrawFace = that.fDrawFace; - fColorStages = that.fColorStages; - fCoverageStages = that.fCoverageStages; fOptSrcBlend = that.fOptSrcBlend; fOptDstBlend = that.fOptDstBlend; fBlendOptFlags = that.fBlendOptFlags; + fState = that.fState; + memcpy(fFixedFunctionVertexAttribIndices, that.fFixedFunctionVertexAttribIndices, sizeof(fFixedFunctionVertexAttribIndices)); @@ -102,8 +111,7 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); - fColorStages.reset(); - fCoverageStages.reset(); + fState.reset(); fRenderTarget.reset(NULL); @@ -115,8 +123,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { } else { fViewMatrix = *initialViewMatrix; } - fSrcBlend = kOne_GrBlendCoeff; - fDstBlend = kZero_GrBlendCoeff; fBlendConstant = 0x0; fFlagBits = 0x0; fStencilSettings.setDisabled(); @@ -127,17 +133,17 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { } bool GrDrawState::setIdentityViewMatrix() { - if (fColorStages.count() || fCoverageStages.count()) { + if (this->numTotalStages()) { SkMatrix invVM; if (!fViewMatrix.invert(&invVM)) { // sad trombone sound return false; } - for (int s = 0; s < fColorStages.count(); ++s) { - fColorStages[s].localCoordChange(invVM); + for (int s = 0; s < this->numColorStages(); ++s) { + fState.fColorStages[s].localCoordChange(invVM); } - for (int s = 0; s < fCoverageStages.count(); ++s) { - fCoverageStages[s].localCoordChange(invVM); + for (int s = 0; s < this->numCoverageStages(); ++s) { + fState.fCoverageStages[s].localCoordChange(invVM); } } fViewMatrix.reset(); @@ -147,15 +153,14 @@ bool GrDrawState::setIdentityViewMatrix() { void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) { SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); - fColorStages.reset(); - fCoverageStages.reset(); + fState.reset(); for (int i = 0; i < paint.numColorStages(); ++i) { - fColorStages.push_back(paint.getColorStage(i)); + fState.fColorStages.push_back(paint.getColorStage(i)); } for (int i = 0; i < paint.numCoverageStages(); ++i) { - fCoverageStages.push_back(paint.getCoverageStage(i)); + fState.fCoverageStages.push_back(paint.getCoverageStage(i)); } this->setRenderTarget(rt); @@ -268,10 +273,11 @@ bool GrDrawState::validateVertexAttribs() const { for (int i = 0; i < kMaxVertexAttribCnt; ++i) { slTypes[i] = static_cast(-1); } - int totalStages = fColorStages.count() + fCoverageStages.count(); + int totalStages = this->numTotalStages(); for (int s = 0; s < totalStages; ++s) { - int covIdx = s - fColorStages.count(); - const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx]; + int covIdx = s - this->numColorStages(); + const GrEffectStage& stage = covIdx < 0 ? this->getColorStage(s) : + this->getCoverageStage(covIdx); const GrEffect* effect = stage.getEffect(); SkASSERT(NULL != effect); // make sure that any attribute indices have the correct binding type, that the attrib @@ -304,14 +310,14 @@ bool GrDrawState::validateVertexAttribs() const { bool GrDrawState::willEffectReadDstColor() const { if (!this->isColorWriteDisabled()) { - for (int s = 0; s < fColorStages.count(); ++s) { - if (fColorStages[s].getEffect()->willReadDstColor()) { + for (int s = 0; s < this->numColorStages(); ++s) { + if (this->getColorStage(s).getEffect()->willReadDstColor()) { return true; } } } - for (int s = 0; s < fCoverageStages.count(); ++s) { - if (fCoverageStages[s].getEffect()->willReadDstColor()) { + for (int s = 0; s < this->numCoverageStages(); ++s) { + if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { return true; } } @@ -333,8 +339,8 @@ bool GrDrawState::srcAlphaWillBeOne() const { } // Run through the color stages - for (int s = 0; s < fColorStages.count(); ++s) { - const GrEffect* effect = fColorStages[s].getEffect(); + for (int s = 0; s < this->numColorStages(); ++s) { + const GrEffect* effect = this->getColorStage(s).getEffect(); effect->getConstantColorComponents(&color, &validComponentFlags); } @@ -350,8 +356,8 @@ bool GrDrawState::srcAlphaWillBeOne() const { color |= (SkMulDiv255Round(a, b) << (c * 8)); } } - for (int s = 0; s < fCoverageStages.count(); ++s) { - const GrEffect* effect = fCoverageStages[s].getEffect(); + for (int s = 0; s < this->numCoverageStages(); ++s) { + const GrEffect* effect = this->getCoverageStage(s).getEffect(); effect->getConstantColorComponents(&color, &validComponentFlags); } } @@ -375,8 +381,8 @@ bool GrDrawState::hasSolidCoverage() const { } // Run through the coverage stages and see if the coverage will be all ones at the end. - for (int s = 0; s < fCoverageStages.count(); ++s) { - const GrEffect* effect = fCoverageStages[s].getEffect(); + for (int s = 0; s < this->numCoverageStages(); ++s) { + const GrEffect* effect = this->getCoverageStage(s).getEffect(); effect->getConstantColorComponents(&coverage, &validComponentFlags); } return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage); @@ -398,9 +404,9 @@ bool GrDrawState::canTweakAlphaForCoverage() const { Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as color by definition. */ - return kOne_GrBlendCoeff == fDstBlend || - kISA_GrBlendCoeff == fDstBlend || - kISC_GrBlendCoeff == fDstBlend || + return kOne_GrBlendCoeff == fState.fDstBlend || + kISA_GrBlendCoeff == fState.fDstBlend || + kISC_GrBlendCoeff == fState.fDstBlend || this->isCoverageDrawing(); } @@ -467,7 +473,7 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, bool hasCoverage = forceCoverage || 0xffffffff != this->getCoverageColor() || this->hasCoverageVertexAttribute() || - fCoverageStages.count() > 0; + this->numCoverageStages() > 0; // if we don't have coverage we can check whether the dst // has to read at all. If not, we'll disable blending. @@ -544,13 +550,13 @@ GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { if (NULL != fDrawState) { - int m = fDrawState->fColorStages.count() - fColorEffectCnt; + int m = fDrawState->numColorStages() - fColorEffectCnt; SkASSERT(m >= 0); - fDrawState->fColorStages.pop_back_n(m); + fDrawState->fState.fColorStages.pop_back_n(m); - int n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt; + int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; SkASSERT(n >= 0); - fDrawState->fCoverageStages.pop_back_n(n); + fDrawState->fState.fCoverageStages.pop_back_n(n); if (m + n > 0) { fDrawState->invalidateBlendOptFlags(); } @@ -558,8 +564,8 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { } fDrawState = ds; if (NULL != ds) { - fColorEffectCnt = ds->fColorStages.count(); - fCoverageEffectCnt = ds->fCoverageStages.count(); + fColorEffectCnt = ds->numColorStages(); + fCoverageEffectCnt = ds->numCoverageStages(); SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) } } @@ -576,10 +582,10 @@ void GrDrawState::AutoViewMatrixRestore::restore() { int i = 0; for (int s = 0; s < fNumColorStages; ++s, ++i) { - fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]); + fDrawState->fState.fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]); } for (int s = 0; s < numCoverageStages; ++s, ++i) { - fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]); + fDrawState->fState.fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]); } fDrawState = NULL; } @@ -640,13 +646,13 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co fNumColorStages = fDrawState->numColorStages(); for (int s = 0; s < fNumColorStages; ++s, ++i) { - fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]); - fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); + fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]); + fDrawState->fState.fColorStages[s].localCoordChange(coordChangeMatrix); } int numCoverageStages = fDrawState->numCoverageStages(); for (int s = 0; s < numCoverageStages; ++s, ++i) { - fDrawState->fCoverageStages[s].saveCoordChange(&fSavedCoordChanges[i]); - fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); + fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); + fDrawState->fState.fCoverageStages[s].localCoordChange(coordChangeMatrix); } } diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 6ed04eded..6603cc966 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -215,6 +215,40 @@ public: /// @} + /** + * This struct is here so that the GrDrawState can have multiple instances of state information. + * The use of this will come in a future revision when we want to keep track of the original + * draw state as well as an optimized version of it. + */ + struct State { + State() { + this->reset(); + } + + State(const GrEffectStage* colorArray, int colorCount, + const GrEffectStage* coverageArray, int coverageCount) + : fColorStages(colorArray, colorCount), fCoverageStages(coverageArray, coverageCount) { + fSrcBlend = kOne_GrBlendCoeff; + fDstBlend = kZero_GrBlendCoeff; + } + + static bool HaveCompatibleState(const State& a, const State& b, bool explicitLocalCoords); + + void reset() { + fSrcBlend = kOne_GrBlendCoeff; + fDstBlend = kZero_GrBlendCoeff; + fColorStages.reset(); + fCoverageStages.reset(); + } + + GrBlendCoeff fSrcBlend; + GrBlendCoeff fDstBlend; + + typedef SkSTArray<4, GrEffectStage> EffectStageArray; + EffectStageArray fColorStages; + EffectStageArray fCoverageStages; + }; + /////////////////////////////////////////////////////////////////////////// /// @name Effect Stages /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment @@ -237,14 +271,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)); + SkNEW_APPEND_TO_TARRAY(&fState.fColorStages, GrEffectStage, (effect, attr0, attr1)); this->invalidateBlendOptFlags(); 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)); + SkNEW_APPEND_TO_TARRAY(&fState.fCoverageStages, GrEffectStage, (effect, attr0, attr1)); this->invalidateBlendOptFlags(); return effect; } @@ -296,12 +330,12 @@ public: int fCoverageEffectCnt; }; - int numColorStages() const { return fColorStages.count(); } - int numCoverageStages() const { return fCoverageStages.count(); } + int numColorStages() const { return fState.fColorStages.count(); } + int numCoverageStages() const { return fState.fCoverageStages.count(); } int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); } - const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; } - const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; } + const GrEffectStage& getColorStage(int stageIdx) const { return fState.fColorStages[stageIdx]; } + const GrEffectStage& getCoverageStage(int stageIdx) const { return fState.fCoverageStages[stageIdx]; } /** * Checks whether any of the effects will read the dst pixel color. @@ -328,8 +362,8 @@ public: * @param dstCoef coefficient applied to the dst color. */ void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { - fSrcBlend = srcCoeff; - fDstBlend = dstCoeff; + fState.fSrcBlend = srcCoeff; + fState.fDstBlend = dstCoeff; this->invalidateBlendOptFlags(); #ifdef SK_DEBUG if (GrBlendCoeffRefsDst(dstCoeff)) { @@ -341,13 +375,13 @@ public: #endif } - GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; } - GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; } + GrBlendCoeff getSrcBlendCoeff() const { return fState.fSrcBlend; } + GrBlendCoeff getDstBlendCoeff() const { return fState.fDstBlend; } void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, GrBlendCoeff* dstBlendCoeff) const { - *srcBlendCoeff = fSrcBlend; - *dstBlendCoeff = fDstBlend; + *srcBlendCoeff = fState.fSrcBlend; + *dstBlendCoeff = fState.fDstBlend; } /** @@ -767,7 +801,6 @@ public: GrDrawState& operator= (const GrDrawState& that); private: - void onReset(const SkMatrix* initialViewMatrix); BlendOptFlags calcBlendOpts(bool forceCoverage = false, @@ -778,8 +811,6 @@ private: SkAutoTUnref fRenderTarget; GrColor fColor; SkMatrix fViewMatrix; - GrBlendCoeff fSrcBlend; - GrBlendCoeff fDstBlend; GrColor fBlendConstant; uint32_t fFlagBits; const GrVertexAttrib* fVAPtr; @@ -788,9 +819,7 @@ private: GrColor fCoverage; DrawFace fDrawFace; - typedef SkSTArray<4, GrEffectStage> EffectStageArray; - EffectStageArray fColorStages; - EffectStageArray fCoverageStages; + State fState; mutable GrBlendCoeff fOptSrcBlend; mutable GrBlendCoeff fOptDstBlend;