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
This commit is contained in:
bsalomon@google.com 2013-03-26 16:42:17 +00:00
parent 4647f90598
commit e9144c64a6
2 changed files with 26 additions and 23 deletions

View File

@ -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();
// 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;
}
}
// other coverage inputs
if (!hasCoverage) {
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());

View File

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