Chromium Code Reviews| 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 |