Add GrAAHairLinePathRenderer
Review URL: http://codereview.appspot.com/4926045
git-svn-id: http://skia.googlecode.com/svn/trunk@2196 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 05b1e88..a9a3953 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -185,11 +185,24 @@
pdesc.fFirstCoverageStage = idx;
bool edgeAA = random.nextF() > .5f;
- if (edgeAA) {
- pdesc.fEdgeAANumEdges = random.nextF() * this->getMaxEdges() + 1;
- pdesc.fEdgeAAConcave = random.nextF() > .5f;
- } else {
- pdesc.fEdgeAANumEdges = 0;
+ if (edgeAA) {
+ bool vertexEdgeAA = random.nextF() > .5f;
+ if (vertexEdgeAA) {
+ pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit;
+ if (this->supportsShaderDerivatives()) {
+ pdesc.fVertexEdgeType = random.nextF() > 0.5f ?
+ kHairQuad_EdgeType :
+ kHairLine_EdgeType;
+ } else {
+ pdesc.fVertexEdgeType = kHairLine_EdgeType;
+ }
+ pdesc.fEdgeAANumEdges = 0;
+ } else {
+ pdesc.fEdgeAANumEdges = random.nextF() * this->getMaxEdges() + 1;
+ pdesc.fEdgeAAConcave = random.nextF() > .5f;
+ }
+ } else {
+ pdesc.fEdgeAANumEdges = 0;
}
if (fDualSourceBlendingSupport) {
@@ -307,6 +320,7 @@
fHWGeometryState.fVertexLayout = 0;
fHWGeometryState.fVertexOffset = ~0;
GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
+ GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
for (int t = 0; t < kMaxTexCoords; ++t) {
GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
}
@@ -641,17 +655,22 @@
int newColorOffset;
int newTexCoordOffsets[kMaxTexCoords];
+ int newEdgeOffset;
GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
this->getGeomSrc().fVertexLayout,
newTexCoordOffsets,
- &newColorOffset);
+ &newColorOffset,
+ &newEdgeOffset);
int oldColorOffset;
int oldTexCoordOffsets[kMaxTexCoords];
+ int oldEdgeOffset;
+
GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
fHWGeometryState.fVertexLayout,
oldTexCoordOffsets,
- &oldColorOffset);
+ &oldColorOffset,
+ &oldEdgeOffset);
bool indexed = NULL != startIndex;
int extraVertexOffset;
@@ -727,6 +746,21 @@
GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
}
+ if (newEdgeOffset > 0) {
+ GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
+ int idx = GrGLProgram::EdgeAttributeIdx();
+ if (oldEdgeOffset <= 0) {
+ GL_CALL(EnableVertexAttribArray(idx));
+ GL_CALL(VertexAttribPointer(idx, 4, scalarType,
+ false, newStride, edgeOffset));
+ } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) {
+ GL_CALL(VertexAttribPointer(idx, 4, scalarType,
+ false, newStride, edgeOffset));
+ }
+ } else if (oldEdgeOffset > 0) {
+ GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
+ }
+
fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
fHWGeometryState.fArrayPtrsDirty = false;
}
@@ -734,6 +768,11 @@
void GrGpuGLShaders::buildProgram(GrPrimitiveType type) {
ProgramDesc& desc = fCurrentProgram.fProgramDesc;
+ // The descriptor is used as a cache key. Thus when a field of the
+ // descriptor will not affect program generation (because of the vertex
+ // layout in use or other descriptor field settings) it should be set
+ // to a canonical value to avoid duplicate programs with different keys.
+
// Must initialize all fields or cache will have false negatives!
desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
@@ -767,6 +806,13 @@
int lastEnabledStage = -1;
+ if (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit) {
+ desc.fVertexEdgeType = fCurrDrawState.fVertexEdgeType;
+ } else {
+ // use canonical value when not set to avoid cache misses
+ desc.fVertexEdgeType = GrDrawTarget::kHairLine_EdgeType;
+ }
+
for (int s = 0; s < kNumStages; ++s) {
StageDesc& stage = desc.fStages[s];