diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-26 16:42:17 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-26 16:42:17 +0000 |
commit | e9144c64a6e75795b591d2adc28f627d7c3fb8f7 (patch) | |
tree | 67d7c01a4a64f10b49abf33bf8b643235cc9f960 | |
parent | 4647f9059825c062169d4d454c12640d82ae16c0 (diff) |
Program key coverage/discard fixes.
Review URL: https://codereview.chromium.org/13095004
git-svn-id: http://skia.googlecode.com/svn/trunk@8393 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 45 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 4 |
2 files changed, 26 insertions, 23 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index fc80a78939..1c8f884afc 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -117,13 +117,6 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState, int lastEnabledStage = -1; - if (!skipCoverage) { - desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite(); - } else { - // Use canonical values when edge-aa is not enabled to avoid program cache misses. - desc->fDiscardIfOutsideEdge = false; - } - for (int s = 0; s < GrDrawState::kNumStages; ++s) { bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCoverage; @@ -152,26 +145,36 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState, #endif #endif - // We want to avoid generating programs with different "first cov stage" values when they would - // compute the same result. We set field in the desc to kNumStages when either there are no - // coverage stages or the distinction between coverage and color is immaterial. - int firstCoverageStage = GrDrawState::kNumStages; + // We leave this set to kNumStages until we discover that the coverage/color distinction is + // material to the generated program. We do this to avoid distinct keys that generate equivalent + // programs. desc->fFirstCoverageStage = GrDrawState::kNumStages; - bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage; - if (hasCoverage) { - firstCoverageStage = drawState.getFirstCoverageStage(); - } - - // other coverage inputs - if (!hasCoverage) { - hasCoverage = requiresAttributeCoverage; + // This tracks the actual first coverage stage. + int firstCoverageStage = GrDrawState::kNumStages; + desc->fDiscardIfZeroCoverage = false; // Enabled below if stenciling and there is coverage. + bool hasCoverage = false; + // If we're rendering coverage-as-color then its as though there are no coverage stages. + if (!drawState.isCoverageDrawing()) { + // We can have coverage either through a stage or coverage vertex attributes. + if (drawState.getFirstCoverageStage() <= lastEnabledStage) { + firstCoverageStage = drawState.getFirstCoverageStage(); + hasCoverage = true; + } else { + hasCoverage = requiresAttributeCoverage; + } } - + if (hasCoverage) { // color filter is applied between color/coverage computation if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) { desc->fFirstCoverageStage = firstCoverageStage; } + + // If we're stenciling then we want to discard samples that have zero coverage + if (drawState.getStencil().doesWrite()) { + desc->fDiscardIfZeroCoverage = true; + desc->fFirstCoverageStage = firstCoverageStage; + } if (gpu->caps()->dualSourceBlendingSupport() && !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | @@ -797,7 +800,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { } // discard if coverage is zero - if (fDesc.fDiscardIfOutsideEdge && !outCoverage.isEmpty()) { + if (fDesc.fDiscardIfZeroCoverage && !outCoverage.isEmpty()) { builder.fsCodeAppendf( "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n", outCoverage.c_str()); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index a6ece6ccbf..2dea59efd8 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -165,8 +165,8 @@ public: kDualSrcOutputCnt }; - // should the FS discard if the edge-aa coverage is zero (to avoid stencil manipulation) - bool fDiscardIfOutsideEdge; + // should the FS discard if the coverage is zero (to avoid stencil manipulation) + bool fDiscardIfZeroCoverage; // stripped of bits that don't affect program generation GrAttribBindings fAttribBindings; |