| Index: src/gpu/GrOptDrawState.cpp
|
| diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
|
| index 19507c07e54ea7ce781a3ec797eed88800911e63..4a6cd142eb08ee49756564eb294f5bb7f9af64bb 100644
|
| --- a/src/gpu/GrOptDrawState.cpp
|
| +++ b/src/gpu/GrOptDrawState.cpp
|
| @@ -35,21 +35,52 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
| drawState.getFixedFunctionVertexAttribIndices(),
|
| sizeof(fFixedFunctionVertexAttribIndices));
|
|
|
| -
|
| fInputColorIsUsed = true;
|
| fInputCoverageIsUsed = true;
|
|
|
| + int firstColorStageIdx = 0;
|
| + int firstCoverageStageIdx = 0;
|
| + bool separateCoverageFromColor;
|
| +
|
| + uint8_t fixedFunctionVAToRemove = 0;
|
| +
|
| + this->computeEffectiveColorStages(drawState, &firstColorStageIdx, &fixedFunctionVAToRemove);
|
| + this->computeEffectiveCoverageStages(drawState, &firstCoverageStageIdx);
|
| + this->adjustFromBlendOpts(drawState, &firstColorStageIdx, &firstCoverageStageIdx,
|
| + &fixedFunctionVAToRemove);
|
| + // Should not be setting any more FFVA to be removed at this point
|
| + this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove);
|
| + this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx);
|
| + this->setOutputStateInfo(drawState, caps, firstCoverageStageIdx, &separateCoverageFromColor);
|
| +
|
| + // 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 (firstColorStageIdx < drawState.numColorStages()) {
|
| + fColorStages.reset(&drawState.getColorStage(firstColorStageIdx),
|
| + drawState.numColorStages() - firstColorStageIdx);
|
| + } else {
|
| + fColorStages.reset();
|
| + }
|
| +
|
| + // Copy Coverage Stages from DS to ODS
|
| + if (drawState.numCoverageStages() > 0 && separateCoverageFromColor) {
|
| + fCoverageStages.reset(&drawState.getCoverageStage(firstCoverageStageIdx),
|
| + drawState.numCoverageStages() - firstCoverageStageIdx);
|
| + } 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 multiply
|
| + fColorStages.push_back_n(drawState.numCoverageStages() - firstCoverageStageIdx,
|
| + &drawState.getCoverageStage(firstCoverageStageIdx));
|
| + }
|
| + }
|
| };
|
|
|
| GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDrawTargetCaps& caps,
|
| @@ -88,55 +119,51 @@ 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,
|
| + int firstCoverageStageIdx,
|
| + bool* separateCoverageFromColor) {
|
| // 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();
|
| + *separateCoverageFromColor = this->hasGeometryProcessor();
|
| if (!this->isCoverageDrawing() &&
|
| - (this->numCoverageStages() > 0 ||
|
| - this->hasGeometryProcessor() ||
|
| + (ds.numCoverageStages() - firstCoverageStageIdx > 0 ||
|
| + ds.hasGeometryProcessor() ||
|
| this->hasCoverageVertexAttribute())) {
|
|
|
| if (caps.dualSourceBlendingSupport()) {
|
| if (kZero_GrBlendCoeff == fDstBlend) {
|
| // write the coverage value to second color
|
| fSecondaryOutputType = kCoverage_SecondaryOutputType;
|
| - separateCoverageFromColor = true;
|
| + *separateCoverageFromColor = 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;
|
| + *separateCoverageFromColor = 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;
|
| + *separateCoverageFromColor = true;
|
| fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
|
| }
|
| } else if (fReadsDst &&
|
| kOne_GrBlendCoeff == fSrcBlend &&
|
| kZero_GrBlendCoeff == fDstBlend) {
|
| fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
|
| - separateCoverageFromColor = true;
|
| + *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));
|
| - }
|
| - fCoverageStages.reset();
|
| - }
|
| }
|
|
|
| -void GrOptDrawState::adjustFromBlendOpts() {
|
| -
|
| +void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
|
| + int* firstColorStageIdx,
|
| + int* firstCoverageStageIdx,
|
| + uint8_t* fixedFunctionVAToRemove) {
|
| switch (fBlendOptFlags) {
|
| case kNone_BlendOpt:
|
| case kSkipDraw_BlendOptFlag:
|
| @@ -147,22 +174,21 @@ void GrOptDrawState::adjustFromBlendOpts() {
|
| case kEmitCoverage_BlendOptFlag:
|
| fColor = 0xffffffff;
|
| fInputColorIsUsed = true;
|
| - fColorStages.reset();
|
| - this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
|
| + *firstColorStageIdx = ds.numColorStages();
|
| + *fixedFunctionVAToRemove |= 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);
|
| + *firstColorStageIdx = ds.numColorStages();
|
| + *firstCoverageStageIdx = ds.numCoverageStages();
|
| + *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding |
|
| + 0x1 << kCoverage_GrVertexAttribBinding);
|
| break;
|
| default:
|
| SkFAIL("Unknown BlendOptFlag");
|
| -
|
| }
|
| }
|
|
|
| @@ -201,9 +227,8 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
| fVAPtr = fOptVA.get();
|
| }
|
|
|
| -void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) {
|
| - int firstColorStage = 0;
|
| -
|
| +void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* firstColorStageIdx,
|
| + uint8_t* fixedFunctionVAToRemove) {
|
| // Set up color and flags for ConstantColorComponent checks
|
| GrProcessor::InvariantOutput inout;
|
| inout.fIsSingleComponent = false;
|
| @@ -224,28 +249,21 @@ 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;
|
| + *firstColorStageIdx = i;
|
| fInputColorIsUsed = false;
|
| }
|
| fp->computeInvariantOutput(&inout);
|
| if (kRGBA_GrColorComponentFlags == inout.fValidFlags) {
|
| - firstColorStage = i + 1;
|
| + *firstColorStageIdx = i + 1;
|
| fColor = inout.fColor;
|
| fInputColorIsUsed = true;
|
| - this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
|
| + *fixedFunctionVAToRemove |= 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,
|
| + int* firstCoverageStageIdx) {
|
| // 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 +274,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;
|
| + *firstCoverageStageIdx = 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 +290,26 @@ static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool*
|
| }
|
| }
|
|
|
| -void GrOptDrawState::getStageStats() {
|
| +void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx,
|
| + int firstCoverageStageIdx) {
|
| // 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() - firstColorStageIdx - firstCoverageStageIdx > 0;
|
|
|
| fReadsDst = false;
|
| fReadsFragPosition = false;
|
|
|
| - for (int s = 0; s < this->numColorStages(); ++s) {
|
| - const GrFragmentStage& stage = this->getColorStage(s);
|
| + for (int s = firstColorStageIdx; 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 = firstCoverageStageIdx; 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();
|
| }
|
| }
|
|
|