OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAAHairLinePathRenderer.h" | 9 #include "GrAAHairLinePathRenderer.h" |
10 | 10 |
11 #include "GrContext.h" | 11 #include "GrContext.h" |
12 #include "GrDrawState.h" | 12 #include "GrDrawState.h" |
13 #include "GrDrawTargetCaps.h" | 13 #include "GrDrawTargetCaps.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 "SkGeometry.h" | 17 #include "SkGeometry.h" |
18 #include "SkStroke.h" | 18 #include "SkStroke.h" |
19 #include "SkTemplates.h" | 19 #include "SkTemplates.h" |
20 | 20 |
| 21 #include "effects/GrEdgeEffect.h" |
| 22 |
21 namespace { | 23 namespace { |
22 // 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 |
23 // 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 |
24 // bloat_quad. | 26 // bloat_quad. |
25 static const int kVertsPerQuad = 5; | 27 static const int kVertsPerQuad = 5; |
26 static const int kIdxsPerQuad = 9; | 28 static const int kIdxsPerQuad = 9; |
27 | 29 |
28 static const int kVertsPerLineSeg = 4; | 30 static const int kVertsPerLineSeg = 4; |
29 static const int kIdxsPerLineSeg = 6; | 31 static const int kIdxsPerLineSeg = 6; |
30 | 32 |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 | 503 |
502 GrIRect devClipBounds; | 504 GrIRect devClipBounds; |
503 target->getClip()->getConservativeBounds(drawState->getRenderTarget(), | 505 target->getClip()->getConservativeBounds(drawState->getRenderTarget(), |
504 &devClipBounds); | 506 &devClipBounds); |
505 | 507 |
506 // position + edge | 508 // position + edge |
507 static const GrVertexAttrib kAttribs[] = { | 509 static const GrVertexAttrib kAttribs[] = { |
508 {kVec2f_GrVertexAttribType, 0}, | 510 {kVec2f_GrVertexAttribType, 0}, |
509 {kVec4f_GrVertexAttribType, sizeof(GrPoint)} | 511 {kVec4f_GrVertexAttribType, sizeof(GrPoint)} |
510 }; | 512 }; |
511 static const GrAttribBindings kBindings = GrDrawState::kEdge_AttribBindingsB
it; | |
512 SkMatrix viewM = drawState->getViewMatrix(); | 513 SkMatrix viewM = drawState->getViewMatrix(); |
513 | 514 |
514 PREALLOC_PTARRAY(128) lines; | 515 PREALLOC_PTARRAY(128) lines; |
515 PREALLOC_PTARRAY(128) quads; | 516 PREALLOC_PTARRAY(128) quads; |
516 IntArray qSubdivs; | 517 IntArray qSubdivs; |
517 *quadCnt = generate_lines_and_quads(path, viewM, devClipBounds, | 518 *quadCnt = generate_lines_and_quads(path, viewM, devClipBounds, |
518 &lines, &quads, &qSubdivs); | 519 &lines, &quads, &qSubdivs); |
519 | 520 |
520 *lineCnt = lines.count() / 2; | 521 *lineCnt = lines.count() / 2; |
521 int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt; | 522 int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt; |
522 | 523 |
523 target->drawState()->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs)); | 524 target->drawState()->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs)); |
524 target->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); | 525 target->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); |
525 target->drawState()->setAttribIndex(GrDrawState::kEdge_AttribIndex, 1); | 526 target->drawState()->setAttribBindings(GrDrawState::kDefault_AttribBindings)
; |
526 target->drawState()->setAttribBindings(kBindings); | |
527 GrAssert(sizeof(Vertex) == target->getDrawState().getVertexSize()); | 527 GrAssert(sizeof(Vertex) == target->getDrawState().getVertexSize()); |
528 | 528 |
529 if (!arg->set(target, vertCnt, 0)) { | 529 if (!arg->set(target, vertCnt, 0)) { |
530 return false; | 530 return false; |
531 } | 531 } |
532 | 532 |
533 Vertex* verts = reinterpret_cast<Vertex*>(arg->vertices()); | 533 Vertex* verts = reinterpret_cast<Vertex*>(arg->vertices()); |
534 | 534 |
535 const SkMatrix* toDevice = NULL; | 535 const SkMatrix* toDevice = NULL; |
536 const SkMatrix* toSrc = NULL; | 536 const SkMatrix* toSrc = NULL; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 int quadCnt; | 582 int quadCnt; |
583 GrDrawTarget::AutoReleaseGeometry arg; | 583 GrDrawTarget::AutoReleaseGeometry arg; |
584 if (!this->createGeom(path, | 584 if (!this->createGeom(path, |
585 target, | 585 target, |
586 &lineCnt, | 586 &lineCnt, |
587 &quadCnt, | 587 &quadCnt, |
588 &arg)) { | 588 &arg)) { |
589 return false; | 589 return false; |
590 } | 590 } |
591 | 591 |
| 592 GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); |
| 593 GrDrawState* drawState = target->drawState(); |
| 594 |
592 GrDrawState::AutoDeviceCoordDraw adcd; | 595 GrDrawState::AutoDeviceCoordDraw adcd; |
593 GrDrawState* drawState = target->drawState(); | |
594 // createGeom transforms the geometry to device space when the matrix does n
ot have | 596 // createGeom transforms the geometry to device space when the matrix does n
ot have |
595 // perspective. | 597 // perspective. |
596 if (!drawState->getViewMatrix().hasPerspective()) { | 598 if (!drawState->getViewMatrix().hasPerspective()) { |
597 adcd.set(drawState); | 599 adcd.set(drawState); |
598 if (!adcd.succeeded()) { | 600 if (!adcd.succeeded()) { |
599 return false; | 601 return false; |
600 } | 602 } |
601 } | 603 } |
602 | 604 |
603 // TODO: See whether rendering lines as degenerate quads improves perf | 605 // TODO: See whether rendering lines as degenerate quads improves perf |
604 // when we have a mix | 606 // when we have a mix |
605 | 607 |
606 GrDrawState::VertexEdgeType oldEdgeType = drawState->getVertexEdgeType(); | 608 enum { |
| 609 // the edge effects share this stage with glyph rendering |
| 610 // (kGlyphMaskStage in GrTextContext) && SW path rendering |
| 611 // (kPathMaskStage in GrSWMaskHelper) |
| 612 kEdgeEffectStage = GrPaint::kTotalStages, |
| 613 }; |
| 614 static const int kEdgeAttrIndex = 1; |
607 | 615 |
| 616 GrEffectRef* hairLineEffect = GrEdgeEffect::Create(GrEdgeEffect::kHairLine_E
dgeType); |
| 617 GrEffectRef* hairQuadEffect = GrEdgeEffect::Create(GrEdgeEffect::kHairQuad_E
dgeType); |
| 618 |
608 target->setIndexSourceToBuffer(fLinesIndexBuffer); | 619 target->setIndexSourceToBuffer(fLinesIndexBuffer); |
609 int lines = 0; | 620 int lines = 0; |
610 int nBufLines = fLinesIndexBuffer->maxQuads(); | 621 int nBufLines = fLinesIndexBuffer->maxQuads(); |
611 drawState->setVertexEdgeType(GrDrawState::kHairLine_EdgeType); | 622 drawState->setEffect(kEdgeEffectStage, hairLineEffect, kEdgeAttrIndex)->unre
f(); |
612 while (lines < lineCnt) { | 623 while (lines < lineCnt) { |
613 int n = GrMin(lineCnt - lines, nBufLines); | 624 int n = GrMin(lineCnt - lines, nBufLines); |
614 target->drawIndexed(kTriangles_GrPrimitiveType, | 625 target->drawIndexed(kTriangles_GrPrimitiveType, |
615 kVertsPerLineSeg*lines, // startV | 626 kVertsPerLineSeg*lines, // startV |
616 0, // startI | 627 0, // startI |
617 kVertsPerLineSeg*n, // vCount | 628 kVertsPerLineSeg*n, // vCount |
618 kIdxsPerLineSeg*n); // iCount | 629 kIdxsPerLineSeg*n); // iCount |
619 lines += n; | 630 lines += n; |
620 } | 631 } |
621 | 632 |
622 target->setIndexSourceToBuffer(fQuadsIndexBuffer); | 633 target->setIndexSourceToBuffer(fQuadsIndexBuffer); |
623 int quads = 0; | 634 int quads = 0; |
624 drawState->setVertexEdgeType(GrDrawState::kHairQuad_EdgeType); | 635 drawState->setEffect(kEdgeEffectStage, hairQuadEffect, kEdgeAttrIndex)->unre
f(); |
625 while (quads < quadCnt) { | 636 while (quads < quadCnt) { |
626 int n = GrMin(quadCnt - quads, kNumQuadsInIdxBuffer); | 637 int n = GrMin(quadCnt - quads, kNumQuadsInIdxBuffer); |
627 target->drawIndexed(kTriangles_GrPrimitiveType, | 638 target->drawIndexed(kTriangles_GrPrimitiveType, |
628 4 * lineCnt + kVertsPerQuad*quads, // startV | 639 4 * lineCnt + kVertsPerQuad*quads, // startV |
629 0, // startI | 640 0, // startI |
630 kVertsPerQuad*n, // vCount | 641 kVertsPerQuad*n, // vCount |
631 kIdxsPerQuad*n); // iCount | 642 kIdxsPerQuad*n); // iCount |
632 quads += n; | 643 quads += n; |
633 } | 644 } |
634 drawState->setVertexEdgeType(oldEdgeType); | 645 |
635 return true; | 646 return true; |
636 } | 647 } |
OLD | NEW |