Index: src/gpu/GrDrawState.cpp |
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp |
index de97f68291701451f5560fb07d3f3d7c83a6a197..a6b3d68238cdc18a20f527c9f7a3dccd5b05b8c9 100644 |
--- a/src/gpu/GrDrawState.cpp |
+++ b/src/gpu/GrDrawState.cpp |
@@ -14,51 +14,13 @@ |
GrDrawState::CombinedState GrDrawState::CombineIfPossible( |
const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { |
- bool usingVertexColors = a.hasColorVertexAttribute(); |
- if (!usingVertexColors && a.fColor != b.fColor) { |
+ if (!a.isEqual(b)) { |
return kIncompatible_CombinedState; |
} |
- 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 || |
- memcmp(a.fVAPtr, b.fVAPtr, a.fVACount * sizeof(GrVertexAttrib)) || |
- a.fStencilSettings != b.fStencilSettings || |
- a.fDrawFace != b.fDrawFace) { |
- return kIncompatible_CombinedState; |
- } |
- |
- bool usingVertexCoverage = a.hasCoverageVertexAttribute(); |
- if (!usingVertexCoverage && a.fCoverage != b.fCoverage) { |
- return kIncompatible_CombinedState; |
- } |
- |
- bool explicitLocalCoords = a.hasLocalCoordAttribute(); |
- for (int i = 0; i < a.numColorStages(); i++) { |
- if (!GrEffectStage::AreCompatible(a.getColorStage(i), b.getColorStage(i), |
- explicitLocalCoords)) { |
- return kIncompatible_CombinedState; |
- } |
- } |
- for (int i = 0; i < a.numCoverageStages(); i++) { |
- if (!GrEffectStage::AreCompatible(a.getCoverageStage(i), b.getCoverageStage(i), |
- explicitLocalCoords)) { |
- return kIncompatible_CombinedState; |
- } |
- } |
- |
- SkASSERT(a.fVertexSize == b.fVertexSize); |
- SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices, |
- b.fFixedFunctionVertexAttribIndices, |
- sizeof(a.fFixedFunctionVertexAttribIndices))); |
- |
- if (usingVertexColors) { |
+ // If the general draw states are equal (from check above) we know hasColorVertexAttribute() |
+ // is equivalent for both a and b |
+ if (a.hasColorVertexAttribute()) { |
// If one is opaque and the other is not then the combined state is not opaque. Moreover, |
// if the opaqueness affects the ability to get color/coverage blending correct then we |
// don't combine the draw states. |
@@ -221,7 +183,7 @@ static size_t vertex_size(const GrVertexAttrib* attribs, int count) { |
#ifdef SK_DEBUG |
uint32_t overlapCheck = 0; |
#endif |
- SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt); |
+ SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); |
size_t size = 0; |
for (int index = 0; index < count; ++index) { |
size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType); |
@@ -237,10 +199,6 @@ static size_t vertex_size(const GrVertexAttrib* attribs, int count) { |
return size; |
} |
-size_t GrDrawState::getVertexSize() const { |
- return fVertexSize; |
-} |
- |
//////////////////////////////////////////////////////////////////////////////// |
void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { |
@@ -298,65 +256,6 @@ void GrDrawState::setDefaultVertexAttribs() { |
//////////////////////////////////////////////////////////////////////////////// |
-bool GrDrawState::validateVertexAttribs() const { |
- // check consistency of effects and attributes |
- GrSLType slTypes[kMaxVertexAttribCnt]; |
- for (int i = 0; i < kMaxVertexAttribCnt; ++i) { |
- slTypes[i] = static_cast<GrSLType>(-1); |
- } |
- int totalStages = this->numTotalStages(); |
- for (int s = 0; s < totalStages; ++s) { |
- 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 |
- // type and effect's shader lang type are compatible, and that attributes shared by |
- // multiple effects use the same shader lang type. |
- const int* attributeIndices = stage.getVertexAttribIndices(); |
- int numAttributes = stage.getVertexAttribIndexCount(); |
- for (int i = 0; i < numAttributes; ++i) { |
- int attribIndex = attributeIndices[i]; |
- if (attribIndex >= fVACount || |
- kEffect_GrVertexAttribBinding != fVAPtr[attribIndex].fBinding) { |
- return false; |
- } |
- |
- GrSLType effectSLType = effect->vertexAttribType(i); |
- GrVertexAttribType attribType = fVAPtr[attribIndex].fType; |
- int slVecCount = GrSLTypeVectorCount(effectSLType); |
- int attribVecCount = GrVertexAttribTypeVectorCount(attribType); |
- if (slVecCount != attribVecCount || |
- (static_cast<GrSLType>(-1) != slTypes[attribIndex] && |
- slTypes[attribIndex] != effectSLType)) { |
- return false; |
- } |
- slTypes[attribIndex] = effectSLType; |
- } |
- } |
- |
- return true; |
-} |
- |
-bool GrDrawState::willEffectReadDstColor() const { |
- if (!this->isColorWriteDisabled()) { |
- for (int s = 0; s < this->numColorStages(); ++s) { |
- if (this->getColorStage(s).getEffect()->willReadDstColor()) { |
- return true; |
- } |
- } |
- } |
- for (int s = 0; s < this->numCoverageStages(); ++s) { |
- if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
- |
bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
if (caps.dualSourceBlendingSupport()) { |
return true; |
@@ -366,114 +265,52 @@ bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
// or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
GrBlendCoeff srcCoeff; |
GrBlendCoeff dstCoeff; |
- GrDrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); |
- return GrDrawState::kNone_BlendOpt != flag || |
+ GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); |
+ return GrRODrawState::kNone_BlendOpt != flag || |
(this->willEffectReadDstColor() && |
kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
} |
-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); |
+GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( |
+ GrDrawState* drawState) { |
+ SkASSERT(NULL != drawState); |
+ fDrawState = drawState; |
+ fVAPtr = drawState->fVAPtr; |
+ fVACount = drawState->fVACount; |
+ fDrawState->setDefaultVertexAttribs(); |
} |
-bool GrDrawState::hasSolidCoverage() const { |
- // If we're drawing coverage directly then coverage is effectively treated as color. |
- if (this->isCoverageDrawing()) { |
- return true; |
- } |
+//////////////////////////////////////////////////////////////////////////////s |
- GrColor coverage; |
- uint32_t validComponentFlags; |
- // Initialize to an unknown starting coverage if per-vertex coverage is specified. |
- if (this->hasCoverageVertexAttribute()) { |
- validComponentFlags = 0; |
- } else { |
- coverage = this->getCoverageColor(); |
- validComponentFlags = kRGBA_GrColorComponentFlags; |
- } |
+void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
+ if (NULL != fDrawState) { |
+ int m = fDrawState->numColorStages() - fColorEffectCnt; |
+ SkASSERT(m >= 0); |
+ fDrawState->fColorStages.pop_back_n(m); |
- // Run through the coverage stages and see if the coverage will be all ones at the end. |
- for (int s = 0; s < this->numCoverageStages(); ++s) { |
- const GrEffect* effect = this->getCoverageStage(s).getEffect(); |
- effect->getConstantColorComponents(&coverage, &validComponentFlags); |
+ int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; |
+ SkASSERT(n >= 0); |
+ fDrawState->fCoverageStages.pop_back_n(n); |
+ if (m + n > 0) { |
+ fDrawState->invalidateBlendOptFlags(); |
+ } |
+ SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
+ } |
+ fDrawState = ds; |
+ if (NULL != ds) { |
+ fColorEffectCnt = ds->numColorStages(); |
+ fCoverageEffectCnt = ds->numCoverageStages(); |
+ SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
} |
- return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage); |
} |
//////////////////////////////////////////////////////////////////////////////// |
-// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while |
-// others will blend incorrectly. |
-bool GrDrawState::canTweakAlphaForCoverage() const { |
- /* |
- The fractional coverage is f. |
- The src and dst coeffs are Cs and Cd. |
- The dst and src colors are S and D. |
- We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha |
- we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second |
- term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we |
- find that only 1, ISA, and ISC produce the correct destination when applied to S' and D. |
- 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 || |
- this->isCoverageDrawing(); |
-} |
- |
-GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
- GrBlendCoeff* srcCoeff, |
- GrBlendCoeff* dstCoeff) const { |
+GrRODrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
+ GrBlendCoeff* srcCoeff, |
+ GrBlendCoeff* dstCoeff) const { |
GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; |
if (NULL == srcCoeff) { |
srcCoeff = &bogusSrcCoeff; |
@@ -499,9 +336,9 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
return fBlendOptFlags; |
} |
-GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, |
- GrBlendCoeff* srcCoeff, |
- GrBlendCoeff* dstCoeff) const { |
+GrRODrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, |
+ GrBlendCoeff* srcCoeff, |
+ GrBlendCoeff* dstCoeff) const { |
*srcCoeff = this->getSrcBlendCoeff(); |
*dstCoeff = this->getDstBlendCoeff(); |
@@ -581,49 +418,6 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, |
return kNone_BlendOpt; |
} |
-bool GrDrawState::canIgnoreColorAttribute() const { |
- if (fBlendOptFlags & kInvalid_BlendOptFlag) { |
- this->getBlendOpts(); |
- } |
- return SkToBool(fBlendOptFlags & (GrDrawState::kEmitTransBlack_BlendOptFlag | |
- GrDrawState::kEmitCoverage_BlendOptFlag)); |
-} |
- |
-////////////////////////////////////////////////////////////////////////////// |
- |
-GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( |
- GrDrawState* drawState) { |
- SkASSERT(NULL != drawState); |
- fDrawState = drawState; |
- fVAPtr = drawState->fVAPtr; |
- fVACount = drawState->fVACount; |
- fDrawState->setDefaultVertexAttribs(); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////s |
- |
-void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
- if (NULL != fDrawState) { |
- int m = fDrawState->numColorStages() - fColorEffectCnt; |
- SkASSERT(m >= 0); |
- fDrawState->fColorStages.pop_back_n(m); |
- |
- int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; |
- SkASSERT(n >= 0); |
- fDrawState->fCoverageStages.pop_back_n(n); |
- if (m + n > 0) { |
- fDrawState->invalidateBlendOptFlags(); |
- } |
- SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
- } |
- fDrawState = ds; |
- if (NULL != ds) { |
- fColorEffectCnt = ds->numColorStages(); |
- fCoverageEffectCnt = ds->numCoverageStages(); |
- SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
- } |
-} |
- |
//////////////////////////////////////////////////////////////////////////////// |
void GrDrawState::AutoViewMatrixRestore::restore() { |
@@ -710,3 +504,67 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co |
fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); |
} |
} |
+ |
+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)); |
+} |
+ |