OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrDashingEffect.h" | 8 #include "GrDashingEffect.h" |
9 | 9 |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "gl/GrGLProcessor.h" | 24 #include "gl/GrGLProcessor.h" |
25 #include "gl/GrGLSL.h" | 25 #include "gl/GrGLSL.h" |
26 #include "gl/builders/GrGLProgramBuilder.h" | 26 #include "gl/builders/GrGLProgramBuilder.h" |
27 | 27 |
28 /////////////////////////////////////////////////////////////////////////////// | 28 /////////////////////////////////////////////////////////////////////////////// |
29 | 29 |
30 // Returns whether or not the gpu can fast path the dash line effect. | 30 // Returns whether or not the gpu can fast path the dash line effect. |
31 static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI nfo, | 31 static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeI nfo, |
32 const GrDrawTarget& target, const GrPipelineBuild er& pipelineBuilder, | 32 const GrDrawTarget& target, const GrPipelineBuild er& pipelineBuilder, |
33 const SkMatrix& viewMatrix) { | 33 const SkMatrix& viewMatrix) { |
34 if (pipelineBuilder.getRenderTarget()->isMultisampled()) { | |
35 return false; | |
36 } | |
37 | |
38 // Pts must be either horizontal or vertical in src space | 34 // Pts must be either horizontal or vertical in src space |
39 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { | 35 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { |
40 return false; | 36 return false; |
41 } | 37 } |
42 | 38 |
43 // May be able to relax this to include skew. As of now cannot do perspectiv e | 39 // May be able to relax this to include skew. As of now cannot do perspectiv e |
44 // because of the non uniform scaling of bloating a rect | 40 // because of the non uniform scaling of bloating a rect |
45 if (!viewMatrix.preservesRightAngles()) { | 41 if (!viewMatrix.preservesRightAngles()) { |
46 return false; | 42 return false; |
47 } | 43 } |
(...skipping 23 matching lines...) Expand all Loading... | |
71 SkScalar fIntervalLength; | 67 SkScalar fIntervalLength; |
72 SkRect fRect; | 68 SkRect fRect; |
73 }; | 69 }; |
74 struct DashCircleVertex { | 70 struct DashCircleVertex { |
75 SkPoint fPos; | 71 SkPoint fPos; |
76 SkPoint fDashPos; | 72 SkPoint fDashPos; |
77 SkScalar fIntervalLength; | 73 SkScalar fIntervalLength; |
78 SkScalar fRadius; | 74 SkScalar fRadius; |
79 SkScalar fCenterX; | 75 SkScalar fCenterX; |
80 }; | 76 }; |
77 | |
78 enum DashAAMode { | |
79 kBW_DashAAMode, | |
80 kEdgeAA_DashAAMode, | |
81 kMSAA_DashAAMode, | |
82 | |
83 kDashAAModeCnt = 3, | |
84 }; | |
81 }; | 85 }; |
82 | 86 |
83 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, | 87 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, |
84 const SkMatrix& viewMatrix, const SkPoint pts[2]) { | 88 const SkMatrix& viewMatrix, const SkPoint pts[2]) { |
85 SkVector vecSrc = pts[1] - pts[0]; | 89 SkVector vecSrc = pts[1] - pts[0]; |
86 SkScalar magSrc = vecSrc.length(); | 90 SkScalar magSrc = vecSrc.length(); |
87 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; | 91 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; |
88 vecSrc.scale(invSrc); | 92 vecSrc.scale(invSrc); |
89 | 93 |
90 SkVector vecSrcPerp; | 94 SkVector vecSrcPerp; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 } | 231 } |
228 | 232 |
229 | 233 |
230 /** | 234 /** |
231 * An GrGeometryProcessor that renders a dashed line. | 235 * An GrGeometryProcessor that renders a dashed line. |
232 * This GrGeometryProcessor is meant for dashed lines that only have a single on /off interval pair. | 236 * This GrGeometryProcessor is meant for dashed lines that only have a single on /off interval pair. |
233 * Bounding geometry is rendered and the effect computes coverage based on the f ragment's | 237 * Bounding geometry is rendered and the effect computes coverage based on the f ragment's |
234 * position relative to the dashed line. | 238 * position relative to the dashed line. |
235 */ | 239 */ |
236 static GrGeometryProcessor* create_dash_gp(GrColor, | 240 static GrGeometryProcessor* create_dash_gp(GrColor, |
237 GrPrimitiveEdgeType edgeType, | 241 DashAAMode aaMode, |
238 DashCap cap, | 242 DashCap cap, |
239 const SkMatrix& localMatrix); | 243 const SkMatrix& localMatrix); |
240 | 244 |
241 class DashBatch : public GrBatch { | 245 class DashBatch : public GrBatch { |
242 public: | 246 public: |
243 struct Geometry { | 247 struct Geometry { |
244 GrColor fColor; | 248 GrColor fColor; |
245 SkMatrix fViewMatrix; | 249 SkMatrix fViewMatrix; |
246 SkMatrix fSrcRotInv; | 250 SkMatrix fSrcRotInv; |
247 SkPoint fPtsRot[2]; | 251 SkPoint fPtsRot[2]; |
248 SkScalar fSrcStrokeWidth; | 252 SkScalar fSrcStrokeWidth; |
249 SkScalar fPhase; | 253 SkScalar fPhase; |
250 SkScalar fIntervals[2]; | 254 SkScalar fIntervals[2]; |
251 SkScalar fParallelScale; | 255 SkScalar fParallelScale; |
252 SkScalar fPerpendicularScale; | 256 SkScalar fPerpendicularScale; |
253 SkDEBUGCODE(SkRect fDevBounds;) | 257 SkDEBUGCODE(SkRect fDevBounds;) |
254 }; | 258 }; |
255 | 259 |
256 static GrBatch* Create(const Geometry& geometry, SkPaint::Cap cap, bool useA A, bool fullDash) { | 260 static GrBatch* Create(const Geometry& geometry, SkPaint::Cap cap, DashAAMod e aaMode, bool fullDash) { |
257 return SkNEW_ARGS(DashBatch, (geometry, cap, useAA, fullDash)); | 261 return SkNEW_ARGS(DashBatch, (geometry, cap, aaMode, fullDash)); |
258 } | 262 } |
259 | 263 |
260 const char* name() const override { return "DashBatch"; } | 264 const char* name() const override { return "DashBatch"; } |
261 | 265 |
262 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 266 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
263 // When this is called on a batch, there is only one geometry bundle | 267 // When this is called on a batch, there is only one geometry bundle |
264 out->setKnownFourComponents(fGeoData[0].fColor); | 268 out->setKnownFourComponents(fGeoData[0].fColor); |
265 } | 269 } |
266 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 270 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
267 out->setUnknownSingleComponent(); | 271 out->setUnknownSingleComponent(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 return; | 306 return; |
303 } | 307 } |
304 | 308 |
305 SkPaint::Cap cap = this->cap(); | 309 SkPaint::Cap cap = this->cap(); |
306 | 310 |
307 SkAutoTUnref<const GrGeometryProcessor> gp; | 311 SkAutoTUnref<const GrGeometryProcessor> gp; |
308 | 312 |
309 bool isRoundCap = SkPaint::kRound_Cap == cap; | 313 bool isRoundCap = SkPaint::kRound_Cap == cap; |
310 DashCap capType = isRoundCap ? kRound_DashCap : kNonRound_DashCap; | 314 DashCap capType = isRoundCap ? kRound_DashCap : kNonRound_DashCap; |
311 if (this->fullDash()) { | 315 if (this->fullDash()) { |
312 GrPrimitiveEdgeType edgeType = this->useAA() ? kFillAA_GrProcessorEd geType : | 316 gp.reset(create_dash_gp(this->color(), this->aaMode(), capType, inve rt)); |
313 kFillBW_GrProcessorEd geType; | |
314 gp.reset(create_dash_gp(this->color(), edgeType, capType, invert)); | |
315 } else { | 317 } else { |
316 // Set up the vertex data for the line and start/end dashes | 318 // Set up the vertex data for the line and start/end dashes |
317 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kP osition_GPType, | 319 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kP osition_GPType, |
318 this->color(), | 320 this->color(), |
319 SkMatrix::I(), | 321 SkMatrix::I(), |
320 invert)); | 322 invert)); |
321 } | 323 } |
322 | 324 |
323 batchTarget->initDraw(gp, pipeline); | 325 batchTarget->initDraw(gp, pipeline); |
324 | 326 |
325 // TODO remove this when batch is everywhere | 327 // TODO remove this when batch is everywhere |
326 GrPipelineInfo init; | 328 GrPipelineInfo init; |
327 init.fColorIgnored = fBatch.fColorIgnored; | 329 init.fColorIgnored = fBatch.fColorIgnored; |
328 init.fOverrideColor = GrColor_ILLEGAL; | 330 init.fOverrideColor = GrColor_ILLEGAL; |
329 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 331 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
330 init.fUsesLocalCoords = this->usesLocalCoords(); | 332 init.fUsesLocalCoords = this->usesLocalCoords(); |
331 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 333 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
332 | 334 |
333 bool useAA = this->useAA(); | 335 // useAA here means Edge AA or MSAA |
336 bool useAA = this->aaMode() != kBW_DashAAMode; | |
334 bool fullDash = this->fullDash(); | 337 bool fullDash = this->fullDash(); |
335 | 338 |
336 // We do two passes over all of the dashes. First we setup the start, e nd, and bounds, | 339 // We do two passes over all of the dashes. First we setup the start, e nd, and bounds, |
337 // rectangles. We preserve all of this work in the rects / draws arrays below. Then we | 340 // rectangles. We preserve all of this work in the rects / draws arrays below. Then we |
338 // iterate again over these decomposed dashes to generate vertices | 341 // iterate again over these decomposed dashes to generate vertices |
339 SkSTArray<128, SkRect, true> rects; | 342 SkSTArray<128, SkRect, true> rects; |
340 SkSTArray<128, DashDraw, true> draws; | 343 SkSTArray<128, DashDraw, true> draws; |
341 | 344 |
342 int totalRectCount = 0; | 345 int totalRectCount = 0; |
343 int rectOffset = 0; | 346 int rectOffset = 0; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
437 args.fPhase = 0; | 440 args.fPhase = 0; |
438 } | 441 } |
439 | 442 |
440 // Change the dashing info from src space into device space | 443 // Change the dashing info from src space into device space |
441 SkScalar* devIntervals = args.fIntervals; | 444 SkScalar* devIntervals = args.fIntervals; |
442 devIntervals[0] = args.fIntervals[0] * args.fParallelScale; | 445 devIntervals[0] = args.fIntervals[0] * args.fParallelScale; |
443 devIntervals[1] = args.fIntervals[1] * args.fParallelScale; | 446 devIntervals[1] = args.fIntervals[1] * args.fParallelScale; |
444 SkScalar devPhase = args.fPhase * args.fParallelScale; | 447 SkScalar devPhase = args.fPhase * args.fParallelScale; |
445 SkScalar strokeWidth = args.fSrcStrokeWidth * args.fPerpendicularSca le; | 448 SkScalar strokeWidth = args.fSrcStrokeWidth * args.fPerpendicularSca le; |
446 | 449 |
447 if ((strokeWidth < 1.f && !useAA) || 0.f == strokeWidth) { | 450 if ((strokeWidth < 1.f && useAA) || 0.f == strokeWidth) { |
448 strokeWidth = 1.f; | 451 strokeWidth = 1.f; |
449 } | 452 } |
450 | 453 |
451 SkScalar halfDevStroke = strokeWidth * 0.5f; | 454 SkScalar halfDevStroke = strokeWidth * 0.5f; |
452 | 455 |
453 if (SkPaint::kSquare_Cap == cap && 0 != args.fSrcStrokeWidth) { | 456 if (SkPaint::kSquare_Cap == cap && 0 != args.fSrcStrokeWidth) { |
454 // add cap to on interval and remove from off interval | 457 // add cap to on interval and remove from off interval |
455 devIntervals[0] += strokeWidth; | 458 devIntervals[0] += strokeWidth; |
456 devIntervals[1] -= strokeWidth; | 459 devIntervals[1] -= strokeWidth; |
457 } | 460 } |
458 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; | 461 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase; |
459 | 462 |
460 SkScalar bloatX = useAA ? 0.5f / args.fParallelScale : 0.f; | 463 SkScalar devBloat = this->aaMode() == kEdgeAA_DashAAMode ? 0.5f : 0. 0f; |
461 SkScalar bloatY = useAA ? 0.5f / args.fPerpendicularScale : 0.f; | |
462 | 464 |
463 SkScalar devBloat = useAA ? 0.5f : 0.f; | 465 SkScalar bloatX = devBloat / args.fParallelScale; |
466 SkScalar bloatY = devBloat / args.fPerpendicularScale; | |
464 | 467 |
465 if (devIntervals[1] <= 0.f && useAA) { | 468 if (devIntervals[1] <= 0.f && useAA) { |
466 // Case when we end up drawing a solid AA rect | 469 // Case when we end up drawing a solid AA rect |
467 // Reset the start rect to draw this single solid rect | 470 // Reset the start rect to draw this single solid rect |
468 // but it requires to upload a new intervals uniform so we can m imic | 471 // but it requires to upload a new intervals uniform so we can m imic |
469 // one giant dash | 472 // one giant dash |
470 args.fPtsRot[0].fX -= hasStartRect ? startAdj : 0; | 473 args.fPtsRot[0].fX -= hasStartRect ? startAdj : 0; |
471 args.fPtsRot[1].fX += hasEndRect ? endAdj : 0; | 474 args.fPtsRot[1].fX += hasEndRect ? endAdj : 0; |
472 startRect.set(args.fPtsRot, 2); | 475 startRect.set(args.fPtsRot, 2); |
473 startRect.outset(strokeAdj, halfSrcStroke); | 476 startRect.outset(strokeAdj, halfSrcStroke); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
617 batchTarget->draw(drawInfo); | 620 batchTarget->draw(drawInfo); |
618 | 621 |
619 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun t()); | 622 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun t()); |
620 totalRectCount -= drawInfo.instanceCount(); | 623 totalRectCount -= drawInfo.instanceCount(); |
621 } | 624 } |
622 } | 625 } |
623 | 626 |
624 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 627 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
625 | 628 |
626 private: | 629 private: |
627 DashBatch(const Geometry& geometry, SkPaint::Cap cap, bool useAA, bool fullD ash) { | 630 DashBatch(const Geometry& geometry, SkPaint::Cap cap, DashAAMode aaMode, boo l fullDash) { |
628 this->initClassID<DashBatch>(); | 631 this->initClassID<DashBatch>(); |
629 fGeoData.push_back(geometry); | 632 fGeoData.push_back(geometry); |
630 | 633 |
631 fBatch.fUseAA = useAA; | 634 fBatch.fAAMode = aaMode; |
632 fBatch.fCap = cap; | 635 fBatch.fCap = cap; |
633 fBatch.fFullDash = fullDash; | 636 fBatch.fFullDash = fullDash; |
634 } | 637 } |
635 | 638 |
636 bool onCombineIfPossible(GrBatch* t) override { | 639 bool onCombineIfPossible(GrBatch* t) override { |
637 DashBatch* that = t->cast<DashBatch>(); | 640 DashBatch* that = t->cast<DashBatch>(); |
638 | 641 |
639 if (this->useAA() != that->useAA()) { | 642 if (this->aaMode() != that->aaMode()) { |
640 return false; | 643 return false; |
641 } | 644 } |
642 | 645 |
643 if (this->fullDash() != that->fullDash()) { | 646 if (this->fullDash() != that->fullDash()) { |
644 return false; | 647 return false; |
645 } | 648 } |
646 | 649 |
647 if (this->cap() != that->cap()) { | 650 if (this->cap() != that->cap()) { |
648 return false; | 651 return false; |
649 } | 652 } |
650 | 653 |
651 // TODO vertex color | 654 // TODO vertex color |
652 if (this->color() != that->color()) { | 655 if (this->color() != that->color()) { |
653 return false; | 656 return false; |
654 } | 657 } |
655 | 658 |
656 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | 659 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
657 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi ewMatrix())) { | 660 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi ewMatrix())) { |
658 return false; | 661 return false; |
659 } | 662 } |
660 | 663 |
661 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; | 664 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; |
662 return true; | 665 return true; |
663 } | 666 } |
664 | 667 |
665 GrColor color() const { return fBatch.fColor; } | 668 GrColor color() const { return fBatch.fColor; } |
666 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 669 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
667 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 670 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
668 bool useAA() const { return fBatch.fUseAA; } | 671 DashAAMode aaMode() const { return fBatch.fAAMode; } |
669 bool fullDash() const { return fBatch.fFullDash; } | 672 bool fullDash() const { return fBatch.fFullDash; } |
670 SkPaint::Cap cap() const { return fBatch.fCap; } | 673 SkPaint::Cap cap() const { return fBatch.fCap; } |
671 | 674 |
672 struct BatchTracker { | 675 struct BatchTracker { |
673 GrColor fColor; | 676 GrColor fColor; |
674 bool fUsesLocalCoords; | 677 bool fUsesLocalCoords; |
675 bool fColorIgnored; | 678 bool fColorIgnored; |
676 bool fCoverageIgnored; | 679 bool fCoverageIgnored; |
677 SkPaint::Cap fCap; | 680 SkPaint::Cap fCap; |
678 bool fUseAA; | 681 DashAAMode fAAMode; |
679 bool fFullDash; | 682 bool fFullDash; |
680 }; | 683 }; |
681 | 684 |
682 static const int kVertsPerDash = 4; | 685 static const int kVertsPerDash = 4; |
683 static const int kIndicesPerDash = 6; | 686 static const int kIndicesPerDash = 6; |
684 | 687 |
685 BatchTracker fBatch; | 688 BatchTracker fBatch; |
686 SkSTArray<1, Geometry, true> fGeoData; | 689 SkSTArray<1, Geometry, true> fGeoData; |
687 }; | 690 }; |
688 | 691 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 geometry.fPtsRot); | 726 geometry.fPtsRot); |
724 | 727 |
725 SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; | 728 SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; |
726 SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularSca le; | 729 SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularSca le; |
727 | 730 |
728 if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { | 731 if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { |
729 // add cap to on interveal and remove from off interval | 732 // add cap to on interveal and remove from off interval |
730 offInterval -= strokeWidth; | 733 offInterval -= strokeWidth; |
731 } | 734 } |
732 | 735 |
733 bool useAA = paint.isAntiAlias(); | 736 DashAAMode aaMode = pipelineBuilder->getRenderTarget()->isMultisampled() ? k MSAA_DashAAMode : |
737 paint.isAntiAlias() ? kEdgeAA_DashAAMode : | |
738 kBW_DashAAMode; | |
739 | |
734 // TODO we can do a real rect call if not using fulldash(ie no off interval, not using AA) | 740 // TODO we can do a real rect call if not using fulldash(ie no off interval, not using AA) |
735 bool fullDash = offInterval > 0.f || useAA; | 741 bool fullDash = offInterval > 0.f || aaMode != kBW_DashAAMode; |
736 | 742 |
737 geometry.fColor = color; | 743 geometry.fColor = color; |
738 geometry.fViewMatrix = viewMatrix; | 744 geometry.fViewMatrix = viewMatrix; |
739 geometry.fPhase = info.fPhase; | 745 geometry.fPhase = info.fPhase; |
740 geometry.fIntervals[0] = info.fIntervals[0]; | 746 geometry.fIntervals[0] = info.fIntervals[0]; |
741 geometry.fIntervals[1] = info.fIntervals[1]; | 747 geometry.fIntervals[1] = info.fIntervals[1]; |
742 | 748 |
743 SkAutoTUnref<GrBatch> batch(DashBatch::Create(geometry, cap, useAA, fullDash )); | 749 SkAutoTUnref<GrBatch> batch(DashBatch::Create(geometry, cap, aaMode, fullDas h)); |
744 target->drawBatch(pipelineBuilder, batch); | 750 target->drawBatch(pipelineBuilder, batch); |
745 | 751 |
746 return true; | 752 return true; |
747 } | 753 } |
748 | 754 |
749 ////////////////////////////////////////////////////////////////////////////// | 755 ////////////////////////////////////////////////////////////////////////////// |
750 | 756 |
751 class GLDashingCircleEffect; | 757 class GLDashingCircleEffect; |
752 | 758 |
753 struct DashingCircleBatchTracker { | 759 struct DashingCircleBatchTracker { |
754 GrGPInput fInputColorType; | 760 GrGPInput fInputColorType; |
755 GrColor fColor; | 761 GrColor fColor; |
756 bool fUsesLocalCoords; | 762 bool fUsesLocalCoords; |
757 }; | 763 }; |
758 | 764 |
759 /* | 765 /* |
760 * This effect will draw a dotted line (defined as a dashed lined with round cap s and no on | 766 * This effect will draw a dotted line (defined as a dashed lined with round cap s and no on |
761 * interval). The radius of the dots is given by the strokeWidth and the spacing by the DashInfo. | 767 * interval). The radius of the dots is given by the strokeWidth and the spacing by the DashInfo. |
762 * Both of the previous two parameters are in device space. This effect also req uires the setting of | 768 * Both of the previous two parameters are in device space. This effect also req uires the setting of |
763 * a vec2 vertex attribute for the the four corners of the bounding rect. This a ttribute is the | 769 * a vec2 vertex attribute for the the four corners of the bounding rect. This a ttribute is the |
764 * "dash position" of each vertex. In other words it is the vertex coords (in de vice space) if we | 770 * "dash position" of each vertex. In other words it is the vertex coords (in de vice space) if we |
765 * transform the line to be horizontal, with the start of line at the origin the n shifted to the | 771 * transform the line to be horizontal, with the start of line at the origin the n shifted to the |
766 * right by half the off interval. The line then goes in the positive x directio n. | 772 * right by half the off interval. The line then goes in the positive x directio n. |
767 */ | 773 */ |
768 class DashingCircleEffect : public GrGeometryProcessor { | 774 class DashingCircleEffect : public GrGeometryProcessor { |
769 public: | 775 public: |
770 typedef SkPathEffect::DashInfo DashInfo; | 776 typedef SkPathEffect::DashInfo DashInfo; |
771 | 777 |
772 static GrGeometryProcessor* Create(GrColor, | 778 static GrGeometryProcessor* Create(GrColor, |
773 GrPrimitiveEdgeType edgeType, | 779 DashAAMode aaMode, |
774 const SkMatrix& localMatrix); | 780 const SkMatrix& localMatrix); |
775 | 781 |
776 virtual ~DashingCircleEffect(); | 782 virtual ~DashingCircleEffect(); |
777 | 783 |
778 const char* name() const override { return "DashingCircleEffect"; } | 784 const char* name() const override { return "DashingCircleEffect"; } |
779 | 785 |
780 const Attribute* inPosition() const { return fInPosition; } | 786 const Attribute* inPosition() const { return fInPosition; } |
781 | 787 |
782 const Attribute* inDashParams() const { return fInDashParams; } | 788 const Attribute* inDashParams() const { return fInDashParams; } |
783 | 789 |
784 const Attribute* inCircleParams() const { return fInCircleParams; } | 790 const Attribute* inCircleParams() const { return fInCircleParams; } |
785 | 791 |
786 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 792 DashAAMode aaMode() const { return fAAMode; } |
787 | 793 |
788 virtual void getGLProcessorKey(const GrBatchTracker&, | 794 virtual void getGLProcessorKey(const GrBatchTracker&, |
789 const GrGLCaps&, | 795 const GrGLCaps&, |
790 GrProcessorKeyBuilder* b) const override; | 796 GrProcessorKeyBuilder* b) const override; |
791 | 797 |
792 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, | 798 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, |
793 const GrGLCaps&) const over ride; | 799 const GrGLCaps&) const over ride; |
794 | 800 |
795 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; | 801 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; |
796 | 802 |
797 bool onCanMakeEqual(const GrBatchTracker&, | 803 bool onCanMakeEqual(const GrBatchTracker&, |
798 const GrGeometryProcessor&, | 804 const GrGeometryProcessor&, |
799 const GrBatchTracker&) const override; | 805 const GrBatchTracker&) const override; |
800 | 806 |
801 private: | 807 private: |
802 DashingCircleEffect(GrColor, GrPrimitiveEdgeType edgeType, const SkMatrix& l ocalMatrix); | 808 DashingCircleEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix) ; |
803 | 809 |
804 bool onIsEqual(const GrGeometryProcessor& other) const override; | 810 bool onIsEqual(const GrGeometryProcessor& other) const override; |
805 | 811 |
806 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; | 812 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; |
807 | 813 |
808 GrPrimitiveEdgeType fEdgeType; | 814 DashAAMode fAAMode; |
809 const Attribute* fInPosition; | 815 const Attribute* fInPosition; |
810 const Attribute* fInDashParams; | 816 const Attribute* fInDashParams; |
811 const Attribute* fInCircleParams; | 817 const Attribute* fInCircleParams; |
812 | 818 |
813 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 819 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
814 | 820 |
815 typedef GrGeometryProcessor INHERITED; | 821 typedef GrGeometryProcessor INHERITED; |
816 }; | 822 }; |
817 | 823 |
818 ////////////////////////////////////////////////////////////////////////////// | 824 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
857 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 863 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
858 | 864 |
859 // emit attributes | 865 // emit attributes |
860 vsBuilder->emitAttributes(dce); | 866 vsBuilder->emitAttributes(dce); |
861 | 867 |
862 // XY are dashPos, Z is dashInterval | 868 // XY are dashPos, Z is dashInterval |
863 GrGLVertToFrag dashParams(kVec3f_GrSLType); | 869 GrGLVertToFrag dashParams(kVec3f_GrSLType); |
864 args.fPB->addVarying("DashParam", &dashParams); | 870 args.fPB->addVarying("DashParam", &dashParams); |
865 vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->f Name); | 871 vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->f Name); |
866 | 872 |
867 // xy, refer to circle radius - 0.5, z refers to cicles center x coord | 873 // xy, refer to circle radius - 0.5, z refers to cicles center x coord |
egdaniel
2015/04/20 19:55:13
silly nit not from you, but do you mind changing t
Stephen White
2015/04/20 20:20:32
Done.
| |
868 GrGLVertToFrag circleParams(kVec2f_GrSLType); | 874 GrGLVertToFrag circleParams(kVec2f_GrSLType); |
869 args.fPB->addVarying("CircleParams", &circleParams); | 875 args.fPB->addVarying("CircleParams", &circleParams); |
870 vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams( )->fName); | 876 vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams( )->fName); |
871 | 877 |
872 // Setup pass through color | 878 // Setup pass through color |
873 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU LL, &fColorUniform); | 879 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU LL, &fColorUniform); |
874 | 880 |
875 // Setup position | 881 // Setup position |
876 this->setupPosition(pb, gpArgs, dce.inPosition()->fName, dce.viewMatrix()); | 882 this->setupPosition(pb, gpArgs, dce.inPosition()->fName, dce.viewMatrix()); |
877 | 883 |
878 // emit transforms | 884 // emit transforms |
879 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName , dce.localMatrix(), | 885 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName , dce.localMatrix(), |
880 args.fTransformsIn, args.fTransformsOut); | 886 args.fTransformsIn, args.fTransformsOut); |
881 | 887 |
882 // transforms all points so that we can compare them to our test circle | 888 // transforms all points so that we can compare them to our test circle |
883 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 889 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
884 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", | 890 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", |
885 dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn (), | 891 dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn (), |
886 dashParams.fsIn()); | 892 dashParams.fsIn()); |
887 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashPa rams.fsIn()); | 893 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashPa rams.fsIn()); |
888 fsBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn() ); | 894 fsBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn() ); |
889 fsBuilder->codeAppend("float dist = length(center - fragPosShifted);"); | 895 fsBuilder->codeAppend("float dist = length(center - fragPosShifted);"); |
890 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { | 896 if (dce.aaMode() == kEdgeAA_DashAAMode) { |
891 fsBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn()) ; | 897 fsBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn()) ; |
892 fsBuilder->codeAppend("diff = 1.0 - diff;"); | 898 fsBuilder->codeAppend("diff = 1.0 - diff;"); |
893 fsBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);"); | 899 fsBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);"); |
894 } else { | 900 } else { |
895 fsBuilder->codeAppendf("float alpha = 1.0;"); | 901 fsBuilder->codeAppendf("float alpha = 1.0;"); |
egdaniel
2015/04/20 19:55:13
since we fall into the else here for both msaa and
Stephen White
2015/04/20 20:20:32
Yeah, I wasn't sure about this. Since we're not bl
| |
896 fsBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circl eParams.fsIn()); | 902 fsBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circl eParams.fsIn()); |
897 } | 903 } |
898 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); | 904 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
899 } | 905 } |
900 | 906 |
901 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman, | 907 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman, |
902 const GrPrimitiveProcessor& processor, | 908 const GrPrimitiveProcessor& processor, |
903 const GrBatchTracker& bt) { | 909 const GrBatchTracker& bt) { |
904 this->setUniformViewMatrix(pdman, processor.viewMatrix()); | 910 this->setUniformViewMatrix(pdman, processor.viewMatrix()); |
905 | 911 |
906 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( ); | 912 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( ); |
907 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { | 913 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { |
908 GrGLfloat c[4]; | 914 GrGLfloat c[4]; |
909 GrColorToRGBAFloat(local.fColor, c); | 915 GrColorToRGBAFloat(local.fColor, c); |
910 pdman.set4fv(fColorUniform, 1, c); | 916 pdman.set4fv(fColorUniform, 1, c); |
911 fColor = local.fColor; | 917 fColor = local.fColor; |
912 } | 918 } |
913 } | 919 } |
914 | 920 |
915 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, | 921 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, |
916 const GrBatchTracker& bt, | 922 const GrBatchTracker& bt, |
917 const GrGLCaps&, | 923 const GrGLCaps&, |
918 GrProcessorKeyBuilder* b) { | 924 GrProcessorKeyBuilder* b) { |
919 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( ); | 925 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( ); |
920 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>(); | 926 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>(); |
921 uint32_t key = 0; | 927 uint32_t key = 0; |
922 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0; | 928 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0; |
923 key |= ComputePosKey(gp.viewMatrix()) << 1; | 929 key |= ComputePosKey(gp.viewMatrix()) << 1; |
924 key |= dce.getEdgeType() << 8; | 930 key |= dce.aaMode() << 8; |
925 b->add32(key << 16 | local.fInputColorType); | 931 b->add32(key << 16 | local.fInputColorType); |
926 } | 932 } |
927 | 933 |
928 ////////////////////////////////////////////////////////////////////////////// | 934 ////////////////////////////////////////////////////////////////////////////// |
929 | 935 |
930 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, | 936 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, |
931 GrPrimitiveEdgeType edgeType, | 937 DashAAMode aaMode, |
932 const SkMatrix& localMatrix) { | 938 const SkMatrix& localMatrix) { |
933 return SkNEW_ARGS(DashingCircleEffect, (color, edgeType, localMatrix)); | 939 return SkNEW_ARGS(DashingCircleEffect, (color, aaMode, localMatrix)); |
934 } | 940 } |
935 | 941 |
936 DashingCircleEffect::~DashingCircleEffect() {} | 942 DashingCircleEffect::~DashingCircleEffect() {} |
937 | 943 |
938 void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* ou t) const { | 944 void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* ou t) const { |
939 out->setUnknownSingleComponent(); | 945 out->setUnknownSingleComponent(); |
940 } | 946 } |
941 | 947 |
942 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, | 948 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, |
943 const GrGLCaps& caps, | 949 const GrGLCaps& caps, |
944 GrProcessorKeyBuilder* b) const { | 950 GrProcessorKeyBuilder* b) const { |
945 GLDashingCircleEffect::GenKey(*this, bt, caps, b); | 951 GLDashingCircleEffect::GenKey(*this, bt, caps, b); |
946 } | 952 } |
947 | 953 |
948 GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack er& bt, | 954 GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack er& bt, |
949 const GrGLCaps&) c onst { | 955 const GrGLCaps&) c onst { |
950 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); | 956 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); |
951 } | 957 } |
952 | 958 |
953 DashingCircleEffect::DashingCircleEffect(GrColor color, | 959 DashingCircleEffect::DashingCircleEffect(GrColor color, |
954 GrPrimitiveEdgeType edgeType, | 960 DashAAMode aaMode, |
955 const SkMatrix& localMatrix) | 961 const SkMatrix& localMatrix) |
956 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { | 962 : INHERITED(color, SkMatrix::I(), localMatrix), fAAMode(aaMode) { |
957 this->initClassID<DashingCircleEffect>(); | 963 this->initClassID<DashingCircleEffect>(); |
958 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); | 964 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); |
959 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe rtexAttribType)); | 965 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe rtexAttribType)); |
960 fInCircleParams = &this->addVertexAttrib(Attribute("inCircleParams", | 966 fInCircleParams = &this->addVertexAttrib(Attribute("inCircleParams", |
961 kVec2f_GrVertexAttribType )); | 967 kVec2f_GrVertexAttribType )); |
962 } | 968 } |
963 | 969 |
964 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { | 970 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { |
965 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); | 971 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); |
966 return fEdgeType == dce.fEdgeType; | 972 return fAAMode == dce.fAAMode; |
967 } | 973 } |
968 | 974 |
969 void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineI nfo& init) const { | 975 void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineI nfo& init) const { |
970 DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>(); | 976 DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>(); |
971 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false); | 977 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false); |
972 local->fUsesLocalCoords = init.fUsesLocalCoords; | 978 local->fUsesLocalCoords = init.fUsesLocalCoords; |
973 } | 979 } |
974 | 980 |
975 bool DashingCircleEffect::onCanMakeEqual(const GrBatchTracker& m, | 981 bool DashingCircleEffect::onCanMakeEqual(const GrBatchTracker& m, |
976 const GrGeometryProcessor& that, | 982 const GrGeometryProcessor& that, |
977 const GrBatchTracker& t) const { | 983 const GrBatchTracker& t) const { |
978 const DashingCircleBatchTracker& mine = m.cast<DashingCircleBatchTracker>(); | 984 const DashingCircleBatchTracker& mine = m.cast<DashingCircleBatchTracker>(); |
979 const DashingCircleBatchTracker& theirs = t.cast<DashingCircleBatchTracker>( ); | 985 const DashingCircleBatchTracker& theirs = t.cast<DashingCircleBatchTracker>( ); |
980 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 986 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
981 that, theirs.fUsesLocalCoords) && | 987 that, theirs.fUsesLocalCoords) && |
982 CanCombineOutput(mine.fInputColorType, mine.fColor, | 988 CanCombineOutput(mine.fInputColorType, mine.fColor, |
983 theirs.fInputColorType, theirs.fColor); | 989 theirs.fInputColorType, theirs.fColor); |
984 } | 990 } |
985 | 991 |
986 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); | 992 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); |
987 | 993 |
988 GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, | 994 GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, |
989 GrContext*, | 995 GrContext*, |
990 const GrDrawTargetCaps& cap s, | 996 const GrDrawTargetCaps& cap s, |
991 GrTexture*[]) { | 997 GrTexture*[]) { |
992 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next ULessThan( | 998 DashAAMode aaMode = static_cast<DashAAMode>(random->nextULessThan(kDashAAMod eCnt)); |
993 kGrProcessorEdgeTypeCnt)); | |
994 return DashingCircleEffect::Create(GrRandomColor(random), | 999 return DashingCircleEffect::Create(GrRandomColor(random), |
995 edgeType, GrProcessorUnitTest::TestMatrix (random)); | 1000 aaMode, GrProcessorUnitTest::TestMatrix(ra ndom)); |
996 } | 1001 } |
997 | 1002 |
998 ////////////////////////////////////////////////////////////////////////////// | 1003 ////////////////////////////////////////////////////////////////////////////// |
999 | 1004 |
1000 class GLDashingLineEffect; | 1005 class GLDashingLineEffect; |
1001 | 1006 |
1002 struct DashingLineBatchTracker { | 1007 struct DashingLineBatchTracker { |
1003 GrGPInput fInputColorType; | 1008 GrGPInput fInputColorType; |
1004 GrColor fColor; | 1009 GrColor fColor; |
1005 bool fUsesLocalCoords; | 1010 bool fUsesLocalCoords; |
1006 }; | 1011 }; |
1007 | 1012 |
1008 /* | 1013 /* |
1009 * This effect will draw a dashed line. The width of the dash is given by the st rokeWidth and the | 1014 * This effect will draw a dashed line. The width of the dash is given by the st rokeWidth and the |
1010 * length and spacing by the DashInfo. Both of the previous two parameters are i n device space. | 1015 * length and spacing by the DashInfo. Both of the previous two parameters are i n device space. |
1011 * This effect also requires the setting of a vec2 vertex attribute for the the four corners of the | 1016 * This effect also requires the setting of a vec2 vertex attribute for the the four corners of the |
1012 * bounding rect. This attribute is the "dash position" of each vertex. In other words it is the | 1017 * bounding rect. This attribute is the "dash position" of each vertex. In other words it is the |
1013 * vertex coords (in device space) if we transform the line to be horizontal, wi th the start of | 1018 * vertex coords (in device space) if we transform the line to be horizontal, wi th the start of |
1014 * line at the origin then shifted to the right by half the off interval. The li ne then goes in the | 1019 * line at the origin then shifted to the right by half the off interval. The li ne then goes in the |
1015 * positive x direction. | 1020 * positive x direction. |
1016 */ | 1021 */ |
1017 class DashingLineEffect : public GrGeometryProcessor { | 1022 class DashingLineEffect : public GrGeometryProcessor { |
1018 public: | 1023 public: |
1019 typedef SkPathEffect::DashInfo DashInfo; | 1024 typedef SkPathEffect::DashInfo DashInfo; |
1020 | 1025 |
1021 static GrGeometryProcessor* Create(GrColor, | 1026 static GrGeometryProcessor* Create(GrColor, |
1022 GrPrimitiveEdgeType edgeType, | 1027 DashAAMode aaMode, |
1023 const SkMatrix& localMatrix); | 1028 const SkMatrix& localMatrix); |
1024 | 1029 |
1025 virtual ~DashingLineEffect(); | 1030 virtual ~DashingLineEffect(); |
1026 | 1031 |
1027 const char* name() const override { return "DashingEffect"; } | 1032 const char* name() const override { return "DashingEffect"; } |
1028 | 1033 |
1029 const Attribute* inPosition() const { return fInPosition; } | 1034 const Attribute* inPosition() const { return fInPosition; } |
1030 | 1035 |
1031 const Attribute* inDashParams() const { return fInDashParams; } | 1036 const Attribute* inDashParams() const { return fInDashParams; } |
1032 | 1037 |
1033 const Attribute* inRectParams() const { return fInRectParams; } | 1038 const Attribute* inRectParams() const { return fInRectParams; } |
1034 | 1039 |
1035 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 1040 DashAAMode aaMode() const { return fAAMode; } |
1036 | 1041 |
1037 virtual void getGLProcessorKey(const GrBatchTracker& bt, | 1042 virtual void getGLProcessorKey(const GrBatchTracker& bt, |
1038 const GrGLCaps& caps, | 1043 const GrGLCaps& caps, |
1039 GrProcessorKeyBuilder* b) const override; | 1044 GrProcessorKeyBuilder* b) const override; |
1040 | 1045 |
1041 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, | 1046 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, |
1042 const GrGLCaps&) const over ride; | 1047 const GrGLCaps&) const over ride; |
1043 | 1048 |
1044 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; | 1049 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override; |
1045 | 1050 |
1046 bool onCanMakeEqual(const GrBatchTracker&, | 1051 bool onCanMakeEqual(const GrBatchTracker&, |
1047 const GrGeometryProcessor&, | 1052 const GrGeometryProcessor&, |
1048 const GrBatchTracker&) const override; | 1053 const GrBatchTracker&) const override; |
1049 | 1054 |
1050 private: | 1055 private: |
1051 DashingLineEffect(GrColor, GrPrimitiveEdgeType edgeType, const SkMatrix& loc alMatrix); | 1056 DashingLineEffect(GrColor, DashAAMode aaMode, const SkMatrix& localMatrix); |
1052 | 1057 |
1053 bool onIsEqual(const GrGeometryProcessor& other) const override; | 1058 bool onIsEqual(const GrGeometryProcessor& other) const override; |
1054 | 1059 |
1055 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; | 1060 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override; |
1056 | 1061 |
1057 GrPrimitiveEdgeType fEdgeType; | 1062 DashAAMode fAAMode; |
1058 const Attribute* fInPosition; | 1063 const Attribute* fInPosition; |
1059 const Attribute* fInDashParams; | 1064 const Attribute* fInDashParams; |
1060 const Attribute* fInRectParams; | 1065 const Attribute* fInRectParams; |
1061 | 1066 |
1062 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 1067 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
1063 | 1068 |
1064 typedef GrGeometryProcessor INHERITED; | 1069 typedef GrGeometryProcessor INHERITED; |
1065 }; | 1070 }; |
1066 | 1071 |
1067 ////////////////////////////////////////////////////////////////////////////// | 1072 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1122 // emit transforms | 1127 // emit transforms |
1123 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(), | 1128 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(), |
1124 args.fTransformsIn, args.fTransformsOut); | 1129 args.fTransformsIn, args.fTransformsOut); |
1125 | 1130 |
1126 // transforms all points so that we can compare them to our test rect | 1131 // transforms all points so that we can compare them to our test rect |
1127 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 1132 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
1128 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", | 1133 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", |
1129 inDashParams.fsIn(), inDashParams.fsIn(), inDashParam s.fsIn(), | 1134 inDashParams.fsIn(), inDashParams.fsIn(), inDashParam s.fsIn(), |
1130 inDashParams.fsIn()); | 1135 inDashParams.fsIn()); |
1131 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDash Params.fsIn()); | 1136 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDash Params.fsIn()); |
1132 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { | 1137 if (de.aaMode() == kEdgeAA_DashAAMode) { |
1133 // The amount of coverage removed in x and y by the edges is computed as a pair of negative | 1138 // The amount of coverage removed in x and y by the edges is computed as a pair of negative |
1134 // numbers, xSub and ySub. | 1139 // numbers, xSub and ySub. |
1135 fsBuilder->codeAppend("float xSub, ySub;"); | 1140 fsBuilder->codeAppend("float xSub, ySub;"); |
1136 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe ctParams.fsIn()); | 1141 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe ctParams.fsIn()); |
1137 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR ectParams.fsIn()); | 1142 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR ectParams.fsIn()); |
1138 fsBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRe ctParams.fsIn()); | 1143 fsBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRe ctParams.fsIn()); |
1139 fsBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inR ectParams.fsIn()); | 1144 fsBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inR ectParams.fsIn()); |
1140 // Now compute coverage in x and y and multiply them to get the fraction of the pixel | 1145 // Now compute coverage in x and y and multiply them to get the fraction of the pixel |
1141 // covered. | 1146 // covered. |
1142 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m ax(ySub, -1.0));"); | 1147 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m ax(ySub, -1.0));"); |
1148 } else if (de.aaMode() == kMSAA_DashAAMode) { | |
1149 // For MSAA, we don't modulate the alpha by the Y distance, since MSAA c overage will handle | |
1150 // AA on the the top and bottom edges. The shader is only responsible fo r intra-dash alpha. | |
1151 fsBuilder->codeAppend("float xSub;"); | |
1152 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe ctParams.fsIn()); | |
1153 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR ectParams.fsIn()); | |
1154 // Now compute coverage in x and y and multiply them to get the fraction of the pixel | |
egdaniel
2015/04/20 19:55:13
not doing y anymore here.
Stephen White
2015/04/20 20:20:32
Done.
| |
1155 // covered. | |
1156 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0));"); | |
1143 } else { | 1157 } else { |
1144 // Assuming the bounding geometry is tight so no need to check y values | 1158 // Assuming the bounding geometry is tight so no need to check y values |
1145 fsBuilder->codeAppendf("float alpha = 1.0;"); | 1159 fsBuilder->codeAppendf("float alpha = 1.0;"); |
1146 fsBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;", | 1160 fsBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;", |
1147 inRectParams.fsIn()); | 1161 inRectParams.fsIn()); |
1148 fsBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;", | 1162 fsBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;", |
1149 inRectParams.fsIn()); | 1163 inRectParams.fsIn()); |
1150 } | 1164 } |
1151 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); | 1165 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
1152 } | 1166 } |
(...skipping 14 matching lines...) Expand all Loading... | |
1167 | 1181 |
1168 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, | 1182 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, |
1169 const GrBatchTracker& bt, | 1183 const GrBatchTracker& bt, |
1170 const GrGLCaps&, | 1184 const GrGLCaps&, |
1171 GrProcessorKeyBuilder* b) { | 1185 GrProcessorKeyBuilder* b) { |
1172 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); | 1186 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); |
1173 const DashingLineEffect& de = gp.cast<DashingLineEffect>(); | 1187 const DashingLineEffect& de = gp.cast<DashingLineEffect>(); |
1174 uint32_t key = 0; | 1188 uint32_t key = 0; |
1175 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0; | 1189 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0; |
1176 key |= ComputePosKey(gp.viewMatrix()) << 1; | 1190 key |= ComputePosKey(gp.viewMatrix()) << 1; |
1177 key |= de.getEdgeType() << 8; | 1191 key |= de.aaMode() << 8; |
1178 b->add32(key << 16 | local.fInputColorType); | 1192 b->add32(key << 16 | local.fInputColorType); |
1179 } | 1193 } |
1180 | 1194 |
1181 ////////////////////////////////////////////////////////////////////////////// | 1195 ////////////////////////////////////////////////////////////////////////////// |
1182 | 1196 |
1183 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, | 1197 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, |
1184 GrPrimitiveEdgeType edgeType, | 1198 DashAAMode aaMode, |
1185 const SkMatrix& localMatrix) { | 1199 const SkMatrix& localMatrix) { |
1186 return SkNEW_ARGS(DashingLineEffect, (color, edgeType, localMatrix)); | 1200 return SkNEW_ARGS(DashingLineEffect, (color, aaMode, localMatrix)); |
1187 } | 1201 } |
1188 | 1202 |
1189 DashingLineEffect::~DashingLineEffect() {} | 1203 DashingLineEffect::~DashingLineEffect() {} |
1190 | 1204 |
1191 void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { | 1205 void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { |
1192 out->setUnknownSingleComponent(); | 1206 out->setUnknownSingleComponent(); |
1193 } | 1207 } |
1194 | 1208 |
1195 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, | 1209 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, |
1196 const GrGLCaps& caps, | 1210 const GrGLCaps& caps, |
1197 GrProcessorKeyBuilder* b) const { | 1211 GrProcessorKeyBuilder* b) const { |
1198 GLDashingLineEffect::GenKey(*this, bt, caps, b); | 1212 GLDashingLineEffect::GenKey(*this, bt, caps, b); |
1199 } | 1213 } |
1200 | 1214 |
1201 GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker & bt, | 1215 GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker & bt, |
1202 const GrGLCaps&) con st { | 1216 const GrGLCaps&) con st { |
1203 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); | 1217 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); |
1204 } | 1218 } |
1205 | 1219 |
1206 DashingLineEffect::DashingLineEffect(GrColor color, | 1220 DashingLineEffect::DashingLineEffect(GrColor color, |
1207 GrPrimitiveEdgeType edgeType, | 1221 DashAAMode aaMode, |
1208 const SkMatrix& localMatrix) | 1222 const SkMatrix& localMatrix) |
1209 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { | 1223 : INHERITED(color, SkMatrix::I(), localMatrix), fAAMode(aaMode) { |
1210 this->initClassID<DashingLineEffect>(); | 1224 this->initClassID<DashingLineEffect>(); |
1211 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); | 1225 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); |
1212 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe rtexAttribType)); | 1226 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe rtexAttribType)); |
1213 fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAt tribType)); | 1227 fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAt tribType)); |
1214 } | 1228 } |
1215 | 1229 |
1216 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { | 1230 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { |
1217 const DashingLineEffect& de = other.cast<DashingLineEffect>(); | 1231 const DashingLineEffect& de = other.cast<DashingLineEffect>(); |
1218 return fEdgeType == de.fEdgeType; | 1232 return fAAMode == de.fAAMode; |
1219 } | 1233 } |
1220 | 1234 |
1221 void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInf o& init) const { | 1235 void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInf o& init) const { |
1222 DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>(); | 1236 DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>(); |
1223 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false); | 1237 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false); |
1224 local->fUsesLocalCoords = init.fUsesLocalCoords; | 1238 local->fUsesLocalCoords = init.fUsesLocalCoords; |
1225 } | 1239 } |
1226 | 1240 |
1227 bool DashingLineEffect::onCanMakeEqual(const GrBatchTracker& m, | 1241 bool DashingLineEffect::onCanMakeEqual(const GrBatchTracker& m, |
1228 const GrGeometryProcessor& that, | 1242 const GrGeometryProcessor& that, |
1229 const GrBatchTracker& t) const { | 1243 const GrBatchTracker& t) const { |
1230 const DashingLineBatchTracker& mine = m.cast<DashingLineBatchTracker>(); | 1244 const DashingLineBatchTracker& mine = m.cast<DashingLineBatchTracker>(); |
1231 const DashingLineBatchTracker& theirs = t.cast<DashingLineBatchTracker>(); | 1245 const DashingLineBatchTracker& theirs = t.cast<DashingLineBatchTracker>(); |
1232 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, | 1246 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, |
1233 that, theirs.fUsesLocalCoords) && | 1247 that, theirs.fUsesLocalCoords) && |
1234 CanCombineOutput(mine.fInputColorType, mine.fColor, | 1248 CanCombineOutput(mine.fInputColorType, mine.fColor, |
1235 theirs.fInputColorType, theirs.fColor); | 1249 theirs.fInputColorType, theirs.fColor); |
1236 } | 1250 } |
1237 | 1251 |
1238 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); | 1252 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); |
1239 | 1253 |
1240 GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, | 1254 GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, |
1241 GrContext*, | 1255 GrContext*, |
1242 const GrDrawTargetCaps& caps, | 1256 const GrDrawTargetCaps& caps, |
1243 GrTexture*[]) { | 1257 GrTexture*[]) { |
1244 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next ULessThan( | 1258 DashAAMode aaMode = static_cast<DashAAMode>(random->nextULessThan(kDashAAMod eCnt)); |
1245 kGrProcessorEdgeTypeCnt)); | |
1246 | |
1247 return DashingLineEffect::Create(GrRandomColor(random), | 1259 return DashingLineEffect::Create(GrRandomColor(random), |
1248 edgeType, GrProcessorUnitTest::TestMatrix(r andom)); | 1260 aaMode, GrProcessorUnitTest::TestMatrix(ran dom)); |
1249 } | 1261 } |
1250 | 1262 |
1251 ////////////////////////////////////////////////////////////////////////////// | 1263 ////////////////////////////////////////////////////////////////////////////// |
1252 | 1264 |
1253 static GrGeometryProcessor* create_dash_gp(GrColor color, | 1265 static GrGeometryProcessor* create_dash_gp(GrColor color, |
1254 GrPrimitiveEdgeType edgeType, | 1266 DashAAMode dashAAMode, |
1255 DashCap cap, | 1267 DashCap cap, |
1256 const SkMatrix& localMatrix) { | 1268 const SkMatrix& localMatrix) { |
1257 switch (cap) { | 1269 switch (cap) { |
1258 case kRound_DashCap: | 1270 case kRound_DashCap: |
1259 return DashingCircleEffect::Create(color, edgeType, localMatrix); | 1271 return DashingCircleEffect::Create(color, dashAAMode, localMatrix); |
1260 case kNonRound_DashCap: | 1272 case kNonRound_DashCap: |
1261 return DashingLineEffect::Create(color, edgeType, localMatrix); | 1273 return DashingLineEffect::Create(color, dashAAMode, localMatrix); |
1262 default: | 1274 default: |
1263 SkFAIL("Unexpected dashed cap."); | 1275 SkFAIL("Unexpected dashed cap."); |
1264 } | 1276 } |
1265 return NULL; | 1277 return NULL; |
1266 } | 1278 } |
OLD | NEW |