OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrAAHairLinePathRenderer.h" | 8 #include "GrAAHairLinePathRenderer.h" |
9 | 9 |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
11 #include "GrDrawState.h" | 11 #include "GrDrawState.h" |
12 #include "GrDrawTargetCaps.h" | 12 #include "GrDrawTargetCaps.h" |
13 #include "GrProcessor.h" | 13 #include "GrProcessor.h" |
14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
16 #include "GrPathUtils.h" | 16 #include "GrPathUtils.h" |
17 #include "GrTBackendProcessorFactory.h" | 17 #include "GrTBackendProcessorFactory.h" |
18 #include "SkGeometry.h" | 18 #include "SkGeometry.h" |
19 #include "SkStroke.h" | 19 #include "SkStroke.h" |
20 #include "SkTemplates.h" | 20 #include "SkTemplates.h" |
21 | 21 |
22 #include "effects/GrBezierEffect.h" | 22 #include "effects/GrBezierEffect.h" |
23 | 23 |
24 namespace { | |
25 // quadratics are rendered as 5-sided polys in order to bound the | 24 // quadratics are rendered as 5-sided polys in order to bound the |
26 // AA stroke around the center-curve. See comments in push_quad_index_buffer and | 25 // AA stroke around the center-curve. See comments in push_quad_index_buffer and |
27 // bloat_quad. Quadratics and conics share an index buffer | 26 // bloat_quad. Quadratics and conics share an index buffer |
28 static const int kVertsPerQuad = 5; | |
29 static const int kIdxsPerQuad = 9; | |
30 | 27 |
31 // lines are rendered as: | 28 // lines are rendered as: |
32 // *______________* | 29 // *______________* |
33 // |\ -_______ /| | 30 // |\ -_______ /| |
34 // | \ \ / | | 31 // | \ \ / | |
35 // | *--------* | | 32 // | *--------* | |
36 // | / ______/ \ | | 33 // | / ______/ \ | |
37 // */_-__________\* | 34 // */_-__________\* |
38 // For: 6 vertices and 18 indices (for 6 triangles) | 35 // For: 6 vertices and 18 indices (for 6 triangles) |
39 static const int kVertsPerLineSeg = 6; | |
40 static const int kIdxsPerLineSeg = 18; | |
41 | 36 |
42 static const int kNumQuadsInIdxBuffer = 256; | 37 // Each quadratic is rendered as a five sided polygon. This poly bounds |
43 static const size_t kQuadIdxSBufize = kIdxsPerQuad * | 38 // the quadratic's bounding triangle but has been expanded so that the |
44 sizeof(uint16_t) * | 39 // 1-pixel wide area around the curve is inside the poly. |
45 kNumQuadsInIdxBuffer; | 40 // If a,b,c are the original control points then the poly a0,b0,c0,c1,a1 |
| 41 // that is rendered would look like this: |
| 42 // b0 |
| 43 // b |
| 44 // |
| 45 // a0 c0 |
| 46 // a c |
| 47 // a1 c1 |
| 48 // Each is drawn as three triangles specified by these 9 indices: |
| 49 static const uint16_t kQuadIdxBufPattern[] = { |
| 50 0, 1, 2, |
| 51 2, 4, 3, |
| 52 1, 4, 2 |
| 53 }; |
46 | 54 |
47 static const int kNumLineSegsInIdxBuffer = 256; | 55 static const int kIdxsPerQuad = SK_ARRAY_COUNT(kQuadIdxBufPattern); |
48 static const size_t kLineSegIdxSBufize = kIdxsPerLineSeg * | 56 static const int kQuadNumVertices = 5; |
49 sizeof(uint16_t) * | 57 static const int kQuadsNumInIdxBuffer = 256; |
50 kNumLineSegsInIdxBuffer; | |
51 | 58 |
52 static bool push_quad_index_data(GrIndexBuffer* qIdxBuffer) { | |
53 uint16_t* data = (uint16_t*) qIdxBuffer->map(); | |
54 bool tempData = NULL == data; | |
55 if (tempData) { | |
56 data = SkNEW_ARRAY(uint16_t, kNumQuadsInIdxBuffer * kIdxsPerQuad); | |
57 } | |
58 for (int i = 0; i < kNumQuadsInIdxBuffer; ++i) { | |
59 | 59 |
60 // Each quadratic is rendered as a five sided polygon. This poly bounds | 60 // Each line segment is rendered as two quads and two triangles. |
61 // the quadratic's bounding triangle but has been expanded so that the | 61 // p0 and p1 have alpha = 1 while all other points have alpha = 0. |
62 // 1-pixel wide area around the curve is inside the poly. | 62 // The four external points are offset 1 pixel perpendicular to the |
63 // If a,b,c are the original control points then the poly a0,b0,c0,c1,a1 | 63 // line and half a pixel parallel to the line. |
64 // that is rendered would look like this: | 64 // |
65 // b0 | 65 // p4 p5 |
66 // b | 66 // p0 p1 |
67 // | 67 // p2 p3 |
68 // a0 c0 | 68 // |
69 // a c | 69 // Each is drawn as six triangles specified by these 18 indices: |
70 // a1 c1 | |
71 // Each is drawn as three triangles specified by these 9 indices: | |
72 int baseIdx = i * kIdxsPerQuad; | |
73 uint16_t baseVert = (uint16_t)(i * kVertsPerQuad); | |
74 data[0 + baseIdx] = baseVert + 0; // a0 | |
75 data[1 + baseIdx] = baseVert + 1; // a1 | |
76 data[2 + baseIdx] = baseVert + 2; // b0 | |
77 data[3 + baseIdx] = baseVert + 2; // b0 | |
78 data[4 + baseIdx] = baseVert + 4; // c1 | |
79 data[5 + baseIdx] = baseVert + 3; // c0 | |
80 data[6 + baseIdx] = baseVert + 1; // a1 | |
81 data[7 + baseIdx] = baseVert + 4; // c1 | |
82 data[8 + baseIdx] = baseVert + 2; // b0 | |
83 } | |
84 if (tempData) { | |
85 bool ret = qIdxBuffer->updateData(data, kQuadIdxSBufize); | |
86 delete[] data; | |
87 return ret; | |
88 } else { | |
89 qIdxBuffer->unmap(); | |
90 return true; | |
91 } | |
92 } | |
93 | 70 |
94 static bool push_line_index_data(GrIndexBuffer* lIdxBuffer) { | 71 static const uint16_t kLineSegIdxBufPattern[] = { |
95 uint16_t* data = (uint16_t*) lIdxBuffer->map(); | 72 0, 1, 3, |
96 bool tempData = NULL == data; | 73 0, 3, 2, |
97 if (tempData) { | 74 0, 4, 5, |
98 data = SkNEW_ARRAY(uint16_t, kNumLineSegsInIdxBuffer * kIdxsPerLineSeg); | 75 0, 5, 1, |
99 } | 76 0, 2, 4, |
100 for (int i = 0; i < kNumLineSegsInIdxBuffer; ++i) { | 77 1, 5, 3 |
101 // Each line segment is rendered as two quads and two triangles. | 78 }; |
102 // p0 and p1 have alpha = 1 while all other points have alpha = 0. | |
103 // The four external points are offset 1 pixel perpendicular to the | |
104 // line and half a pixel parallel to the line. | |
105 // | |
106 // p4 p5 | |
107 // p0 p1 | |
108 // p2 p3 | |
109 // | |
110 // Each is drawn as six triangles specified by these 18 indices: | |
111 int baseIdx = i * kIdxsPerLineSeg; | |
112 uint16_t baseVert = (uint16_t)(i * kVertsPerLineSeg); | |
113 data[0 + baseIdx] = baseVert + 0; | |
114 data[1 + baseIdx] = baseVert + 1; | |
115 data[2 + baseIdx] = baseVert + 3; | |
116 | 79 |
117 data[3 + baseIdx] = baseVert + 0; | 80 static const int kIdxsPerLineSeg = SK_ARRAY_COUNT(kLineSegIdxBufPattern); |
118 data[4 + baseIdx] = baseVert + 3; | 81 static const int kLineSegNumVertices = 6; |
119 data[5 + baseIdx] = baseVert + 2; | 82 static const int kLineSegsNumInIdxBuffer = 256; |
120 | |
121 data[6 + baseIdx] = baseVert + 0; | |
122 data[7 + baseIdx] = baseVert + 4; | |
123 data[8 + baseIdx] = baseVert + 5; | |
124 | |
125 data[9 + baseIdx] = baseVert + 0; | |
126 data[10+ baseIdx] = baseVert + 5; | |
127 data[11+ baseIdx] = baseVert + 1; | |
128 | |
129 data[12 + baseIdx] = baseVert + 0; | |
130 data[13 + baseIdx] = baseVert + 2; | |
131 data[14 + baseIdx] = baseVert + 4; | |
132 | |
133 data[15 + baseIdx] = baseVert + 1; | |
134 data[16 + baseIdx] = baseVert + 5; | |
135 data[17 + baseIdx] = baseVert + 3; | |
136 } | |
137 if (tempData) { | |
138 bool ret = lIdxBuffer->updateData(data, kLineSegIdxSBufize); | |
139 delete[] data; | |
140 return ret; | |
141 } else { | |
142 lIdxBuffer->unmap(); | |
143 return true; | |
144 } | |
145 } | |
146 } | |
147 | 83 |
148 GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) { | 84 GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) { |
149 GrGpu* gpu = context->getGpu(); | 85 GrGpu* gpu = context->getGpu(); |
150 GrIndexBuffer* qIdxBuf = gpu->createIndexBuffer(kQuadIdxSBufize, false); | 86 GrIndexBuffer* qIdxBuf = gpu->createInstancedIndexBuffer(kQuadIdxBufPattern, |
| 87 kIdxsPerQuad, |
| 88 kQuadsNumInIdxBuffe
r, |
| 89 kQuadNumVertices); |
151 SkAutoTUnref<GrIndexBuffer> qIdxBuffer(qIdxBuf); | 90 SkAutoTUnref<GrIndexBuffer> qIdxBuffer(qIdxBuf); |
152 if (NULL == qIdxBuf || !push_quad_index_data(qIdxBuf)) { | 91 GrIndexBuffer* lIdxBuf = gpu->createInstancedIndexBuffer(kLineSegIdxBufPatte
rn, |
153 return NULL; | 92 kIdxsPerLineSeg, |
154 } | 93 kLineSegsNumInIdxBu
ffer, |
155 GrIndexBuffer* lIdxBuf = gpu->createIndexBuffer(kLineSegIdxSBufize, false); | 94 kLineSegNumVertices
); |
156 SkAutoTUnref<GrIndexBuffer> lIdxBuffer(lIdxBuf); | 95 SkAutoTUnref<GrIndexBuffer> lIdxBuffer(lIdxBuf); |
157 if (NULL == lIdxBuf || !push_line_index_data(lIdxBuf)) { | |
158 return NULL; | |
159 } | |
160 return SkNEW_ARGS(GrAAHairLinePathRenderer, | 96 return SkNEW_ARGS(GrAAHairLinePathRenderer, |
161 (context, lIdxBuf, qIdxBuf)); | 97 (context, lIdxBuf, qIdxBuf)); |
162 } | 98 } |
163 | 99 |
164 GrAAHairLinePathRenderer::GrAAHairLinePathRenderer( | 100 GrAAHairLinePathRenderer::GrAAHairLinePathRenderer( |
165 const GrContext* context, | 101 const GrContext* context, |
166 const GrIndexBuffer* linesIndexBuffer, | 102 const GrIndexBuffer* linesIndexBuffer, |
167 const GrIndexBuffer* quadsIndexBuffer) { | 103 const GrIndexBuffer* quadsIndexBuffer) { |
168 fLinesIndexBuffer = linesIndexBuffer; | 104 fLinesIndexBuffer = linesIndexBuffer; |
169 linesIndexBuffer->ref(); | 105 linesIndexBuffer->ref(); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 SkScalarMul(normA.fY, normB.fX); | 454 SkScalarMul(normA.fY, normB.fX); |
519 wInv = SkScalarInvert(wInv); | 455 wInv = SkScalarInvert(wInv); |
520 | 456 |
521 result->fX = SkScalarMul(normA.fY, lineBW) - SkScalarMul(lineAW, normB.fY); | 457 result->fX = SkScalarMul(normA.fY, lineBW) - SkScalarMul(lineAW, normB.fY); |
522 result->fX = SkScalarMul(result->fX, wInv); | 458 result->fX = SkScalarMul(result->fX, wInv); |
523 | 459 |
524 result->fY = SkScalarMul(lineAW, normB.fX) - SkScalarMul(normA.fX, lineBW); | 460 result->fY = SkScalarMul(lineAW, normB.fX) - SkScalarMul(normA.fX, lineBW); |
525 result->fY = SkScalarMul(result->fY, wInv); | 461 result->fY = SkScalarMul(result->fY, wInv); |
526 } | 462 } |
527 | 463 |
528 void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kVertsPerQuad]) { | 464 void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) { |
529 // this should be in the src space, not dev coords, when we have perspective | 465 // this should be in the src space, not dev coords, when we have perspective |
530 GrPathUtils::QuadUVMatrix DevToUV(qpts); | 466 GrPathUtils::QuadUVMatrix DevToUV(qpts); |
531 DevToUV.apply<kVertsPerQuad, sizeof(BezierVertex), sizeof(SkPoint)>(verts); | 467 DevToUV.apply<kQuadNumVertices, sizeof(BezierVertex), sizeof(SkPoint)>(verts
); |
532 } | 468 } |
533 | 469 |
534 void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice, | 470 void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice, |
535 const SkMatrix* toSrc, BezierVertex verts[kVertsPerQuad], | 471 const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices], |
536 SkRect* devBounds) { | 472 SkRect* devBounds) { |
537 SkASSERT(!toDevice == !toSrc); | 473 SkASSERT(!toDevice == !toSrc); |
538 // original quad is specified by tri a,b,c | 474 // original quad is specified by tri a,b,c |
539 SkPoint a = qpts[0]; | 475 SkPoint a = qpts[0]; |
540 SkPoint b = qpts[1]; | 476 SkPoint b = qpts[1]; |
541 SkPoint c = qpts[2]; | 477 SkPoint c = qpts[2]; |
542 | 478 |
543 if (toDevice) { | 479 if (toDevice) { |
544 toDevice->mapPoints(&a, 1); | 480 toDevice->mapPoints(&a, 1); |
545 toDevice->mapPoints(&b, 1); | 481 toDevice->mapPoints(&b, 1); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 a0.fPos += abN; | 527 a0.fPos += abN; |
592 a1.fPos = a; | 528 a1.fPos = a; |
593 a1.fPos -= abN; | 529 a1.fPos -= abN; |
594 | 530 |
595 c0.fPos = c; | 531 c0.fPos = c; |
596 c0.fPos += cbN; | 532 c0.fPos += cbN; |
597 c1.fPos = c; | 533 c1.fPos = c; |
598 c1.fPos -= cbN; | 534 c1.fPos -= cbN; |
599 | 535 |
600 intersect_lines(a0.fPos, abN, c0.fPos, cbN, &b0.fPos); | 536 intersect_lines(a0.fPos, abN, c0.fPos, cbN, &b0.fPos); |
601 devBounds->growToInclude(&verts[0].fPos, sizeof(BezierVertex), kVertsPerQuad
); | 537 devBounds->growToInclude(&verts[0].fPos, sizeof(BezierVertex), kQuadNumVerti
ces); |
602 | 538 |
603 if (toSrc) { | 539 if (toSrc) { |
604 toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(BezierVertex), kVertsP
erQuad); | 540 toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(BezierVertex), kQuadNu
mVertices); |
605 } | 541 } |
606 } | 542 } |
607 | 543 |
608 // Equations based off of Loop-Blinn Quadratic GPU Rendering | 544 // Equations based off of Loop-Blinn Quadratic GPU Rendering |
609 // Input Parametric: | 545 // Input Parametric: |
610 // P(t) = (P0*(1-t)^2 + 2*w*P1*t*(1-t) + P2*t^2) / (1-t)^2 + 2*w*t*(1-t) + t^2) | 546 // P(t) = (P0*(1-t)^2 + 2*w*P1*t*(1-t) + P2*t^2) / (1-t)^2 + 2*w*t*(1-t) + t^2) |
611 // Output Implicit: | 547 // Output Implicit: |
612 // f(x, y, w) = f(P) = K^2 - LM | 548 // f(x, y, w) = f(P) = K^2 - LM |
613 // K = dot(k, P), L = dot(l, P), M = dot(m, P) | 549 // K = dot(k, P), L = dot(l, P), M = dot(m, P) |
614 // k, l, m are calculated in function GrPathUtils::getConicKLM | 550 // k, l, m are calculated in function GrPathUtils::getConicKLM |
615 void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kVertsPerQuad], | 551 void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices], |
616 const SkScalar weight) { | 552 const SkScalar weight) { |
617 SkScalar klm[9]; | 553 SkScalar klm[9]; |
618 | 554 |
619 GrPathUtils::getConicKLM(p, weight, klm); | 555 GrPathUtils::getConicKLM(p, weight, klm); |
620 | 556 |
621 for (int i = 0; i < kVertsPerQuad; ++i) { | 557 for (int i = 0; i < kQuadNumVertices; ++i) { |
622 const SkPoint pnt = verts[i].fPos; | 558 const SkPoint pnt = verts[i].fPos; |
623 verts[i].fConic.fK = pnt.fX * klm[0] + pnt.fY * klm[1] + klm[2]; | 559 verts[i].fConic.fK = pnt.fX * klm[0] + pnt.fY * klm[1] + klm[2]; |
624 verts[i].fConic.fL = pnt.fX * klm[3] + pnt.fY * klm[4] + klm[5]; | 560 verts[i].fConic.fL = pnt.fX * klm[3] + pnt.fY * klm[4] + klm[5]; |
625 verts[i].fConic.fM = pnt.fX * klm[6] + pnt.fY * klm[7] + klm[8]; | 561 verts[i].fConic.fM = pnt.fX * klm[6] + pnt.fY * klm[7] + klm[8]; |
626 } | 562 } |
627 } | 563 } |
628 | 564 |
629 void add_conics(const SkPoint p[3], | 565 void add_conics(const SkPoint p[3], |
630 const SkScalar weight, | 566 const SkScalar weight, |
631 const SkMatrix* toDevice, | 567 const SkMatrix* toDevice, |
632 const SkMatrix* toSrc, | 568 const SkMatrix* toSrc, |
633 BezierVertex** vert, | 569 BezierVertex** vert, |
634 SkRect* devBounds) { | 570 SkRect* devBounds) { |
635 bloat_quad(p, toDevice, toSrc, *vert, devBounds); | 571 bloat_quad(p, toDevice, toSrc, *vert, devBounds); |
636 set_conic_coeffs(p, *vert, weight); | 572 set_conic_coeffs(p, *vert, weight); |
637 *vert += kVertsPerQuad; | 573 *vert += kQuadNumVertices; |
638 } | 574 } |
639 | 575 |
640 void add_quads(const SkPoint p[3], | 576 void add_quads(const SkPoint p[3], |
641 int subdiv, | 577 int subdiv, |
642 const SkMatrix* toDevice, | 578 const SkMatrix* toDevice, |
643 const SkMatrix* toSrc, | 579 const SkMatrix* toSrc, |
644 BezierVertex** vert, | 580 BezierVertex** vert, |
645 SkRect* devBounds) { | 581 SkRect* devBounds) { |
646 SkASSERT(subdiv >= 0); | 582 SkASSERT(subdiv >= 0); |
647 if (subdiv) { | 583 if (subdiv) { |
648 SkPoint newP[5]; | 584 SkPoint newP[5]; |
649 SkChopQuadAtHalf(p, newP); | 585 SkChopQuadAtHalf(p, newP); |
650 add_quads(newP + 0, subdiv-1, toDevice, toSrc, vert, devBounds); | 586 add_quads(newP + 0, subdiv-1, toDevice, toSrc, vert, devBounds); |
651 add_quads(newP + 2, subdiv-1, toDevice, toSrc, vert, devBounds); | 587 add_quads(newP + 2, subdiv-1, toDevice, toSrc, vert, devBounds); |
652 } else { | 588 } else { |
653 bloat_quad(p, toDevice, toSrc, *vert, devBounds); | 589 bloat_quad(p, toDevice, toSrc, *vert, devBounds); |
654 set_uv_quad(p, *vert); | 590 set_uv_quad(p, *vert); |
655 *vert += kVertsPerQuad; | 591 *vert += kQuadNumVertices; |
656 } | 592 } |
657 } | 593 } |
658 | 594 |
659 void add_line(const SkPoint p[2], | 595 void add_line(const SkPoint p[2], |
660 const SkMatrix* toSrc, | 596 const SkMatrix* toSrc, |
661 GrColor coverage, | 597 GrColor coverage, |
662 LineVertex** vert) { | 598 LineVertex** vert) { |
663 const SkPoint& a = p[0]; | 599 const SkPoint& a = p[0]; |
664 const SkPoint& b = p[1]; | 600 const SkPoint& b = p[1]; |
665 | 601 |
(...skipping 14 matching lines...) Expand all Loading... |
680 (*vert)[3].fPos = b + vec + ortho; | 616 (*vert)[3].fPos = b + vec + ortho; |
681 (*vert)[3].fCoverage = 0; | 617 (*vert)[3].fCoverage = 0; |
682 (*vert)[4].fPos = a - vec - ortho; | 618 (*vert)[4].fPos = a - vec - ortho; |
683 (*vert)[4].fCoverage = 0; | 619 (*vert)[4].fCoverage = 0; |
684 (*vert)[5].fPos = b + vec - ortho; | 620 (*vert)[5].fPos = b + vec - ortho; |
685 (*vert)[5].fCoverage = 0; | 621 (*vert)[5].fCoverage = 0; |
686 | 622 |
687 if (toSrc) { | 623 if (toSrc) { |
688 toSrc->mapPointsWithStride(&(*vert)->fPos, | 624 toSrc->mapPointsWithStride(&(*vert)->fPos, |
689 sizeof(LineVertex), | 625 sizeof(LineVertex), |
690 kVertsPerLineSeg); | 626 kLineSegNumVertices); |
691 } | 627 } |
692 } else { | 628 } else { |
693 // just make it degenerate and likely offscreen | 629 // just make it degenerate and likely offscreen |
694 for (int i = 0; i < kVertsPerLineSeg; ++i) { | 630 for (int i = 0; i < kLineSegNumVertices; ++i) { |
695 (*vert)[i].fPos.set(SK_ScalarMax, SK_ScalarMax); | 631 (*vert)[i].fPos.set(SK_ScalarMax, SK_ScalarMax); |
696 } | 632 } |
697 } | 633 } |
698 | 634 |
699 *vert += kVertsPerLineSeg; | 635 *vert += kLineSegNumVertices; |
700 } | 636 } |
701 | 637 |
702 } | 638 } |
703 | 639 |
704 /////////////////////////////////////////////////////////////////////////////// | 640 /////////////////////////////////////////////////////////////////////////////// |
705 | 641 |
706 namespace { | 642 namespace { |
707 | 643 |
708 // position + edge | 644 // position + edge |
709 extern const GrVertexAttrib gHairlineBezierAttribs[] = { | 645 extern const GrVertexAttrib gHairlineBezierAttribs[] = { |
(...skipping 12 matching lines...) Expand all Loading... |
722 bool GrAAHairLinePathRenderer::createLineGeom(const SkPath& path, | 658 bool GrAAHairLinePathRenderer::createLineGeom(const SkPath& path, |
723 GrDrawTarget* target, | 659 GrDrawTarget* target, |
724 const PtArray& lines, | 660 const PtArray& lines, |
725 int lineCnt, | 661 int lineCnt, |
726 GrDrawTarget::AutoReleaseGeometry*
arg, | 662 GrDrawTarget::AutoReleaseGeometry*
arg, |
727 SkRect* devBounds) { | 663 SkRect* devBounds) { |
728 GrDrawState* drawState = target->drawState(); | 664 GrDrawState* drawState = target->drawState(); |
729 | 665 |
730 const SkMatrix& viewM = drawState->getViewMatrix(); | 666 const SkMatrix& viewM = drawState->getViewMatrix(); |
731 | 667 |
732 int vertCnt = kVertsPerLineSeg * lineCnt; | 668 int vertCnt = kLineSegNumVertices * lineCnt; |
733 | 669 |
734 drawState->setVertexAttribs<gHairlineLineAttribs>(SK_ARRAY_COUNT(gHairlineLi
neAttribs), | 670 drawState->setVertexAttribs<gHairlineLineAttribs>(SK_ARRAY_COUNT(gHairlineLi
neAttribs), |
735 sizeof(LineVertex)); | 671 sizeof(LineVertex)); |
736 | 672 |
737 if (!arg->set(target, vertCnt, 0)) { | 673 if (!arg->set(target, vertCnt, 0)) { |
738 return false; | 674 return false; |
739 } | 675 } |
740 | 676 |
741 LineVertex* verts = reinterpret_cast<LineVertex*>(arg->vertices()); | 677 LineVertex* verts = reinterpret_cast<LineVertex*>(arg->vertices()); |
742 | 678 |
(...skipping 26 matching lines...) Expand all Loading... |
769 const PtArray& conics, | 705 const PtArray& conics, |
770 int conicCnt, | 706 int conicCnt, |
771 const IntArray& qSubdivs, | 707 const IntArray& qSubdivs, |
772 const FloatArray& cWeights, | 708 const FloatArray& cWeights, |
773 GrDrawTarget::AutoReleaseGeometry* arg
, | 709 GrDrawTarget::AutoReleaseGeometry* arg
, |
774 SkRect* devBounds) { | 710 SkRect* devBounds) { |
775 GrDrawState* drawState = target->drawState(); | 711 GrDrawState* drawState = target->drawState(); |
776 | 712 |
777 const SkMatrix& viewM = drawState->getViewMatrix(); | 713 const SkMatrix& viewM = drawState->getViewMatrix(); |
778 | 714 |
779 int vertCnt = kVertsPerQuad * quadCnt + kVertsPerQuad * conicCnt; | 715 int vertCnt = kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt; |
780 | 716 |
781 int vAttribCnt = SK_ARRAY_COUNT(gHairlineBezierAttribs); | 717 int vAttribCnt = SK_ARRAY_COUNT(gHairlineBezierAttribs); |
782 target->drawState()->setVertexAttribs<gHairlineBezierAttribs>(vAttribCnt, si
zeof(BezierVertex)); | 718 target->drawState()->setVertexAttribs<gHairlineBezierAttribs>(vAttribCnt, si
zeof(BezierVertex)); |
783 | 719 |
784 if (!arg->set(target, vertCnt, 0)) { | 720 if (!arg->set(target, vertCnt, 0)) { |
785 return false; | 721 return false; |
786 } | 722 } |
787 | 723 |
788 BezierVertex* verts = reinterpret_cast<BezierVertex*>(arg->vertices()); | 724 BezierVertex* verts = reinterpret_cast<BezierVertex*>(arg->vertices()); |
789 | 725 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 // perspective. | 871 // perspective. |
936 if (target->getDrawState().getViewMatrix().hasPerspective()) { | 872 if (target->getDrawState().getViewMatrix().hasPerspective()) { |
937 asr.set(target, GrDrawTarget::kPreserve_ASRInit); | 873 asr.set(target, GrDrawTarget::kPreserve_ASRInit); |
938 } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) { | 874 } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) { |
939 return false; | 875 return false; |
940 } | 876 } |
941 GrDrawState* drawState = target->drawState(); | 877 GrDrawState* drawState = target->drawState(); |
942 | 878 |
943 // Check devBounds | 879 // Check devBounds |
944 SkASSERT(check_bounds<LineVertex>(drawState, devBounds, arg.vertices(), | 880 SkASSERT(check_bounds<LineVertex>(drawState, devBounds, arg.vertices(), |
945 kVertsPerLineSeg * lineCnt)); | 881 kLineSegNumVertices * lineCnt)); |
946 | 882 |
947 { | 883 { |
948 GrDrawState::AutoRestoreEffects are(drawState); | 884 GrDrawState::AutoRestoreEffects are(drawState); |
949 target->setIndexSourceToBuffer(fLinesIndexBuffer); | 885 target->setIndexSourceToBuffer(fLinesIndexBuffer); |
950 int lines = 0; | 886 int lines = 0; |
951 while (lines < lineCnt) { | 887 while (lines < lineCnt) { |
952 int n = SkTMin(lineCnt - lines, kNumLineSegsInIdxBuffer); | 888 int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer); |
953 target->drawIndexed(kTriangles_GrPrimitiveType, | 889 target->drawIndexed(kTriangles_GrPrimitiveType, |
954 kVertsPerLineSeg*lines, // startV | 890 kLineSegNumVertices*lines, // startV |
955 0, // startI | 891 0, // startI |
956 kVertsPerLineSeg*n, // vCount | 892 kLineSegNumVertices*n, // vCount |
957 kIdxsPerLineSeg*n, // iCount | 893 kIdxsPerLineSeg*n, // iCount |
958 &devBounds); | 894 &devBounds); |
959 lines += n; | 895 lines += n; |
960 } | 896 } |
961 } | 897 } |
962 } | 898 } |
963 | 899 |
964 // then quadratics/conics | 900 // then quadratics/conics |
965 if (quadCnt || conicCnt) { | 901 if (quadCnt || conicCnt) { |
966 GrDrawTarget::AutoReleaseGeometry arg; | 902 GrDrawTarget::AutoReleaseGeometry arg; |
967 SkRect devBounds; | 903 SkRect devBounds; |
(...skipping 17 matching lines...) Expand all Loading... |
985 // perspective. | 921 // perspective. |
986 if (target->getDrawState().getViewMatrix().hasPerspective()) { | 922 if (target->getDrawState().getViewMatrix().hasPerspective()) { |
987 asr.set(target, GrDrawTarget::kPreserve_ASRInit); | 923 asr.set(target, GrDrawTarget::kPreserve_ASRInit); |
988 } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) { | 924 } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) { |
989 return false; | 925 return false; |
990 } | 926 } |
991 GrDrawState* drawState = target->drawState(); | 927 GrDrawState* drawState = target->drawState(); |
992 | 928 |
993 // Check devBounds | 929 // Check devBounds |
994 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, | 930 SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices()
, |
995 kVertsPerQuad * quadCnt + kVertsPerQ
uad * conicCnt)); | 931 kQuadNumVertices * quadCnt + kQuadNu
mVertices * conicCnt)); |
996 | 932 |
997 if (quadCnt > 0) { | 933 if (quadCnt > 0) { |
998 GrGeometryProcessor* hairQuadProcessor = | 934 GrGeometryProcessor* hairQuadProcessor = |
999 GrQuadEffect::Create(kHairlineAA_GrProcessorEdgeType, *targe
t->caps()); | 935 GrQuadEffect::Create(kHairlineAA_GrProcessorEdgeType, *targe
t->caps()); |
1000 SkASSERT(hairQuadProcessor); | 936 SkASSERT(hairQuadProcessor); |
1001 GrDrawState::AutoRestoreEffects are(drawState); | 937 GrDrawState::AutoRestoreEffects are(drawState); |
1002 target->setIndexSourceToBuffer(fQuadsIndexBuffer); | 938 target->setIndexSourceToBuffer(fQuadsIndexBuffer); |
1003 drawState->setGeometryProcessor(hairQuadProcessor)->unref(); | 939 drawState->setGeometryProcessor(hairQuadProcessor)->unref(); |
1004 int quads = 0; | 940 int quads = 0; |
1005 while (quads < quadCnt) { | 941 while (quads < quadCnt) { |
1006 int n = SkTMin(quadCnt - quads, kNumQuadsInIdxBuffer); | 942 int n = SkTMin(quadCnt - quads, kQuadsNumInIdxBuffer); |
1007 target->drawIndexed(kTriangles_GrPrimitiveType, | 943 target->drawIndexed(kTriangles_GrPrimitiveType, |
1008 kVertsPerQuad*quads, // startV | 944 kQuadNumVertices*quads, // sta
rtV |
1009 0, // startI | 945 0, // sta
rtI |
1010 kVertsPerQuad*n, // vCount | 946 kQuadNumVertices*n, // vCo
unt |
1011 kIdxsPerQuad*n, // iCount | 947 kIdxsPerQuad*n, // iCo
unt |
1012 &devBounds); | 948 &devBounds); |
1013 quads += n; | 949 quads += n; |
1014 } | 950 } |
1015 } | 951 } |
1016 | 952 |
1017 if (conicCnt > 0) { | 953 if (conicCnt > 0) { |
1018 GrDrawState::AutoRestoreEffects are(drawState); | 954 GrDrawState::AutoRestoreEffects are(drawState); |
1019 GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create( | 955 GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create( |
1020 kHairlineAA_GrProcessorEdgeType, *target->caps()); | 956 kHairlineAA_GrProcessorEdgeType, *target->caps()); |
1021 SkASSERT(hairConicProcessor); | 957 SkASSERT(hairConicProcessor); |
1022 drawState->setGeometryProcessor(hairConicProcessor)->unref(); | 958 drawState->setGeometryProcessor(hairConicProcessor)->unref(); |
1023 int conics = 0; | 959 int conics = 0; |
1024 while (conics < conicCnt) { | 960 while (conics < conicCnt) { |
1025 int n = SkTMin(conicCnt - conics, kNumQuadsInIdxBuffer); | 961 int n = SkTMin(conicCnt - conics, kQuadsNumInIdxBuffer); |
1026 target->drawIndexed(kTriangles_GrPrimitiveType, | 962 target->drawIndexed(kTriangles_GrPrimitiveType, |
1027 kVertsPerQuad*(quadCnt + conics), // startV | 963 kQuadNumVertices*(quadCnt + conics), // sta
rtV |
1028 0, // startI | 964 0, // sta
rtI |
1029 kVertsPerQuad*n, // vCount | 965 kQuadNumVertices*n, // vCo
unt |
1030 kIdxsPerQuad*n, // iCount | 966 kIdxsPerQuad*n, // iCo
unt |
1031 &devBounds); | 967 &devBounds); |
1032 conics += n; | 968 conics += n; |
1033 } | 969 } |
1034 } | 970 } |
1035 } | 971 } |
1036 | 972 |
1037 target->resetIndexSource(); | 973 target->resetIndexSource(); |
1038 | 974 |
1039 return true; | 975 return true; |
1040 } | 976 } |
OLD | NEW |