Index: src/gpu/GrDrawState.cpp |
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp |
index 2a81e2619c1efdc1df5fbf85934025f719cf93a0..7c68543479f1a898396fd3487aca9ee2f824ad0b 100644 |
--- a/src/gpu/GrDrawState.cpp |
+++ b/src/gpu/GrDrawState.cpp |
@@ -9,18 +9,17 @@ |
#include "GrPaint.h" |
bool GrDrawState::setIdentityViewMatrix() { |
- SkMatrix invVM; |
- bool inverted = false; |
- for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
- if (this->isStageEnabled(s)) { |
- if (!inverted) { |
- if (!fCommon.fViewMatrix.invert(&invVM)) { |
- // sad trombone sound |
- return false; |
- } |
- inverted = true; |
- } |
- fStages[s].localCoordChange(invVM); |
+ if (fColorStages.count() || fCoverageStages.count()) { |
+ SkMatrix invVM; |
+ if (!fCommon.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 < fCoverageStages.count(); ++s) { |
+ fCoverageStages[s].localCoordChange(invVM); |
} |
} |
fCommon.fViewMatrix.reset(); |
@@ -28,31 +27,23 @@ bool GrDrawState::setIdentityViewMatrix() { |
} |
void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) { |
+ GrAssert(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
+ |
+ fColorStages.reset(); |
+ fCoverageStages.reset(); |
+ |
for (int i = 0; i < GrPaint::kMaxColorStages; ++i) { |
- int s = i + GrPaint::kFirstColorStage; |
if (paint.isColorStageEnabled(i)) { |
- fStages[s] = paint.getColorStage(i); |
- } else { |
- fStages[s].setEffect(NULL); |
+ fColorStages.push_back(paint.getColorStage(i)); |
} |
} |
- this->setFirstCoverageStage(GrPaint::kFirstCoverageStage); |
- |
for (int i = 0; i < GrPaint::kMaxCoverageStages; ++i) { |
- int s = i + GrPaint::kFirstCoverageStage; |
if (paint.isCoverageStageEnabled(i)) { |
- fStages[s] = paint.getCoverageStage(i); |
- } else { |
- fStages[s].setEffect(NULL); |
+ fCoverageStages.push_back(paint.getCoverageStage(i)); |
} |
} |
- // disable all stages not accessible via the paint |
- for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) { |
- this->disableStage(s); |
- } |
- |
this->setRenderTarget(rt); |
fCommon.fViewMatrix = vm; |
@@ -162,33 +153,34 @@ bool GrDrawState::validateVertexAttribs() const { |
for (int i = 0; i < kMaxVertexAttribCnt; ++i) { |
slTypes[i] = static_cast<GrSLType>(-1); |
} |
- for (int s = 0; s < kNumStages; ++s) { |
- if (this->isStageEnabled(s)) { |
- const GrEffectStage& stage = fStages[s]; |
- const GrEffectRef* effect = stage.getEffect(); |
- // 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 >= fCommon.fVACount || |
- kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) { |
- return false; |
- } |
- |
- GrSLType effectSLType = (*effect)->vertexAttribType(i); |
- GrVertexAttribType attribType = fCommon.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; |
+ int totalStages = fColorStages.count() + fCoverageStages.count(); |
+ for (int s = 0; s < totalStages; ++s) { |
+ int covIdx = s - fColorStages.count(); |
+ const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx]; |
+ const GrEffectRef* effect = stage.getEffect(); |
+ GrAssert(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 >= fCommon.fVACount || |
+ kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) { |
+ return false; |
} |
+ |
+ GrSLType effectSLType = (*effect)->vertexAttribType(i); |
+ GrVertexAttribType attribType = fCommon.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; |
} |
} |
@@ -196,9 +188,15 @@ bool GrDrawState::validateVertexAttribs() const { |
} |
bool GrDrawState::willEffectReadDstColor() const { |
- int startStage = this->isColorWriteDisabled() ? this->getFirstCoverageStage() : 0; |
- for (int s = startStage; s < kNumStages; ++s) { |
- if (this->isStageEnabled(s) && (*this->getStage(s).getEffect())->willReadDstColor()) { |
+ if (!this->isColorWriteDisabled()) { |
+ for (int s = 0; s < fColorStages.count(); ++s) { |
+ if ((*fColorStages[s].getEffect())->willReadDstColor()) { |
+ return true; |
+ } |
+ } |
+ } |
+ for (int s = 0; s < fCoverageStages.count(); ++s) { |
+ if ((*fCoverageStages[s].getEffect())->willReadDstColor()) { |
return true; |
} |
} |
@@ -220,12 +218,9 @@ bool GrDrawState::srcAlphaWillBeOne() const { |
} |
// Run through the color stages |
- int stageCnt = getFirstCoverageStage(); |
- for (int s = 0; s < stageCnt; ++s) { |
- const GrEffectRef* effect = this->getStage(s).getEffect(); |
- if (NULL != effect) { |
- (*effect)->getConstantColorComponents(&color, &validComponentFlags); |
- } |
+ for (int s = 0; s < fColorStages.count(); ++s) { |
+ const GrEffectRef* effect = fColorStages[s].getEffect(); |
+ (*effect)->getConstantColorComponents(&color, &validComponentFlags); |
} |
// Check if the color filter could introduce an alpha. |
@@ -247,11 +242,9 @@ bool GrDrawState::srcAlphaWillBeOne() const { |
color |= (SkMulDiv255Round(a, b) << (c * 8)); |
} |
} |
- for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) { |
- const GrEffectRef* effect = this->getStage(s).getEffect(); |
- if (NULL != effect) { |
- (*effect)->getConstantColorComponents(&color, &validComponentFlags); |
- } |
+ for (int s = 0; s < fCoverageStages.count(); ++s) { |
+ const GrEffectRef* effect = fCoverageStages[s].getEffect(); |
+ (*effect)->getConstantColorComponents(&color, &validComponentFlags); |
} |
} |
return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color); |
@@ -274,13 +267,11 @@ bool GrDrawState::hasSolidCoverage() const { |
} |
// Run through the coverage stages and see if the coverage will be all ones at the end. |
- for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) { |
- const GrEffectRef* effect = this->getStage(s).getEffect(); |
- if (NULL != effect) { |
- (*effect)->getConstantColorComponents(&coverage, &validComponentFlags); |
- } |
+ for (int s = 0; s < fCoverageStages.count(); ++s) { |
+ const GrEffectRef* effect = fCoverageStages[s].getEffect(); |
+ (*effect)->getConstantColorComponents(&coverage, &validComponentFlags); |
} |
- return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage); |
+ return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage); |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -349,12 +340,8 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
// check for coverage due to constant coverage, per-vertex coverage, or coverage stage |
bool hasCoverage = forceCoverage || |
0xffffffff != this->getCoverage() || |
- this->hasCoverageVertexAttribute(); |
- for (int s = this->getFirstCoverageStage(); !hasCoverage && s < GrDrawState::kNumStages; ++s) { |
- if (this->isStageEnabled(s)) { |
- hasCoverage = true; |
- } |
- } |
+ this->hasCoverageVertexAttribute() || |
+ fCoverageStages.count() > 0; |
// if we don't have coverage we can check whether the dst |
// has to read at all. If not, we'll disable blending. |
@@ -417,11 +404,18 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
void GrDrawState::AutoViewMatrixRestore::restore() { |
if (NULL != fDrawState) { |
+ GR_DEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
fDrawState->fCommon.fViewMatrix = fViewMatrix; |
- for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
- if (fRestoreMask & (1 << s)) { |
- fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]); |
- } |
+ GrAssert(fDrawState->numColorStages() >= fNumColorStages); |
+ int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; |
+ GrAssert(fDrawState->numCoverageStages() >= numCoverageStages); |
+ |
+ int i = 0; |
+ for (int s = 0; s < fNumColorStages; ++s, ++i) { |
+ fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]); |
+ } |
+ for (int s = 0; s < numCoverageStages; ++s, ++i) { |
+ fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]); |
} |
fDrawState = NULL; |
} |
@@ -431,21 +425,17 @@ void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
const SkMatrix& preconcatMatrix) { |
this->restore(); |
+ GrAssert(NULL == fDrawState); |
if (NULL == drawState || preconcatMatrix.isIdentity()) { |
return; |
} |
fDrawState = drawState; |
- fRestoreMask = 0; |
fViewMatrix = drawState->getViewMatrix(); |
drawState->fCommon.fViewMatrix.preConcat(preconcatMatrix); |
- for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
- if (drawState->isStageEnabled(s)) { |
- fRestoreMask |= (1 << s); |
- drawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]); |
- drawState->fStages[s].localCoordChange(preconcatMatrix); |
- } |
- } |
+ |
+ this->doEffectCoordChanges(preconcatMatrix); |
+ GR_DEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
} |
bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
@@ -460,16 +450,39 @@ bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
} |
fViewMatrix = drawState->getViewMatrix(); |
- fRestoreMask = 0; |
- for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
- if (drawState->isStageEnabled(s)) { |
- fRestoreMask |= (1 << s); |
- drawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]); |
+ if (0 == drawState->numTotalStages()) { |
+ drawState->fCommon.fViewMatrix.reset(); |
+ fDrawState = drawState; |
+ fNumColorStages = 0; |
+ fSavedCoordChanges.reset(0); |
+ GR_DEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
+ return true; |
+ } else { |
+ SkMatrix inv; |
+ if (!fViewMatrix.invert(&inv)) { |
+ return false; |
} |
+ drawState->fCommon.fViewMatrix.reset(); |
+ fDrawState = drawState; |
+ this->doEffectCoordChanges(inv); |
+ GR_DEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
+ return true; |
} |
- if (!drawState->setIdentityViewMatrix()) { |
- return false; |
+} |
+ |
+void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) { |
+ fSavedCoordChanges.reset(fDrawState->numTotalStages()); |
+ int i = 0; |
+ |
+ fNumColorStages = fDrawState->numColorStages(); |
+ for (int s = 0; s < fNumColorStages; ++s, ++i) { |
+ fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]); |
+ fDrawState->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 = drawState; |
- return true; |
} |