Index: src/gpu/GrOptDrawState.cpp |
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp |
index 19507c07e54ea7ce781a3ec797eed88800911e63..4aa270a6ffdfcf30b68765e0fa1a951875fc9f10 100644 |
--- a/src/gpu/GrOptDrawState.cpp |
+++ b/src/gpu/GrOptDrawState.cpp |
@@ -35,21 +35,48 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, |
drawState.getFixedFunctionVertexAttribIndices(), |
sizeof(fFixedFunctionVertexAttribIndices)); |
- |
fInputColorIsUsed = true; |
fInputCoverageIsUsed = true; |
+ fFirstColorStageIdx = 0; |
+ fFirstCoverageStageIdx = 0; |
+ fFixedFunctionVAToRemove = 0; |
+ |
+ this->computeEffectiveColorStages(drawState); |
+ this->computeEffectiveCoverageStages(drawState); |
+ this->adjustFromBlendOpts(drawState); |
+ this->removeFixedFunctionVertexAttribs(); |
+ this->getStageStats(drawState); |
+ this->setOutputStateInfo(drawState, caps); |
+ |
+ // Copy GeometryProcesssor from DS or ODS |
if (drawState.hasGeometryProcessor()) { |
fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor()))); |
} else { |
fGeometryProcessor.reset(NULL); |
} |
- this->copyEffectiveColorStages(drawState); |
- this->copyEffectiveCoverageStages(drawState); |
- this->adjustFromBlendOpts(); |
- this->getStageStats(); |
- this->setOutputStateInfo(caps); |
+ // Copy Color Stages from DS to ODS |
+ if (fFirstColorStageIdx < drawState.numColorStages()) { |
+ fColorStages.reset(&drawState.getColorStage(fFirstColorStageIdx), |
+ drawState.numColorStages() - fFirstColorStageIdx); |
+ } else { |
+ fColorStages.reset(); |
+ } |
+ |
+ // Copy Coverage Stages from DS to ODS |
+ if (drawState.numCoverageStages() > 0 && fSeparateCoverageFromColor) { |
+ fCoverageStages.reset(&drawState.getCoverageStage(fFirstCoverageStageIdx), |
+ drawState.numCoverageStages() - fFirstCoverageStageIdx); |
+ } else { |
+ fCoverageStages.reset(); |
+ if (drawState.numCoverageStages() > 0) { |
+ // TODO: Once we have flag to know if we only multiply on stages, only push coverage |
+ // into color stages if everything is multipy |
+ fColorStages.push_back_n(drawState.numCoverageStages() - fFirstCoverageStageIdx, |
+ &drawState.getCoverageStage(fFirstCoverageStageIdx)); |
+ } |
+ } |
}; |
GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDrawTargetCaps& caps, |
@@ -88,55 +115,45 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra |
return drawState.fCachedOptState; |
} |
-void GrOptDrawState::setOutputStateInfo(const GrDrawTargetCaps& caps) { |
+void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds, const GrDrawTargetCaps& caps) { |
// Set this default and then possibly change our mind if there is coverage. |
fPrimaryOutputType = kModulate_PrimaryOutputType; |
fSecondaryOutputType = kNone_SecondaryOutputType; |
// If we do have coverage determine whether it matters. |
- bool separateCoverageFromColor = this->hasGeometryProcessor(); |
+ fSeparateCoverageFromColor = this->hasGeometryProcessor(); |
if (!this->isCoverageDrawing() && |
- (this->numCoverageStages() > 0 || |
- this->hasGeometryProcessor() || |
+ (ds.numCoverageStages() - fFirstCoverageStageIdx > 0 || |
+ ds.hasGeometryProcessor() || |
this->hasCoverageVertexAttribute())) { |
if (caps.dualSourceBlendingSupport()) { |
if (kZero_GrBlendCoeff == fDstBlend) { |
// write the coverage value to second color |
fSecondaryOutputType = kCoverage_SecondaryOutputType; |
- separateCoverageFromColor = true; |
+ fSeparateCoverageFromColor = true; |
fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; |
} else if (kSA_GrBlendCoeff == fDstBlend) { |
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. |
fSecondaryOutputType = kCoverageISA_SecondaryOutputType; |
- separateCoverageFromColor = true; |
+ fSeparateCoverageFromColor = true; |
fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; |
} else if (kSC_GrBlendCoeff == fDstBlend) { |
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. |
fSecondaryOutputType = kCoverageISC_SecondaryOutputType; |
- separateCoverageFromColor = true; |
+ fSeparateCoverageFromColor = true; |
fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; |
} |
} else if (fReadsDst && |
kOne_GrBlendCoeff == fSrcBlend && |
kZero_GrBlendCoeff == fDstBlend) { |
fPrimaryOutputType = kCombineWithDst_PrimaryOutputType; |
- separateCoverageFromColor = true; |
- } |
- } |
- |
- // TODO: Once we have flag to know if we only multiply on stages, only push coverage into color |
- // stages if everything is multipy |
- if (!separateCoverageFromColor) { |
- for (int s = 0; s < this->numCoverageStages(); ++s) { |
- fColorStages.push_back(this->getCoverageStage(s)); |
+ fSeparateCoverageFromColor = true; |
} |
- fCoverageStages.reset(); |
} |
} |
-void GrOptDrawState::adjustFromBlendOpts() { |
- |
+void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds) { |
switch (fBlendOptFlags) { |
case kNone_BlendOpt: |
case kSkipDraw_BlendOptFlag: |
@@ -147,31 +164,30 @@ void GrOptDrawState::adjustFromBlendOpts() { |
case kEmitCoverage_BlendOptFlag: |
fColor = 0xffffffff; |
fInputColorIsUsed = true; |
- fColorStages.reset(); |
- this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding); |
+ fFirstColorStageIdx = ds.numColorStages(); |
+ fFixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding; |
break; |
case kEmitTransBlack_BlendOptFlag: |
fColor = 0; |
fCoverage = 0xff; |
fInputColorIsUsed = true; |
fInputCoverageIsUsed = true; |
- fColorStages.reset(); |
- fCoverageStages.reset(); |
- this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding | |
- 0x1 << kCoverage_GrVertexAttribBinding); |
+ fFirstColorStageIdx = ds.numColorStages(); |
+ fFirstCoverageStageIdx = ds.numCoverageStages(); |
+ fFixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding | |
+ 0x1 << kCoverage_GrVertexAttribBinding); |
break; |
default: |
SkFAIL("Unknown BlendOptFlag"); |
- |
} |
} |
-void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) { |
+void GrOptDrawState::removeFixedFunctionVertexAttribs() { |
int numToRemove = 0; |
uint8_t maskCheck = 0x1; |
// Count the number of vertex attributes that we will actually remove |
for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) { |
- if ((maskCheck & removeVAFlag) && -1 != fFixedFunctionVertexAttribIndices[i]) { |
+ if ((maskCheck & fFixedFunctionVAToRemove) && -1 != fFixedFunctionVertexAttribIndices[i]) { |
++numToRemove; |
} |
maskCheck <<= 1; |
@@ -186,7 +202,7 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) { |
const GrVertexAttrib& currAttrib = *src; |
if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) { |
uint8_t maskCheck = 0x1 << currAttrib.fBinding; |
- if (maskCheck & removeVAFlag) { |
+ if (maskCheck & fFixedFunctionVAToRemove) { |
SkASSERT(-1 != fFixedFunctionVertexAttribIndices[currAttrib.fBinding]); |
fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1; |
continue; |
@@ -201,9 +217,7 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) { |
fVAPtr = fOptVA.get(); |
} |
-void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) { |
- int firstColorStage = 0; |
- |
+void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds) { |
// Set up color and flags for ConstantColorComponent checks |
GrProcessor::InvariantOutput inout; |
inout.fIsSingleComponent = false; |
@@ -224,28 +238,20 @@ void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) { |
for (int i = 0; i < ds.numColorStages(); ++i) { |
const GrFragmentProcessor* fp = ds.getColorStage(i).getProcessor(); |
if (!fp->willUseInputColor()) { |
- firstColorStage = i; |
+ fFirstColorStageIdx = i; |
fInputColorIsUsed = false; |
} |
fp->computeInvariantOutput(&inout); |
if (kRGBA_GrColorComponentFlags == inout.fValidFlags) { |
- firstColorStage = i + 1; |
+ fFirstColorStageIdx = i + 1; |
fColor = inout.fColor; |
fInputColorIsUsed = true; |
- this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding); |
+ fFixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding; |
} |
} |
- if (firstColorStage < ds.numColorStages()) { |
- fColorStages.reset(&ds.getColorStage(firstColorStage), |
- ds.numColorStages() - firstColorStage); |
- } else { |
- fColorStages.reset(); |
- } |
} |
-void GrOptDrawState::copyEffectiveCoverageStages(const GrDrawState& ds) { |
- int firstCoverageStage = 0; |
- |
+void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds) { |
// We do not try to optimize out constantColor coverage effects here. It is extremely rare |
// to have a coverage effect that returns a constant value for all four channels. Thus we |
// save having to make extra virtual calls by not checking for it. |
@@ -256,17 +262,11 @@ void GrOptDrawState::copyEffectiveCoverageStages(const GrDrawState& ds) { |
for (int i = 0; i < ds.numCoverageStages(); ++i) { |
const GrProcessor* processor = ds.getCoverageStage(i).getProcessor(); |
if (!processor->willUseInputColor()) { |
- firstCoverageStage = i; |
+ fFirstCoverageStageIdx = i; |
fInputCoverageIsUsed = false; |
} |
} |
#endif |
- if (ds.numCoverageStages() > 0) { |
- fCoverageStages.reset(&ds.getCoverageStage(firstCoverageStage), |
- ds.numCoverageStages() - firstCoverageStage); |
- } else { |
- fCoverageStages.reset(); |
- } |
} |
static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool* readsFragPosition) { |
@@ -278,24 +278,25 @@ static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool* |
} |
} |
-void GrOptDrawState::getStageStats() { |
+void GrOptDrawState::getStageStats(const GrDrawState& ds) { |
// We will need a local coord attrib if there is one currently set on the optState and we are |
// actually generating some effect code |
- fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() && this->numTotalStages() > 0; |
+ fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() && |
+ ds.numTotalStages() - fFirstColorStageIdx - fFirstCoverageStageIdx > 0; |
fReadsDst = false; |
fReadsFragPosition = false; |
- for (int s = 0; s < this->numColorStages(); ++s) { |
- const GrFragmentStage& stage = this->getColorStage(s); |
+ for (int s = fFirstColorStageIdx; s < ds.numColorStages(); ++s) { |
+ const GrFragmentStage& stage = ds.getColorStage(s); |
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition); |
} |
- for (int s = 0; s < this->numCoverageStages(); ++s) { |
- const GrFragmentStage& stage = this->getCoverageStage(s); |
+ for (int s = fFirstCoverageStageIdx; s < ds.numCoverageStages(); ++s) { |
+ const GrFragmentStage& stage = ds.getCoverageStage(s); |
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition); |
} |
- if (this->hasGeometryProcessor()) { |
- const GrGeometryStage& stage = *this->getGeometryProcessor(); |
+ if (ds.hasGeometryProcessor()) { |
+ const GrGeometryStage& stage = *ds.getGeometryProcessor(); |
fReadsFragPosition = fReadsFragPosition || stage.getProcessor()->willReadFragmentPosition(); |
} |
} |