| Index: src/gpu/GrAAConvexPathRenderer.cpp
|
| diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
|
| index a0e72e5e6e676fcfd1860fbaeb77f99f41a94e6b..fc6cae68c62298fc26430154ae6c9090f47f2bf7 100644
|
| --- a/src/gpu/GrAAConvexPathRenderer.cpp
|
| +++ b/src/gpu/GrAAConvexPathRenderer.cpp
|
| @@ -128,7 +128,7 @@ void compute_vectors(SegmentArray* segments,
|
| *iCount = 0;
|
| // compute normals at all points
|
| for (int a = 0; a < count; ++a) {
|
| - const Segment& sega = (*segments)[a];
|
| + Segment& sega = (*segments)[a];
|
| int b = (a + 1) % count;
|
| Segment& segb = (*segments)[b];
|
|
|
| @@ -304,12 +304,23 @@ struct QuadVertex {
|
| SkScalar fD1;
|
| };
|
|
|
| +struct Draw {
|
| + Draw() : fVertexCnt(0), fIndexCnt(0) {}
|
| + int fVertexCnt;
|
| + int fIndexCnt;
|
| +};
|
| +
|
| +typedef SkTArray<Draw, true> DrawArray;
|
| +
|
| void create_vertices(const SegmentArray& segments,
|
| const SkPoint& fanPt,
|
| + DrawArray* draws,
|
| QuadVertex* verts,
|
| uint16_t* idxs) {
|
| - int v = 0;
|
| - int i = 0;
|
| + Draw* draw = &draws->push_back();
|
| + // alias just to make vert/index assignments easier to read.
|
| + int* v = &draw->fVertexCnt;
|
| + int* i = &draw->fIndexCnt;
|
|
|
| int count = segments.count();
|
| for (int a = 0; a < count; ++a) {
|
| @@ -317,117 +328,133 @@ void create_vertices(const SegmentArray& segments,
|
| int b = (a + 1) % count;
|
| const Segment& segb = segments[b];
|
|
|
| + // Check whether adding the verts for this segment to the current draw would cause index
|
| + // values to overflow.
|
| + int vCount = 4;
|
| + if (Segment::kLine == segb.fType) {
|
| + vCount += 5;
|
| + } else {
|
| + vCount += 6;
|
| + }
|
| + if (draw->fVertexCnt + vCount > (1 << 16)) {
|
| + verts += *v;
|
| + idxs += *i;
|
| + draw = &draws->push_back();
|
| + v = &draw->fVertexCnt;
|
| + i = &draw->fIndexCnt;
|
| + }
|
| +
|
| // FIXME: These tris are inset in the 1 unit arc around the corner
|
| - verts[v + 0].fPos = sega.endPt();
|
| - verts[v + 1].fPos = verts[v + 0].fPos + sega.endNorm();
|
| - verts[v + 2].fPos = verts[v + 0].fPos + segb.fMid;
|
| - verts[v + 3].fPos = verts[v + 0].fPos + segb.fNorms[0];
|
| - verts[v + 0].fUV.set(0,0);
|
| - verts[v + 1].fUV.set(0,-SK_Scalar1);
|
| - verts[v + 2].fUV.set(0,-SK_Scalar1);
|
| - verts[v + 3].fUV.set(0,-SK_Scalar1);
|
| - verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1;
|
| - verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1;
|
| - verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1;
|
| - verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1;
|
| -
|
| - idxs[i + 0] = v + 0;
|
| - idxs[i + 1] = v + 2;
|
| - idxs[i + 2] = v + 1;
|
| - idxs[i + 3] = v + 0;
|
| - idxs[i + 4] = v + 3;
|
| - idxs[i + 5] = v + 2;
|
| -
|
| - v += 4;
|
| - i += 6;
|
| + verts[*v + 0].fPos = sega.endPt();
|
| + verts[*v + 1].fPos = verts[*v + 0].fPos + sega.endNorm();
|
| + verts[*v + 2].fPos = verts[*v + 0].fPos + segb.fMid;
|
| + verts[*v + 3].fPos = verts[*v + 0].fPos + segb.fNorms[0];
|
| + verts[*v + 0].fUV.set(0,0);
|
| + verts[*v + 1].fUV.set(0,-SK_Scalar1);
|
| + verts[*v + 2].fUV.set(0,-SK_Scalar1);
|
| + verts[*v + 3].fUV.set(0,-SK_Scalar1);
|
| + verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1;
|
| + verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1;
|
| + verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1;
|
| + verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1;
|
| +
|
| + idxs[*i + 0] = *v + 0;
|
| + idxs[*i + 1] = *v + 2;
|
| + idxs[*i + 2] = *v + 1;
|
| + idxs[*i + 3] = *v + 0;
|
| + idxs[*i + 4] = *v + 3;
|
| + idxs[*i + 5] = *v + 2;
|
| +
|
| + *v += 4;
|
| + *i += 6;
|
|
|
| if (Segment::kLine == segb.fType) {
|
| - verts[v + 0].fPos = fanPt;
|
| - verts[v + 1].fPos = sega.endPt();
|
| - verts[v + 2].fPos = segb.fPts[0];
|
| + verts[*v + 0].fPos = fanPt;
|
| + verts[*v + 1].fPos = sega.endPt();
|
| + verts[*v + 2].fPos = segb.fPts[0];
|
|
|
| - verts[v + 3].fPos = verts[v + 1].fPos + segb.fNorms[0];
|
| - verts[v + 4].fPos = verts[v + 2].fPos + segb.fNorms[0];
|
| + verts[*v + 3].fPos = verts[*v + 1].fPos + segb.fNorms[0];
|
| + verts[*v + 4].fPos = verts[*v + 2].fPos + segb.fNorms[0];
|
|
|
| // we draw the line edge as a degenerate quad (u is 0, v is the
|
| // signed distance to the edge)
|
| - SkScalar dist = fanPt.distanceToLineBetween(verts[v + 1].fPos,
|
| - verts[v + 2].fPos);
|
| - verts[v + 0].fUV.set(0, dist);
|
| - verts[v + 1].fUV.set(0, 0);
|
| - verts[v + 2].fUV.set(0, 0);
|
| - verts[v + 3].fUV.set(0, -SK_Scalar1);
|
| - verts[v + 4].fUV.set(0, -SK_Scalar1);
|
| -
|
| - verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1;
|
| - verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1;
|
| - verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1;
|
| - verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1;
|
| - verts[v + 4].fD0 = verts[v + 4].fD1 = -SK_Scalar1;
|
| -
|
| - idxs[i + 0] = v + 0;
|
| - idxs[i + 1] = v + 2;
|
| - idxs[i + 2] = v + 1;
|
| -
|
| - idxs[i + 3] = v + 3;
|
| - idxs[i + 4] = v + 1;
|
| - idxs[i + 5] = v + 2;
|
| -
|
| - idxs[i + 6] = v + 4;
|
| - idxs[i + 7] = v + 3;
|
| - idxs[i + 8] = v + 2;
|
| -
|
| - v += 5;
|
| - i += 9;
|
| + SkScalar dist = fanPt.distanceToLineBetween(verts[*v + 1].fPos,
|
| + verts[*v + 2].fPos);
|
| + verts[*v + 0].fUV.set(0, dist);
|
| + verts[*v + 1].fUV.set(0, 0);
|
| + verts[*v + 2].fUV.set(0, 0);
|
| + verts[*v + 3].fUV.set(0, -SK_Scalar1);
|
| + verts[*v + 4].fUV.set(0, -SK_Scalar1);
|
| +
|
| + verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1;
|
| + verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1;
|
| + verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1;
|
| + verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1;
|
| + verts[*v + 4].fD0 = verts[*v + 4].fD1 = -SK_Scalar1;
|
| +
|
| + idxs[*i + 0] = *v + 0;
|
| + idxs[*i + 1] = *v + 2;
|
| + idxs[*i + 2] = *v + 1;
|
| +
|
| + idxs[*i + 3] = *v + 3;
|
| + idxs[*i + 4] = *v + 1;
|
| + idxs[*i + 5] = *v + 2;
|
| +
|
| + idxs[*i + 6] = *v + 4;
|
| + idxs[*i + 7] = *v + 3;
|
| + idxs[*i + 8] = *v + 2;
|
| +
|
| + *v += 5;
|
| + *i += 9;
|
| } else {
|
| GrPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]};
|
|
|
| GrVec midVec = segb.fNorms[0] + segb.fNorms[1];
|
| midVec.normalize();
|
|
|
| - verts[v + 0].fPos = fanPt;
|
| - verts[v + 1].fPos = qpts[0];
|
| - verts[v + 2].fPos = qpts[2];
|
| - verts[v + 3].fPos = qpts[0] + segb.fNorms[0];
|
| - verts[v + 4].fPos = qpts[2] + segb.fNorms[1];
|
| - verts[v + 5].fPos = qpts[1] + midVec;
|
| + verts[*v + 0].fPos = fanPt;
|
| + verts[*v + 1].fPos = qpts[0];
|
| + verts[*v + 2].fPos = qpts[2];
|
| + verts[*v + 3].fPos = qpts[0] + segb.fNorms[0];
|
| + verts[*v + 4].fPos = qpts[2] + segb.fNorms[1];
|
| + verts[*v + 5].fPos = qpts[1] + midVec;
|
|
|
| SkScalar c = segb.fNorms[0].dot(qpts[0]);
|
| - verts[v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c;
|
| - verts[v + 1].fD0 = 0.f;
|
| - verts[v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c;
|
| - verts[v + 3].fD0 = -SK_ScalarMax/100;
|
| - verts[v + 4].fD0 = -SK_ScalarMax/100;
|
| - verts[v + 5].fD0 = -SK_ScalarMax/100;
|
| + verts[*v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c;
|
| + verts[*v + 1].fD0 = 0.f;
|
| + verts[*v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c;
|
| + verts[*v + 3].fD0 = -SK_ScalarMax/100;
|
| + verts[*v + 4].fD0 = -SK_ScalarMax/100;
|
| + verts[*v + 5].fD0 = -SK_ScalarMax/100;
|
|
|
| c = segb.fNorms[1].dot(qpts[2]);
|
| - verts[v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c;
|
| - verts[v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c;
|
| - verts[v + 2].fD1 = 0.f;
|
| - verts[v + 3].fD1 = -SK_ScalarMax/100;
|
| - verts[v + 4].fD1 = -SK_ScalarMax/100;
|
| - verts[v + 5].fD1 = -SK_ScalarMax/100;
|
| + verts[*v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c;
|
| + verts[*v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c;
|
| + verts[*v + 2].fD1 = 0.f;
|
| + verts[*v + 3].fD1 = -SK_ScalarMax/100;
|
| + verts[*v + 4].fD1 = -SK_ScalarMax/100;
|
| + verts[*v + 5].fD1 = -SK_ScalarMax/100;
|
|
|
| GrPathUtils::QuadUVMatrix toUV(qpts);
|
| - toUV.apply<6, sizeof(QuadVertex), sizeof(GrPoint)>(verts + v);
|
| + toUV.apply<6, sizeof(QuadVertex), sizeof(GrPoint)>(verts + *v);
|
|
|
| - idxs[i + 0] = v + 3;
|
| - idxs[i + 1] = v + 1;
|
| - idxs[i + 2] = v + 2;
|
| - idxs[i + 3] = v + 4;
|
| - idxs[i + 4] = v + 3;
|
| - idxs[i + 5] = v + 2;
|
| + idxs[*i + 0] = *v + 3;
|
| + idxs[*i + 1] = *v + 1;
|
| + idxs[*i + 2] = *v + 2;
|
| + idxs[*i + 3] = *v + 4;
|
| + idxs[*i + 4] = *v + 3;
|
| + idxs[*i + 5] = *v + 2;
|
|
|
| - idxs[i + 6] = v + 5;
|
| - idxs[i + 7] = v + 3;
|
| - idxs[i + 8] = v + 4;
|
| + idxs[*i + 6] = *v + 5;
|
| + idxs[*i + 7] = *v + 3;
|
| + idxs[*i + 8] = *v + 4;
|
|
|
| - idxs[i + 9] = v + 0;
|
| - idxs[i + 10] = v + 2;
|
| - idxs[i + 11] = v + 1;
|
| + idxs[*i + 9] = *v + 0;
|
| + idxs[*i + 10] = *v + 2;
|
| + idxs[*i + 11] = *v + 1;
|
|
|
| - v += 6;
|
| - i += 12;
|
| + *v += 6;
|
| + *i += 12;
|
| }
|
| }
|
| }
|
| @@ -601,6 +628,7 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
|
| int iCount;
|
| enum {
|
| kPreallocSegmentCnt = 512 / sizeof(Segment),
|
| + kPreallocDrawCnt = 4,
|
| };
|
| SkSTArray<kPreallocSegmentCnt, Segment, true> segments;
|
| SkPoint fanPt;
|
| @@ -629,13 +657,19 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
|
| verts = reinterpret_cast<QuadVertex*>(arg.vertices());
|
| idxs = reinterpret_cast<uint16_t*>(arg.indices());
|
|
|
| - create_vertices(segments, fanPt, verts, idxs);
|
| -
|
| - target->drawIndexed(kTriangles_GrPrimitiveType,
|
| - 0, // start vertex
|
| - 0, // start index
|
| - vCount,
|
| - iCount);
|
| + SkSTArray<kPreallocDrawCnt, Draw, true> draws;
|
| + create_vertices(segments, fanPt, &draws, verts, idxs);
|
| +
|
| + int vOffset = 0;
|
| + for (int i = 0; i < draws.count(); ++i) {
|
| + const Draw& draw = draws[i];
|
| + target->drawIndexed(kTriangles_GrPrimitiveType,
|
| + vOffset, // start vertex
|
| + 0, // start index
|
| + draw.fVertexCnt,
|
| + draw.fIndexCnt);
|
| + vOffset += draw.fVertexCnt;
|
| + }
|
|
|
| return true;
|
| }
|
|
|