Add per-vertex coverage field, use in AA rects when alpha tweak is not valid, add relevant sample/gm
Review URL: http://codereview.appspot.com/5181044/
git-svn-id: http://skia.googlecode.com/svn/trunk@2440 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 80f0268..3ca4346 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -219,6 +219,10 @@
idx = (int)(random.nextF() * (kNumStages+1));
pdesc.fFirstCoverageStage = idx;
+ pdesc.fVertexLayout |= (random.nextF() > .5f) ?
+ GrDrawTarget::kCoverage_VertexLayoutBit :
+ 0;
+
#if GR_GL_EXPERIMENTAL_GS
pdesc.fExperimentalGS = this->getCaps().fGeometryShaderSupport &&
random.nextF() > .5f;
@@ -238,8 +242,8 @@
}
pdesc.fEdgeAANumEdges = 0;
} else {
- pdesc.fEdgeAANumEdges = SkToS8(1 + random.nextF() *
- this->getMaxEdges());
+ pdesc.fEdgeAANumEdges = static_cast<int>(1 + random.nextF() *
+ this->getMaxEdges());
pdesc.fEdgeAAConcave = random.nextF() > .5f;
}
} else {
@@ -312,6 +316,7 @@
// Enable supported shader-releated caps
fCaps.fShaderSupport = true;
+ fCaps.fSupportPerVertexCoverage = true;
if (kDesktop_GrGLBinding == this->glBinding()) {
fCaps.fDualSourceBlendingSupport =
this->glVersion() >= GR_GL_VER(3,3) ||
@@ -700,6 +705,7 @@
int indexCount) {
int newColorOffset;
+ int newCoverageOffset;
int newTexCoordOffsets[kMaxTexCoords];
int newEdgeOffset;
@@ -707,8 +713,10 @@
this->getGeomSrc().fVertexLayout,
newTexCoordOffsets,
&newColorOffset,
+ &newCoverageOffset,
&newEdgeOffset);
int oldColorOffset;
+ int oldCoverageOffset;
int oldTexCoordOffsets[kMaxTexCoords];
int oldEdgeOffset;
@@ -716,6 +724,7 @@
fHWGeometryState.fVertexLayout,
oldTexCoordOffsets,
&oldColorOffset,
+ &oldCoverageOffset,
&oldEdgeOffset);
bool indexed = NULL != startIndex;
@@ -792,6 +801,23 @@
GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
}
+ if (newCoverageOffset > 0) {
+ // bind just alpha channel.
+ GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset +
+ GrColor_INDEX_A);
+ int idx = GrGLProgram::CoverageAttributeIdx();
+ if (oldCoverageOffset <= 0) {
+ GL_CALL(EnableVertexAttribArray(idx));
+ GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE,
+ true, newStride, coverageOffset));
+ } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) {
+ GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE,
+ true, newStride, coverageOffset));
+ }
+ } else if (oldCoverageOffset > 0) {
+ GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx()));
+ }
+
if (newEdgeOffset > 0) {
GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
int idx = GrGLProgram::EdgeAttributeIdx();
@@ -954,13 +980,30 @@
desc.fExperimentalGS = this->getCaps().fGeometryShaderSupport;
#endif
- // use canonical value when coverage/color distinction won't affect
- // generated code to prevent duplicate programs.
+ // 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 = kNumStages;
desc.fFirstCoverageStage = kNumStages;
- if (fCurrDrawState.fFirstCoverageStage <= lastEnabledStage) {
+ bool hasCoverage = fCurrDrawState.fFirstCoverageStage <= lastEnabledStage;
+ if (hasCoverage) {
+ firstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+ }
+
+ // other coverage inputs
+ if (!hasCoverage) {
+ hasCoverage =
+ desc.fEdgeAANumEdges ||
+ (desc.fVertexLayout & GrDrawTarget::kCoverage_VertexLayoutBit) ||
+ (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit);
+ }
+
+ if (hasCoverage) {
// color filter is applied between color/coverage computation
if (SkXfermode::kDst_Mode != desc.fColorFilterXfermode) {
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+ desc.fFirstCoverageStage = firstCoverageStage;
}
// We could consider cases where the final color is solid (0xff alpha)
@@ -972,17 +1015,17 @@
if (kZero_BlendCoeff == fCurrDrawState.fDstBlend) {
// write the coverage value to second color
desc.fDualSrcOutput = ProgramDesc::kCoverage_DualSrcOutput;
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+ desc.fFirstCoverageStage = firstCoverageStage;
} else if (kSA_BlendCoeff == fCurrDrawState.fDstBlend) {
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
// cover
desc.fDualSrcOutput = ProgramDesc::kCoverageISA_DualSrcOutput;
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+ desc.fFirstCoverageStage = firstCoverageStage;
} else if (kSC_BlendCoeff == fCurrDrawState.fDstBlend) {
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
// cover
desc.fDualSrcOutput = ProgramDesc::kCoverageISC_DualSrcOutput;
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+ desc.fFirstCoverageStage = firstCoverageStage;
}
}
}