| 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 |