Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Unified Diff: src/gpu/GrAAHairLinePathRenderer.cpp

Issue 22486003: Fix hairline pathrenderer for Nexus-10. Switches to passing in an offset and using that to compute … (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Changed to use geometry-based method Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrAAHairLinePathRenderer.cpp
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index c1f951ab7f91832d95ece209f71b377794c68e48..d39090f3225deb43a21f41f6dd6928ce05452245 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -29,14 +29,19 @@ namespace {
static const int kVertsPerQuad = 5;
static const int kIdxsPerQuad = 9;
-static const int kVertsPerLineSeg = 4;
-static const int kIdxsPerLineSeg = 6;
+static const int kVertsPerLineSeg = 6;
+static const int kIdxsPerLineSeg = 12;
static const int kNumQuadsInIdxBuffer = 256;
static const size_t kQuadIdxSBufize = kIdxsPerQuad *
sizeof(uint16_t) *
kNumQuadsInIdxBuffer;
+static const int kNumLineSegsInIdxBuffer = 256;
+static const size_t kLineSegIdxSBufize = kIdxsPerLineSeg *
+ sizeof(uint16_t) *
+ kNumLineSegsInIdxBuffer;
+
bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) {
uint16_t* data = (uint16_t*) qIdxBuffer->lock();
bool tempData = NULL == data;
@@ -78,13 +83,53 @@ bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) {
return true;
}
}
+
+bool push_line_index_data(GrIndexBuffer* qIdxBuffer) {
+ uint16_t* data = (uint16_t*) qIdxBuffer->lock();
+ bool tempData = NULL == data;
+ if (tempData) {
+ data = SkNEW_ARRAY(uint16_t, kNumLineSegsInIdxBuffer * kIdxsPerLineSeg);
+ }
+ for (int i = 0; i < kNumLineSegsInIdxBuffer; ++i) {
+ // Each line segment is rendered as two quads, with alpha = 1 along the
+ // spine of the segment, and alpha = 0 along the outer edges, represented
+ // horizontally like (i.e. the line equation is t*(p1-p0) + p0)
+ //
+ // p4 p5
+ // p0 p1
+ // p2 p3
+ //
+ // Each is drawn as four triangles specified by these 12 indices:
+ int baseIdx = i * kIdxsPerLineSeg;
+ uint16_t baseVert = (uint16_t)(i * kVertsPerLineSeg);
+ data[0 + baseIdx] = baseVert + 0; // p0
+ data[1 + baseIdx] = baseVert + 1; // p1
+ data[2 + baseIdx] = baseVert + 2; // p2
+
+ data[3 + baseIdx] = baseVert + 2; // p2
+ data[4 + baseIdx] = baseVert + 1; // p1
+ data[5 + baseIdx] = baseVert + 3; // p3
+
+ data[6 + baseIdx] = baseVert + 0; // p0
+ data[7 + baseIdx] = baseVert + 5; // p5
+ data[8 + baseIdx] = baseVert + 1; // p1
+
+ data[9 + baseIdx] = baseVert + 0; // p0
+ data[10+ baseIdx] = baseVert + 4; // p4
+ data[11+ baseIdx] = baseVert + 5; // p5
+ }
+ if (tempData) {
+ bool ret = qIdxBuffer->updateData(data, kLineSegIdxSBufize);
+ delete[] data;
+ return ret;
+ } else {
+ qIdxBuffer->unlock();
+ return true;
+ }
+}
}
GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) {
- const GrIndexBuffer* lIdxBuffer = context->getQuadIndexBuffer();
- if (NULL == lIdxBuffer) {
- return NULL;
- }
GrGpu* gpu = context->getGpu();
GrIndexBuffer* qIdxBuf = gpu->createIndexBuffer(kQuadIdxSBufize, false);
SkAutoTUnref<GrIndexBuffer> qIdxBuffer(qIdxBuf);
@@ -92,8 +137,14 @@ GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) {
!push_quad_index_data(qIdxBuf)) {
return NULL;
}
+ GrIndexBuffer* lIdxBuf = gpu->createIndexBuffer(kLineSegIdxSBufize, false);
+ SkAutoTUnref<GrIndexBuffer> lIdxBuffer(lIdxBuf);
+ if (NULL == lIdxBuf ||
+ !push_line_index_data(lIdxBuf)) {
+ return NULL;
+ }
return SkNEW_ARGS(GrAAHairLinePathRenderer,
- (context, lIdxBuffer, qIdxBuf));
+ (context, lIdxBuf, qIdxBuf));
}
GrAAHairLinePathRenderer::GrAAHairLinePathRenderer(
@@ -435,11 +486,7 @@ int generate_lines_and_quads(const SkPath& path,
struct Vertex {
GrPoint fPos;
union {
- struct {
- SkScalar fA;
- SkScalar fB;
- SkScalar fC;
- } fLine;
+ SkScalar fCoverage;
bsalomon 2013/08/07 20:59:57 fLineCoverage? or... struct { SkScalar fCoverage
jvanverth1 2013/08/07 21:15:04 Done.
struct {
SkScalar fK;
SkScalar fL;
@@ -661,17 +708,17 @@ void add_line(const SkPoint p[2],
if (orthVec.setLength(SK_Scalar1)) {
orthVec.setOrthog(orthVec);
- SkScalar lineC = -(a.dot(orthVec));
for (int i = 0; i < kVertsPerLineSeg; ++i) {
- (*vert)[i].fPos = (i < 2) ? a : b;
- if (0 == i || 3 == i) {
+ (*vert)[i].fPos = (i & 0x1) ? b : a;
+ if (i & 0x2) {
+ (*vert)[i].fPos += orthVec;
+ (*vert)[i].fCoverage = 0;
+ } else if (i & 0x4) {
(*vert)[i].fPos -= orthVec;
+ (*vert)[i].fCoverage = 0;
} else {
- (*vert)[i].fPos += orthVec;
+ (*vert)[i].fCoverage= SK_Scalar1;
}
- (*vert)[i].fLine.fA = orthVec.fX;
- (*vert)[i].fLine.fB = orthVec.fY;
- (*vert)[i].fLine.fC = lineC;
}
if (NULL != toSrc) {
toSrc->mapPointsWithStride(&(*vert)->fPos,
@@ -684,6 +731,8 @@ void add_line(const SkPoint p[2],
(*vert)[1].fPos.set(SK_ScalarMax, SK_ScalarMax);
(*vert)[2].fPos.set(SK_ScalarMax, SK_ScalarMax);
(*vert)[3].fPos.set(SK_ScalarMax, SK_ScalarMax);
+ (*vert)[4].fPos.set(SK_ScalarMax, SK_ScalarMax);
+ (*vert)[5].fPos.set(SK_ScalarMax, SK_ScalarMax);
}
*vert += kVertsPerLineSeg;
@@ -936,7 +985,7 @@ GrEffectRef* HairQuadEdgeEffect::TestCreate(SkMWCRandom* random,
/**
* The output of this effect is a 1-pixel wide line.
- * Input is 2D implicit device coord line eq (a*x + b*y +c = 0). 4th component unused.
+ * Input is 2D offset vector from the line. 3rd and 4th components unused.
*/
class HairLineEdgeEffect : public GrEffect {
public:
@@ -978,9 +1027,7 @@ public:
builder->addVarying(kVec4f_GrSLType, "HairLineEdge", &vsName, &fsName);
- builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n",
- builder->fragmentPosition(), fsName);
- builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
+ builder->fsCodeAppendf("\t\tedgeAlpha = %s.x;\n", fsName);
SkString modulate;
GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
@@ -1194,10 +1241,9 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
GrDrawState::AutoRestoreEffects are(drawState);
target->setIndexSourceToBuffer(fLinesIndexBuffer);
int lines = 0;
- int nBufLines = fLinesIndexBuffer->maxQuads();
drawState->addCoverageEffect(hairLineEffect, kEdgeAttrIndex)->unref();
while (lines < lineCnt) {
- int n = GrMin(lineCnt - lines, nBufLines);
+ int n = GrMin(lineCnt - lines, kNumLineSegsInIdxBuffer);
target->drawIndexed(kTriangles_GrPrimitiveType,
kVertsPerLineSeg*lines, // startV
0, // startI
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698