diff options
Diffstat (limited to 'src/gpu/GrDrawState.cpp')
-rw-r--r-- | src/gpu/GrDrawState.cpp | 213 |
1 files changed, 113 insertions, 100 deletions
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 2a81e2619c..7c68543479 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; } |