| 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;
|
| }
|
|
|