| Index: src/gpu/gl/GrGLProgramDesc.cpp
|
| diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
|
| index f9728ff556fbc5d21b6ad0fb0bf11b9f4a3636dd..d95874252e5cbef0f00cd73feddbe0a62e14516c 100644
|
| --- a/src/gpu/gl/GrGLProgramDesc.cpp
|
| +++ b/src/gpu/gl/GrGLProgramDesc.cpp
|
| @@ -56,6 +56,27 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|
|
| bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag |
|
| GrDrawState::kEmitCoverage_BlendOptFlag));
|
| + int firstEffectiveColorStage = 0;
|
| + bool inputColorIsUsed = true;
|
| + if (!skipColor) {
|
| + firstEffectiveColorStage = drawState.numColorStages();
|
| + while (firstEffectiveColorStage > 0 && inputColorIsUsed) {
|
| + --firstEffectiveColorStage;
|
| + const GrEffect* effect = drawState.getColorStage(firstEffectiveColorStage).getEffect()->get();
|
| + inputColorIsUsed = effect->willUseInputColor();
|
| + }
|
| + }
|
| +
|
| + int firstEffectiveCoverageStage = 0;
|
| + bool inputCoverageIsUsed = true;
|
| + if (!skipCoverage) {
|
| + firstEffectiveCoverageStage = drawState.numCoverageStages();
|
| + while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) {
|
| + --firstEffectiveCoverageStage;
|
| + const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCoverageStage).getEffect()->get();
|
| + inputCoverageIsUsed = effect->willUseInputColor();
|
| + }
|
| + }
|
|
|
| // The descriptor is used as a cache key. Thus when a field of the
|
| // descriptor will not affect program generation (because of the attribute
|
| @@ -70,10 +91,11 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|
|
| bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
|
| bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
|
| - (!requiresColorAttrib && 0xffffffff == drawState.getColor());
|
| + (!requiresColorAttrib && 0xffffffff == drawState.getColor()) ||
|
| + (!inputColorIsUsed);
|
|
|
| - int numEffects = (skipColor ? 0 : drawState.numColorStages()) +
|
| - (skipCoverage ? 0 : drawState.numCoverageStages());
|
| + int numEffects = (skipColor ? 0 : (drawState.numColorStages() - firstEffectiveColorStage)) +
|
| + (skipCoverage ? 0 : (drawState.numCoverageStages() - firstEffectiveCoverageStage));
|
|
|
| size_t newKeyLength = KeyLength(numEffects);
|
| bool allocChanged;
|
| @@ -93,7 +115,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| bool readFragPosition = false;
|
| bool hasVertexCode = false;
|
| if (!skipColor) {
|
| - for (int s = 0; s < drawState.numColorStages(); ++s) {
|
| + for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
|
| effectKeys[currEffectKey++] =
|
| get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps(),
|
| requiresLocalCoordAttrib, &readsDst, &readFragPosition,
|
| @@ -101,7 +123,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| }
|
| }
|
| if (!skipCoverage) {
|
| - for (int s = 0; s < drawState.numCoverageStages(); ++s) {
|
| + for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
|
| effectKeys[currEffectKey++] =
|
| get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glCaps(),
|
| requiresLocalCoordAttrib, &readsDst, &readFragPosition,
|
| @@ -111,7 +133,6 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|
|
| header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib;
|
| header->fEmitsPointSize = isPoints;
|
| - header->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState.getColorFilterMode();
|
|
|
| // Currently the experimental GS will only work with triangle prims (and it doesn't do anything
|
| // other than pass through values from the VS to the FS anyway).
|
| @@ -139,7 +160,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|
|
| if (skipCoverage) {
|
| header->fCoverageInput = kTransBlack_ColorInput;
|
| - } else if (covIsSolidWhite) {
|
| + } else if (covIsSolidWhite || !inputCoverageIsUsed) {
|
| header->fCoverageInput = kSolidWhite_ColorInput;
|
| } else if (defaultToUniformInputs && !requiresCoverageAttrib) {
|
| header->fCoverageInput = kUniform_ColorInput;
|
| @@ -202,10 +223,6 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| bool separateCoverageFromColor = false;
|
| if (!drawState.isCoverageDrawing() && !skipCoverage &&
|
| (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) {
|
| - // color filter is applied between color/coverage computation
|
| - if (SkXfermode::kDst_Mode != header->fColorFilterXfermode) {
|
| - separateCoverageFromColor = true;
|
| - }
|
|
|
| // If we're stenciling then we want to discard samples that have zero coverage
|
| if (drawState.getStencil().doesWrite()) {
|
| @@ -237,24 +254,23 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| }
|
| }
|
| if (!skipColor) {
|
| - for (int s = 0; s < drawState.numColorStages(); ++s) {
|
| + for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
|
| colorStages->push_back(&drawState.getColorStage(s));
|
| }
|
| - header->fColorEffectCnt = drawState.numColorStages();
|
| }
|
| if (!skipCoverage) {
|
| SkTArray<const GrEffectStage*, true>* array;
|
| if (separateCoverageFromColor) {
|
| array = coverageStages;
|
| - header->fCoverageEffectCnt = drawState.numCoverageStages();
|
| } else {
|
| array = colorStages;
|
| - header->fColorEffectCnt += drawState.numCoverageStages();
|
| }
|
| - for (int s = 0; s < drawState.numCoverageStages(); ++s) {
|
| + for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
|
| array->push_back(&drawState.getCoverageStage(s));
|
| }
|
| }
|
| + header->fColorEffectCnt = colorStages->count();
|
| + header->fCoverageEffectCnt = coverageStages->count();
|
|
|
| *desc->checksum() = 0;
|
| *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fKey.get()),
|
|
|