OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrBatchTest.h" | 8 #include "GrBatchTest.h" |
9 #include "GrColor.h" | 9 #include "GrColor.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 nullptr, nullptr); | 272 nullptr, nullptr); |
273 } | 273 } |
274 | 274 |
275 return batch; | 275 return batch; |
276 } | 276 } |
277 | 277 |
278 void GrDrawContext::drawRect(const GrClip& clip, | 278 void GrDrawContext::drawRect(const GrClip& clip, |
279 const GrPaint& paint, | 279 const GrPaint& paint, |
280 const SkMatrix& viewMatrix, | 280 const SkMatrix& viewMatrix, |
281 const SkRect& rect, | 281 const SkRect& rect, |
282 const GrStrokeInfo* strokeInfo) { | 282 const GrStyle* style) { |
| 283 if (!style) { |
| 284 style = &GrStyle::SimpleFill(); |
| 285 } |
283 ASSERT_SINGLE_OWNER | 286 ASSERT_SINGLE_OWNER |
284 RETURN_IF_ABANDONED | 287 RETURN_IF_ABANDONED |
285 SkDEBUGCODE(this->validate();) | 288 SkDEBUGCODE(this->validate();) |
286 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); | 289 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); |
287 | 290 |
288 // Dashing should've been devolved to a path in SkGpuDevice | 291 // Path effects should've been devolved to a path in SkGpuDevice |
289 SkASSERT(!strokeInfo || !strokeInfo->isDashed()); | 292 SkASSERT(!style->pathEffect()); |
290 | 293 |
291 AutoCheckFlush acf(fDrawingManager); | 294 AutoCheckFlush acf(fDrawingManager); |
292 | 295 |
293 SkScalar width = !strokeInfo ? -1 : strokeInfo->getWidth(); | 296 const SkStrokeRec& stroke = style->strokeRec(); |
| 297 SkScalar width = stroke.getWidth(); |
294 | 298 |
295 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking | 299 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking |
296 // cases where the RT is fully inside a stroke. | 300 // cases where the RT is fully inside a stroke. |
297 if (width < 0) { | 301 if (width < 0) { |
298 SkRect rtRect; | 302 SkRect rtRect; |
299 fRenderTarget->getBoundsRect(&rtRect); | 303 fRenderTarget->getBoundsRect(&rtRect); |
300 SkRect clipSpaceRTRect = rtRect; | 304 SkRect clipSpaceRTRect = rtRect; |
301 bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); | 305 bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); |
302 if (checkClip) { | 306 if (checkClip) { |
303 clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), | 307 clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), |
(...skipping 26 matching lines...) Expand all Loading... |
330 SkAutoTUnref<GrDrawBatch> batch; | 334 SkAutoTUnref<GrDrawBatch> batch; |
331 if (width < 0) { | 335 if (width < 0) { |
332 batch.reset(this->getFillRectBatch(paint, viewMatrix, rect)); | 336 batch.reset(this->getFillRectBatch(paint, viewMatrix, rect)); |
333 } else { | 337 } else { |
334 GrColor color = paint.getColor(); | 338 GrColor color = paint.getColor(); |
335 | 339 |
336 if (should_apply_coverage_aa(paint, fRenderTarget.get())) { | 340 if (should_apply_coverage_aa(paint, fRenderTarget.get())) { |
337 // The stroke path needs the rect to remain axis aligned (no rotatio
n or skew). | 341 // The stroke path needs the rect to remain axis aligned (no rotatio
n or skew). |
338 if (viewMatrix.rectStaysRect()) { | 342 if (viewMatrix.rectStaysRect()) { |
339 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix
, rect, | 343 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix
, rect, |
340 *strokeInfo)); | 344 stroke)); |
341 } | 345 } |
342 } else { | 346 } else { |
343 // Non-AA hairlines are snapped to pixel centers to make which pixel
s are hit | 347 // Non-AA hairlines are snapped to pixel centers to make which pixel
s are hit |
344 // deterministic | 348 // deterministic |
345 snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisa
mpled()); | 349 snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisa
mpled()); |
346 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix,
rect, | 350 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix,
rect, |
347 width, snapToPixel
Centers)); | 351 width, snapToPixel
Centers)); |
348 | 352 |
349 // Depending on sub-pixel coordinates and the particular GPU, we may
lose a corner of | 353 // Depending on sub-pixel coordinates and the particular GPU, we may
lose a corner of |
350 // hairline rects. We jam all the vertices to pixel centers to avoid
this, but not | 354 // hairline rects. We jam all the vertices to pixel centers to avoid
this, but not |
351 // when MSAA is enabled because it can cause ugly artifacts. | 355 // when MSAA is enabled because it can cause ugly artifacts. |
352 } | 356 } |
353 } | 357 } |
354 | 358 |
355 if (batch) { | 359 if (batch) { |
356 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 360 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
357 | 361 |
358 if (snapToPixelCenters) { | 362 if (snapToPixelCenters) { |
359 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCent
ers_Flag, | 363 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCent
ers_Flag, |
360 snapToPixelCenters); | 364 snapToPixelCenters); |
361 } | 365 } |
362 | 366 |
363 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 367 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
364 return; | 368 return; |
365 } | 369 } |
366 | 370 |
367 SkPath path; | 371 SkPath path; |
368 path.setIsVolatile(true); | 372 path.setIsVolatile(true); |
369 path.addRect(rect); | 373 path.addRect(rect); |
370 this->internalDrawPath(clip, paint, viewMatrix, path, | 374 this->internalDrawPath(clip, paint, viewMatrix, path, *style); |
371 strokeInfo ? *strokeInfo : GrStrokeInfo::FillInfo()); | |
372 } | 375 } |
373 | 376 |
374 bool GrDrawContextPriv::drawAndStencilRect(const SkIRect* scissorRect, | 377 bool GrDrawContextPriv::drawAndStencilRect(const SkIRect* scissorRect, |
375 const GrStencilSettings& ss, | 378 const GrStencilSettings& ss, |
376 SkRegion::Op op, | 379 SkRegion::Op op, |
377 bool invert, | 380 bool invert, |
378 bool doAA, | 381 bool doAA, |
379 const SkMatrix& viewMatrix, | 382 const SkMatrix& viewMatrix, |
380 const SkRect& rect) { | 383 const SkRect& rect) { |
381 ASSERT_SINGLE_OWNER_PRIV | 384 ASSERT_SINGLE_OWNER_PRIV |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 532 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
530 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 533 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
531 } | 534 } |
532 | 535 |
533 /////////////////////////////////////////////////////////////////////////////// | 536 /////////////////////////////////////////////////////////////////////////////// |
534 | 537 |
535 void GrDrawContext::drawRRect(const GrClip& clip, | 538 void GrDrawContext::drawRRect(const GrClip& clip, |
536 const GrPaint& paint, | 539 const GrPaint& paint, |
537 const SkMatrix& viewMatrix, | 540 const SkMatrix& viewMatrix, |
538 const SkRRect& rrect, | 541 const SkRRect& rrect, |
539 const GrStrokeInfo& strokeInfo) { | 542 const GrStyle& style) { |
540 ASSERT_SINGLE_OWNER | 543 ASSERT_SINGLE_OWNER |
541 RETURN_IF_ABANDONED | 544 RETURN_IF_ABANDONED |
542 SkDEBUGCODE(this->validate();) | 545 SkDEBUGCODE(this->validate();) |
543 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); | 546 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); |
544 | 547 |
545 if (rrect.isEmpty()) { | 548 if (rrect.isEmpty()) { |
546 return; | 549 return; |
547 } | 550 } |
548 | 551 |
549 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice | 552 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in
SkGpuDevice |
550 | 553 const SkStrokeRec stroke = style.strokeRec(); |
551 AutoCheckFlush acf(fDrawingManager); | 554 AutoCheckFlush acf(fDrawingManager); |
552 | 555 |
553 if (should_apply_coverage_aa(paint, fRenderTarget.get())) { | 556 if (should_apply_coverage_aa(paint, fRenderTarget.get())) { |
554 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 557 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
555 | 558 |
556 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.g
etColor(), | 559 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.g
etColor(), |
557 viewMat
rix, | 560 viewMat
rix, |
558 rrect, | 561 rrect, |
559 strokeI
nfo, | 562 stroke, |
560 shaderC
aps)); | 563 shaderC
aps)); |
561 if (batch) { | 564 if (batch) { |
562 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 565 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
563 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 566 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
564 return; | 567 return; |
565 } | 568 } |
566 } | 569 } |
567 | 570 |
568 SkPath path; | 571 SkPath path; |
569 path.setIsVolatile(true); | 572 path.setIsVolatile(true); |
570 path.addRRect(rrect); | 573 path.addRRect(rrect); |
571 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); | 574 this->internalDrawPath(clip, paint, viewMatrix, path, style); |
572 } | 575 } |
573 | 576 |
574 bool GrDrawContext::drawFilledDRRect(const GrClip& clip, | 577 bool GrDrawContext::drawFilledDRRect(const GrClip& clip, |
575 const GrPaint& paintIn, | 578 const GrPaint& paintIn, |
576 const SkMatrix& viewMatrix, | 579 const SkMatrix& viewMatrix, |
577 const SkRRect& origOuter, | 580 const SkRRect& origOuter, |
578 const SkRRect& origInner) { | 581 const SkRRect& origInner) { |
579 SkASSERT(!origInner.isEmpty()); | 582 SkASSERT(!origInner.isEmpty()); |
580 SkASSERT(!origOuter.isEmpty()); | 583 SkASSERT(!origOuter.isEmpty()); |
581 | 584 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 return; | 650 return; |
648 } | 651 } |
649 | 652 |
650 SkPath path; | 653 SkPath path; |
651 path.setIsVolatile(true); | 654 path.setIsVolatile(true); |
652 path.addRRect(inner); | 655 path.addRRect(inner); |
653 path.addRRect(outer); | 656 path.addRRect(outer); |
654 path.setFillType(SkPath::kEvenOdd_FillType); | 657 path.setFillType(SkPath::kEvenOdd_FillType); |
655 | 658 |
656 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 659 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
657 this->internalDrawPath(clip, paint, viewMatrix, path, GrStrokeInfo::FillInfo
()); | 660 this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill())
; |
658 } | 661 } |
659 | 662 |
660 /////////////////////////////////////////////////////////////////////////////// | 663 /////////////////////////////////////////////////////////////////////////////// |
661 | 664 |
662 void GrDrawContext::drawOval(const GrClip& clip, | 665 void GrDrawContext::drawOval(const GrClip& clip, |
663 const GrPaint& paint, | 666 const GrPaint& paint, |
664 const SkMatrix& viewMatrix, | 667 const SkMatrix& viewMatrix, |
665 const SkRect& oval, | 668 const SkRect& oval, |
666 const GrStrokeInfo& strokeInfo) { | 669 const GrStyle& style) { |
667 ASSERT_SINGLE_OWNER | 670 ASSERT_SINGLE_OWNER |
668 RETURN_IF_ABANDONED | 671 RETURN_IF_ABANDONED |
669 SkDEBUGCODE(this->validate();) | 672 SkDEBUGCODE(this->validate();) |
670 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval"); | 673 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval"); |
671 | 674 |
672 if (oval.isEmpty()) { | 675 if (oval.isEmpty()) { |
673 return; | 676 return; |
674 } | 677 } |
675 | 678 |
676 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice | 679 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in
SkGpuDevice |
677 | 680 |
678 AutoCheckFlush acf(fDrawingManager); | 681 AutoCheckFlush acf(fDrawingManager); |
679 | 682 const SkStrokeRec& stroke = style.strokeRec(); |
680 if (should_apply_coverage_aa(paint, fRenderTarget.get())) { | 683 if (should_apply_coverage_aa(paint, fRenderTarget.get())) { |
681 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 684 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
682 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.ge
tColor(), | 685 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.ge
tColor(), |
683 viewMatr
ix, | 686 viewMatr
ix, |
684 oval, | 687 oval, |
685 strokeIn
fo, | 688 stroke, |
686 shaderCa
ps)); | 689 shaderCa
ps)); |
687 if (batch) { | 690 if (batch) { |
688 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 691 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
689 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 692 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
690 return; | 693 return; |
691 } | 694 } |
692 } | 695 } |
693 | 696 |
694 SkPath path; | 697 SkPath path; |
695 path.setIsVolatile(true); | 698 path.setIsVolatile(true); |
696 path.addOval(oval); | 699 path.addOval(oval); |
697 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); | 700 this->internalDrawPath(clip, paint, viewMatrix, path, style); |
698 } | 701 } |
699 | 702 |
700 void GrDrawContext::drawImageNine(const GrClip& clip, | 703 void GrDrawContext::drawImageNine(const GrClip& clip, |
701 const GrPaint& paint, | 704 const GrPaint& paint, |
702 const SkMatrix& viewMatrix, | 705 const SkMatrix& viewMatrix, |
703 int imageWidth, | 706 int imageWidth, |
704 int imageHeight, | 707 int imageHeight, |
705 const SkIRect& center, | 708 const SkIRect& center, |
706 const SkRect& dst) { | 709 const SkRect& dst) { |
707 ASSERT_SINGLE_OWNER | 710 ASSERT_SINGLE_OWNER |
708 RETURN_IF_ABANDONED | 711 RETURN_IF_ABANDONED |
709 SkDEBUGCODE(this->validate();) | 712 SkDEBUGCODE(this->validate();) |
710 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawImageNine"); | 713 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawImageNine"); |
711 | 714 |
712 AutoCheckFlush acf(fDrawingManager); | 715 AutoCheckFlush acf(fDrawingManager); |
713 | 716 |
714 SkAutoTUnref<GrDrawBatch> batch(GrNinePatch::CreateNonAA(paint.getColor(), v
iewMatrix, | 717 SkAutoTUnref<GrDrawBatch> batch(GrNinePatch::CreateNonAA(paint.getColor(), v
iewMatrix, |
715 imageWidth, imageHe
ight, | 718 imageWidth, imageHe
ight, |
716 center, dst)); | 719 center, dst)); |
717 | 720 |
718 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 721 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
719 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 722 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
720 } | 723 } |
721 | 724 |
722 | 725 |
723 // Can 'path' be drawn as a pair of filled nested rectangles? | 726 // Can 'path' be drawn as a pair of filled nested rectangles? |
724 static bool is_nested_rects(const SkMatrix& viewMatrix, | 727 static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path
, SkRect rects[2]) { |
725 const SkPath& path, | |
726 const SkStrokeRec& stroke, | |
727 SkRect rects[2]) { | |
728 SkASSERT(stroke.isFillStyle()); | |
729 | 728 |
730 if (path.isInverseFillType()) { | 729 if (path.isInverseFillType()) { |
731 return false; | 730 return false; |
732 } | 731 } |
733 | 732 |
734 // TODO: this restriction could be lifted if we were willing to apply | 733 // TODO: this restriction could be lifted if we were willing to apply |
735 // the matrix to all the points individually rather than just to the rect | 734 // the matrix to all the points individually rather than just to the rect |
736 if (!viewMatrix.rectStaysRect()) { | 735 if (!viewMatrix.rectStaysRect()) { |
737 return false; | 736 return false; |
738 } | 737 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 | 791 |
793 AutoCheckFlush acf(fDrawingManager); | 792 AutoCheckFlush acf(fDrawingManager); |
794 | 793 |
795 this->getDrawTarget()->drawPathBatch(pipelineBuilder, batch); | 794 this->getDrawTarget()->drawPathBatch(pipelineBuilder, batch); |
796 } | 795 } |
797 | 796 |
798 void GrDrawContext::drawPath(const GrClip& clip, | 797 void GrDrawContext::drawPath(const GrClip& clip, |
799 const GrPaint& paint, | 798 const GrPaint& paint, |
800 const SkMatrix& viewMatrix, | 799 const SkMatrix& viewMatrix, |
801 const SkPath& path, | 800 const SkPath& path, |
802 const GrStrokeInfo& strokeInfo) { | 801 const GrStyle& style) { |
803 ASSERT_SINGLE_OWNER | 802 ASSERT_SINGLE_OWNER |
804 RETURN_IF_ABANDONED | 803 RETURN_IF_ABANDONED |
805 SkDEBUGCODE(this->validate();) | 804 SkDEBUGCODE(this->validate();) |
806 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); | 805 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); |
807 | 806 |
808 if (path.isEmpty()) { | 807 if (path.isEmpty()) { |
809 if (path.isInverseFillType()) { | 808 if (path.isInverseFillType()) { |
810 this->drawPaint(clip, paint, viewMatrix); | 809 this->drawPaint(clip, paint, viewMatrix); |
811 } | 810 } |
812 return; | 811 return; |
813 } | 812 } |
814 | 813 |
815 AutoCheckFlush acf(fDrawingManager); | 814 AutoCheckFlush acf(fDrawingManager); |
816 | 815 |
817 if (should_apply_coverage_aa(paint, fRenderTarget.get()) && !strokeInfo.isDa
shed()) { | 816 if (should_apply_coverage_aa(paint, fRenderTarget.get()) && !style.pathEffec
t()) { |
818 if (strokeInfo.getWidth() < 0 && !path.isConvex()) { | 817 if (style.isSimpleFill() && !path.isConvex()) { |
819 // Concave AA paths are expensive - try to avoid them for special ca
ses | 818 // Concave AA paths are expensive - try to avoid them for special ca
ses |
820 SkRect rects[2]; | 819 SkRect rects[2]; |
821 | 820 |
822 if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) { | 821 if (fills_as_nested_rects(viewMatrix, path, rects)) { |
823 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill
NestedRects( | 822 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill
NestedRects( |
824 paint.getColor(), viewMatrix, rects)); | 823 paint.getColor(), viewMatrix, rects)); |
825 if (batch) { | 824 if (batch) { |
826 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get()
, clip); | 825 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get()
, clip); |
827 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 826 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
828 } | 827 } |
829 return; | 828 return; |
830 } | 829 } |
831 } | 830 } |
832 SkRect ovalRect; | 831 SkRect ovalRect; |
833 bool isOval = path.isOval(&ovalRect); | 832 bool isOval = path.isOval(&ovalRect); |
834 | 833 |
835 if (isOval && !path.isInverseFillType()) { | 834 if (isOval && !path.isInverseFillType()) { |
836 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 835 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
837 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(pain
t.getColor(), | 836 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(pain
t.getColor(), |
838 view
Matrix, | 837 view
Matrix, |
839 oval
Rect, | 838 oval
Rect, |
840 stro
keInfo, | 839 styl
e.strokeRec(), |
841 shad
erCaps)); | 840 shad
erCaps)); |
842 if (batch) { | 841 if (batch) { |
843 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), cl
ip); | 842 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), cl
ip); |
844 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 843 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
845 return; | 844 return; |
846 } | 845 } |
847 } | 846 } |
848 } | 847 } |
849 | 848 |
850 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. | 849 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. |
851 // Scratch textures can be recycled after they are returned to the texture | 850 // Scratch textures can be recycled after they are returned to the texture |
852 // cache. This presents a potential hazard for buffered drawing. However, | 851 // cache. This presents a potential hazard for buffered drawing. However, |
853 // the writePixels that uploads to the scratch will perform a flush so we're | 852 // the writePixels that uploads to the scratch will perform a flush so we're |
854 // OK. | 853 // OK. |
855 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); | 854 this->internalDrawPath(clip, paint, viewMatrix, path, style); |
856 } | 855 } |
857 | 856 |
858 bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect, | 857 bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect, |
859 const GrStencilSettings& ss, | 858 const GrStencilSettings& ss, |
860 SkRegion::Op op, | 859 SkRegion::Op op, |
861 bool invert, | 860 bool invert, |
862 bool doAA, | 861 bool doAA, |
863 const SkMatrix& viewMatrix, | 862 const SkMatrix& viewMatrix, |
864 const SkPath& path) { | 863 const SkPath& path) { |
865 ASSERT_SINGLE_OWNER_PRIV | 864 ASSERT_SINGLE_OWNER_PRIV |
(...skipping 19 matching lines...) Expand all Loading... |
885 bool isStencilBufferMSAA = fDrawContext->fRenderTarget->isStencilBufferMulti
sampled(); | 884 bool isStencilBufferMSAA = fDrawContext->fRenderTarget->isStencilBufferMulti
sampled(); |
886 | 885 |
887 const GrPathRendererChain::DrawType type = | 886 const GrPathRendererChain::DrawType type = |
888 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType | 887 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType |
889 : GrPathRendererChain::kColor_DrawType; | 888 : GrPathRendererChain::kColor_DrawType; |
890 | 889 |
891 GrPathRenderer::CanDrawPathArgs canDrawArgs; | 890 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
892 canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps(
)->shaderCaps(); | 891 canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps(
)->shaderCaps(); |
893 canDrawArgs.fViewMatrix = &viewMatrix; | 892 canDrawArgs.fViewMatrix = &viewMatrix; |
894 canDrawArgs.fPath = &path; | 893 canDrawArgs.fPath = &path; |
895 canDrawArgs.fStroke = &GrStrokeInfo::FillInfo(); | 894 canDrawArgs.fStyle = &GrStyle::SimpleFill(); |
896 canDrawArgs.fAntiAlias = useCoverageAA; | 895 canDrawArgs.fAntiAlias = useCoverageAA; |
897 canDrawArgs.fIsStencilDisabled = isStencilDisabled; | 896 canDrawArgs.fIsStencilDisabled = isStencilDisabled; |
898 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; | 897 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; |
899 | 898 |
900 // Don't allow the SW renderer | 899 // Don't allow the SW renderer |
901 GrPathRenderer* pr = fDrawContext->fDrawingManager->getPathRenderer(canDrawA
rgs, false, type); | 900 GrPathRenderer* pr = fDrawContext->fDrawingManager->getPathRenderer(canDrawA
rgs, false, type); |
902 if (!pr) { | 901 if (!pr) { |
903 return false; | 902 return false; |
904 } | 903 } |
905 | 904 |
(...skipping 10 matching lines...) Expand all Loading... |
916 GrPipelineBuilder pipelineBuilder(paint, fDrawContext->accessRenderTarget(),
clip); | 915 GrPipelineBuilder pipelineBuilder(paint, fDrawContext->accessRenderTarget(),
clip); |
917 pipelineBuilder.setStencil(ss); | 916 pipelineBuilder.setStencil(ss); |
918 | 917 |
919 GrPathRenderer::DrawPathArgs args; | 918 GrPathRenderer::DrawPathArgs args; |
920 args.fTarget = fDrawContext->getDrawTarget(); | 919 args.fTarget = fDrawContext->getDrawTarget(); |
921 args.fResourceProvider = fDrawContext->fDrawingManager->getContext()->resour
ceProvider(); | 920 args.fResourceProvider = fDrawContext->fDrawingManager->getContext()->resour
ceProvider(); |
922 args.fPipelineBuilder = &pipelineBuilder; | 921 args.fPipelineBuilder = &pipelineBuilder; |
923 args.fColor = GrColor_WHITE; | 922 args.fColor = GrColor_WHITE; |
924 args.fViewMatrix = &viewMatrix; | 923 args.fViewMatrix = &viewMatrix; |
925 args.fPath = &path; | 924 args.fPath = &path; |
926 args.fStroke = &GrStrokeInfo::FillInfo(); | 925 args.fStyle = &GrStyle::SimpleFill(); |
927 args.fAntiAlias = useCoverageAA; | 926 args.fAntiAlias = useCoverageAA; |
928 args.fGammaCorrect = fDrawContext->isGammaCorrect(); | 927 args.fGammaCorrect = fDrawContext->isGammaCorrect(); |
929 pr->drawPath(args); | 928 pr->drawPath(args); |
930 return true; | 929 return true; |
931 } | 930 } |
932 | 931 |
933 void GrDrawContext::internalDrawPath(const GrClip& clip, | 932 void GrDrawContext::internalDrawPath(const GrClip& clip, |
934 const GrPaint& paint, | 933 const GrPaint& paint, |
935 const SkMatrix& viewMatrix, | 934 const SkMatrix& viewMatrix, |
936 const SkPath& path, | 935 const SkPath& origPath, |
937 const GrStrokeInfo& strokeInfo) { | 936 const GrStyle& origStyle) { |
938 ASSERT_SINGLE_OWNER | 937 ASSERT_SINGLE_OWNER |
939 RETURN_IF_ABANDONED | 938 RETURN_IF_ABANDONED |
940 SkASSERT(!path.isEmpty()); | 939 SkASSERT(!origPath.isEmpty()); |
941 | 940 |
942 // An Assumption here is that path renderer would use some form of tweaking | |
943 // the src color (either the input alpha or in the frag shader) to implement | |
944 // aa. If we have some future driver-mojo path AA that can do the right | |
945 // thing WRT to the blend then we'll need some query on the PR. | |
946 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get()); | 941 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get()); |
947 const bool isStencilDisabled = true; | 942 const bool isStencilDisabled = true; |
948 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); | 943 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); |
949 | 944 |
950 const GrPathRendererChain::DrawType type = | 945 const GrPathRendererChain::DrawType type = |
951 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType | 946 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType |
952 : GrPathRendererChain::kColor_DrawType; | 947 : GrPathRendererChain::kColor_DrawType; |
953 | 948 |
954 const SkPath* pathPtr = &path; | |
955 SkTLazy<SkPath> tmpPath; | 949 SkTLazy<SkPath> tmpPath; |
956 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; | 950 SkTLazy<GrStyle> tmpStyle; |
957 | 951 |
958 GrPathRenderer::CanDrawPathArgs canDrawArgs; | 952 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
959 canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps(
); | 953 canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps(
); |
960 canDrawArgs.fViewMatrix = &viewMatrix; | 954 canDrawArgs.fViewMatrix = &viewMatrix; |
961 canDrawArgs.fPath = pathPtr; | 955 canDrawArgs.fPath = &origPath; |
962 canDrawArgs.fStroke = strokeInfoPtr; | 956 canDrawArgs.fStyle = &origStyle; |
963 canDrawArgs.fAntiAlias = useCoverageAA; | 957 canDrawArgs.fAntiAlias = useCoverageAA; |
964 canDrawArgs.fIsStencilDisabled = isStencilDisabled; | 958 canDrawArgs.fIsStencilDisabled = isStencilDisabled; |
965 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; | 959 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; |
966 | 960 |
967 // Try a 1st time without stroking the path and without allowing the SW rend
erer | 961 // Try a 1st time without applying any of the style to the geometry (and bar
ring sw) |
968 GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, ty
pe); | 962 GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, ty
pe); |
| 963 SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix); |
969 | 964 |
970 GrStrokeInfo dashlessStrokeInfo(strokeInfo, false); | 965 if (!pr && canDrawArgs.fStyle->pathEffect()) { |
971 if (nullptr == pr && strokeInfo.isDashed()) { | 966 // It didn't work above, so try again with the path effect applied. |
972 // It didn't work above, so try again with dashed stroke converted to a
dashless stroke. | 967 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); |
973 if (!strokeInfo.applyDashToPath(tmpPath.init(), &dashlessStrokeInfo, *pa
thPtr)) { | 968 if (!canDrawArgs.fStyle->applyPathEffectToPath(tmpPath.init(), &rec, *ca
nDrawArgs.fPath, |
| 969 styleScale)) { |
| 970 GrStyle noPathEffect(canDrawArgs.fStyle->strokeRec(), nullptr); |
| 971 this->internalDrawPath(clip, paint, viewMatrix, *canDrawArgs.fPath,
noPathEffect); |
974 return; | 972 return; |
975 } | 973 } |
976 pathPtr = tmpPath.get(); | 974 tmpStyle.init(rec, nullptr); |
977 if (pathPtr->isEmpty()) { | 975 canDrawArgs.fPath = tmpPath.get(); |
| 976 canDrawArgs.fStyle = tmpStyle.get(); |
| 977 if (canDrawArgs.fPath->isEmpty()) { |
978 return; | 978 return; |
979 } | 979 } |
980 strokeInfoPtr = &dashlessStrokeInfo; | |
981 | |
982 canDrawArgs.fPath = pathPtr; | |
983 canDrawArgs.fStroke = strokeInfoPtr; | |
984 | 980 |
985 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type); | 981 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type); |
986 } | 982 } |
987 | 983 if (!pr) { |
988 if (nullptr == pr) { | 984 SkASSERT(!canDrawArgs.fStyle->pathEffect()); |
989 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMa
trix, nullptr) && | 985 if (canDrawArgs.fStyle->strokeRec().needToApply()) { |
990 !strokeInfoPtr->isFillStyle()) { | |
991 // It didn't work above, so try again with stroke converted to a fil
l. | |
992 if (!tmpPath.isValid()) { | 986 if (!tmpPath.isValid()) { |
993 tmpPath.init(); | 987 tmpPath.init(); |
994 } | 988 } |
995 dashlessStrokeInfo.setResScale(SkScalarAbs(viewMatrix.getMaxScale())
); | 989 // It didn't work above, so try again by applying the stroke to the
geometry. |
996 if (!dashlessStrokeInfo.applyToPath(tmpPath.get(), *pathPtr)) { | 990 SkStrokeRec::InitStyle fillOrHairline; |
| 991 if (!canDrawArgs.fStyle->applyToPath(tmpPath.get(), &fillOrHairline, |
| 992 *canDrawArgs.fPath, styleScale)
) { |
997 return; | 993 return; |
998 } | 994 } |
999 pathPtr = tmpPath.get(); | 995 if (!tmpStyle.isValid()) { |
1000 if (pathPtr->isEmpty()) { | 996 tmpStyle.init(fillOrHairline); |
| 997 } else { |
| 998 tmpStyle.get()->resetToInitStyle(fillOrHairline); |
| 999 } |
| 1000 canDrawArgs.fPath = tmpPath.get(); |
| 1001 canDrawArgs.fStyle = tmpStyle.get(); |
| 1002 if (canDrawArgs.fPath->isEmpty()) { |
1001 return; | 1003 return; |
1002 } | 1004 } |
1003 dashlessStrokeInfo.setFillStyle(); | 1005 |
1004 strokeInfoPtr = &dashlessStrokeInfo; | 1006 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type); |
1005 } | 1007 } |
1006 | 1008 |
1007 canDrawArgs.fPath = pathPtr; | |
1008 canDrawArgs.fStroke = strokeInfoPtr; | |
1009 | |
1010 // This time, allow SW renderer | 1009 // This time, allow SW renderer |
1011 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); | 1010 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); |
1012 } | 1011 } |
1013 | 1012 |
1014 if (nullptr == pr) { | 1013 if (nullptr == pr) { |
1015 #ifdef SK_DEBUG | 1014 #ifdef SK_DEBUG |
1016 SkDebugf("Unable to find path renderer compatible with path.\n"); | 1015 SkDebugf("Unable to find path renderer compatible with path.\n"); |
1017 #endif | 1016 #endif |
1018 return; | 1017 return; |
1019 } | 1018 } |
1020 | 1019 |
1021 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); | 1020 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip); |
1022 | 1021 |
1023 GrPathRenderer::DrawPathArgs args; | 1022 GrPathRenderer::DrawPathArgs args; |
1024 args.fTarget = this->getDrawTarget(); | 1023 args.fTarget = this->getDrawTarget(); |
1025 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); | 1024 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); |
1026 args.fPipelineBuilder = &pipelineBuilder; | 1025 args.fPipelineBuilder = &pipelineBuilder; |
1027 args.fColor = paint.getColor(); | 1026 args.fColor = paint.getColor(); |
1028 args.fViewMatrix = &viewMatrix; | 1027 args.fViewMatrix = &viewMatrix; |
1029 args.fPath = pathPtr; | 1028 args.fPath = canDrawArgs.fPath; |
1030 args.fStroke = strokeInfoPtr; | 1029 args.fStyle = canDrawArgs.fStyle; |
1031 args.fAntiAlias = useCoverageAA; | 1030 args.fAntiAlias = useCoverageAA; |
1032 args.fGammaCorrect = this->isGammaCorrect(); | 1031 args.fGammaCorrect = this->isGammaCorrect(); |
1033 pr->drawPath(args); | 1032 pr->drawPath(args); |
1034 } | 1033 } |
1035 | 1034 |
1036 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { | 1035 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { |
1037 ASSERT_SINGLE_OWNER | 1036 ASSERT_SINGLE_OWNER |
1038 RETURN_IF_ABANDONED | 1037 RETURN_IF_ABANDONED |
1039 SkDEBUGCODE(this->validate();) | 1038 SkDEBUGCODE(this->validate();) |
1040 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); | 1039 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); |
1041 | 1040 |
1042 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); | 1041 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); |
1043 } | 1042 } |
OLD | NEW |