Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(476)

Side by Side Diff: src/gpu/effects/GrDashingEffect.cpp

Issue 892203003: Dash using vertex attributes for interval and stroke width (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: dashing Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrDashingEffect.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "../GrAARectRenderer.h" 10 #include "../GrAARectRenderer.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 return false; 60 return false;
61 } 61 }
62 62
63 return true; 63 return true;
64 } 64 }
65 65
66 namespace { 66 namespace {
67 struct DashLineVertex { 67 struct DashLineVertex {
68 SkPoint fPos; 68 SkPoint fPos;
69 SkPoint fDashPos; 69 SkPoint fDashPos;
70 SkScalar fIntervalLength;
71 SkRect fRect;
72 };
73 struct DashCircleVertex {
74 SkPoint fPos;
75 SkPoint fDashPos;
76 SkScalar fIntervalLength;
77 SkScalar fRadius;
78 SkScalar fCenterX;
70 }; 79 };
71 }; 80 };
72 81
73 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, 82 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale,
74 const SkMatrix& viewMatrix, const SkPoint pts[2]) { 83 const SkMatrix& viewMatrix, const SkPoint pts[2]) {
75 SkVector vecSrc = pts[1] - pts[0]; 84 SkVector vecSrc = pts[1] - pts[0];
76 SkScalar magSrc = vecSrc.length(); 85 SkScalar magSrc = vecSrc.length();
77 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; 86 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0;
78 vecSrc.scale(invSrc); 87 vecSrc.scale(invSrc);
79 88
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 140 }
132 if (*endingInt > info.fIntervals[0]) { 141 if (*endingInt > info.fIntervals[0]) {
133 if (0 == info.fIntervals[0]) { 142 if (0 == info.fIntervals[0]) {
134 *endingInt -= 0.01f; // make sure we capture the last zero size pnt (used if has caps) 143 *endingInt -= 0.01f; // make sure we capture the last zero size pnt (used if has caps)
135 } 144 }
136 return *endingInt - info.fIntervals[0]; 145 return *endingInt - info.fIntervals[0];
137 } 146 }
138 return 0; 147 return 0;
139 } 148 }
140 149
141 static void setup_dashed_rect(const SkRect& rect, DashLineVertex* verts, int idx , const SkMatrix& matrix, 150 enum DashCap {
142 SkScalar offset, SkScalar bloat, SkScalar len, SkScalar s troke) { 151 kRound_DashCap,
143 SkScalar startDashX = offset - bloat; 152 kNonRound_DashCap,
144 SkScalar endDashX = offset + len + bloat; 153 };
145 SkScalar startDashY = -stroke - bloat; 154
146 SkScalar endDashY = stroke + bloat; 155 static int kDashVertices = 4;
147 verts[idx].fDashPos = SkPoint::Make(startDashX , startDashY); 156
148 verts[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY); 157 template <typename T>
149 verts[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY); 158 void setup_dashed_rect_common(const SkRect& rect, const SkMatrix& matrix, T* ver tices, int idx,
150 verts[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY); 159 SkScalar offset, SkScalar bloat, SkScalar len, SkS calar stroke) {
151 verts[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop); 160 SkScalar startDashX = offset - bloat;
152 verts[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom); 161 SkScalar endDashX = offset + len + bloat;
153 verts[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom); 162 SkScalar startDashY = -stroke - bloat;
154 verts[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop); 163 SkScalar endDashY = stroke + bloat;
155 matrix.mapPointsWithStride(&verts[idx].fPos, sizeof(DashLineVertex), 4); 164 vertices[idx].fDashPos = SkPoint::Make(startDashX , startDashY);
165 vertices[idx + 1].fDashPos = SkPoint::Make(startDashX, endDashY);
166 vertices[idx + 2].fDashPos = SkPoint::Make(endDashX, endDashY);
167 vertices[idx + 3].fDashPos = SkPoint::Make(endDashX, startDashY);
168
169 vertices[idx].fPos = SkPoint::Make(rect.fLeft, rect.fTop);
170 vertices[idx + 1].fPos = SkPoint::Make(rect.fLeft, rect.fBottom);
171 vertices[idx + 2].fPos = SkPoint::Make(rect.fRight, rect.fBottom);
172 vertices[idx + 3].fPos = SkPoint::Make(rect.fRight, rect.fTop);
173
174 matrix.mapPointsWithStride(&vertices[idx].fPos, sizeof(T), 4);
175 }
176
177 static void setup_dashed_rect(const SkRect& rect, void* vertices, int idx,
178 const SkMatrix& matrix, SkScalar offset, SkScalar bloat,
179 SkScalar len, SkScalar stroke, SkScalar startInter val,
180 SkScalar endInterval, SkScalar strokeWidth, DashCa p cap,
181 const size_t vertexStride) {
182 SkScalar intervalLength = startInterval + endInterval;
183
184 if (kRound_DashCap == cap) {
185 SkASSERT(vertexStride == sizeof(DashCircleVertex));
186 DashCircleVertex* verts = reinterpret_cast<DashCircleVertex*>(vertices);
187
188 setup_dashed_rect_common<DashCircleVertex>(rect, matrix, verts, idx, off set, bloat, len,
189 stroke);
190
191 SkScalar radius = SkScalarHalf(strokeWidth) - 0.5f;
192 SkScalar centerX = SkScalarHalf(endInterval);
193
194 for (int i = 0; i < kDashVertices; i++) {
195 verts[idx + i].fIntervalLength = intervalLength;
196 verts[idx + i].fRadius = radius;
197 verts[idx + i].fCenterX = centerX;
198 }
199
200 } else {
201 SkASSERT(kNonRound_DashCap == cap && vertexStride == sizeof(DashLineVert ex));
202 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(vertices);
203
204 setup_dashed_rect_common<DashLineVertex>(rect, matrix, verts, idx, offse t, bloat, len,
205 stroke);
206
207 SkScalar halfOffLen = SkScalarHalf(endInterval);
208 SkScalar halfStroke = SkScalarHalf(strokeWidth);
209 SkRect rectParam;
210 rectParam.set(halfOffLen + 0.5f, -halfStroke + 0.5f,
211 halfOffLen + startInterval - 0.5f, halfStroke - 0.5f);
212 for (int i = 0; i < kDashVertices; i++) {
213 verts[idx + i].fIntervalLength = intervalLength;
214 verts[idx + i].fRect = rectParam;
215 }
216 }
156 } 217 }
157 218
158 static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m atrix, 219 static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m atrix,
159 SkPoint* verts) { 220 SkPoint* verts) {
160 verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop); 221 verts[idx] = SkPoint::Make(rect.fLeft, rect.fTop);
161 verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom); 222 verts[idx + 1] = SkPoint::Make(rect.fLeft, rect.fBottom);
162 verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom); 223 verts[idx + 2] = SkPoint::Make(rect.fRight, rect.fBottom);
163 verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop); 224 verts[idx + 3] = SkPoint::Make(rect.fRight, rect.fTop);
164 matrix.mapPoints(&verts[idx], 4); 225 matrix.mapPoints(&verts[idx], 4);
165 } 226 }
166 227
228
229 /**
230 * An GrGeometryProcessor that renders a dashed line.
231 * This GrGeometryProcessor is meant for dashed lines that only have a single on /off interval pair.
232 * Bounding geometry is rendered and the effect computes coverage based on the f ragment's
233 * position relative to the dashed line.
234 */
235 static GrGeometryProcessor* create_dash_gp(GrColor,
236 GrPrimitiveEdgeType edgeType,
237 DashCap cap,
238 const SkMatrix& localMatrix);
239
167 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, 240 bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target,
168 GrPipelineBuilder* pipelineBuilder, GrColor c olor, 241 GrPipelineBuilder* pipelineBuilder, GrColor c olor,
169 const SkMatrix& viewMatrix, const SkPoint pts [2], 242 const SkMatrix& viewMatrix, const SkPoint pts [2],
170 const GrPaint& paint, const GrStrokeInfo& str okeInfo) { 243 const GrPaint& paint, const GrStrokeInfo& str okeInfo) {
171 if (!can_fast_path_dash(pts, strokeInfo, *target, *pipelineBuilder, viewMatr ix)) { 244 if (!can_fast_path_dash(pts, strokeInfo, *target, *pipelineBuilder, viewMatr ix)) {
172 return false; 245 return false;
173 } 246 }
174 247
175 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); 248 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo();
176 249
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 devIntervals[0] = lineLength; 408 devIntervals[0] = lineLength;
336 } 409 }
337 410
338 // reset to device coordinates 411 // reset to device coordinates
339 SkMatrix invert; 412 SkMatrix invert;
340 if (!viewMatrix.invert(&invert)) { 413 if (!viewMatrix.invert(&invert)) {
341 SkDebugf("Failed to invert\n"); 414 SkDebugf("Failed to invert\n");
342 return false; 415 return false;
343 } 416 }
344 417
418 bool isRoundCap = SkPaint::kRound_Cap == cap;
419 DashCap capType = isRoundCap ? kRound_DashCap : kNonRound_DashCap;
420
345 SkAutoTUnref<const GrGeometryProcessor> gp; 421 SkAutoTUnref<const GrGeometryProcessor> gp;
346 bool fullDash = devIntervals[1] > 0.f || useAA; 422 bool fullDash = devIntervals[1] > 0.f || useAA;
347 if (fullDash) { 423 if (fullDash) {
348 SkPathEffect::DashInfo devInfo; 424 SkPathEffect::DashInfo devInfo;
349 devInfo.fPhase = devPhase; 425 devInfo.fPhase = devPhase;
350 devInfo.fCount = 2; 426 devInfo.fCount = 2;
351 devInfo.fIntervals = devIntervals; 427 devInfo.fIntervals = devIntervals;
352 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : 428 GrPrimitiveEdgeType edgeType = useAA ? kFillAA_GrProcessorEdgeType :
353 kFillBW_GrProcessorEdgeType; 429 kFillBW_GrProcessorEdgeType;
354 bool isRoundCap = SkPaint::kRound_Cap == cap; 430 gp.reset(create_dash_gp(color, edgeType, capType, invert));
355 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_ DashCap :
356 GrDashingEffect::kNonRou nd_DashCap;
357 gp.reset(GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType, invert));
358 } else { 431 } else {
359 // Set up the vertex data for the line and start/end dashes 432 // Set up the vertex data for the line and start/end dashes
360 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosit ion_GPType, 433 gp.reset(GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosit ion_GPType,
361 color, 434 color,
362 SkMatrix::I(), 435 SkMatrix::I(),
363 invert)); 436 invert));
364 } 437 }
365 438
366 int totalRectCnt = 0; 439 int totalRectCnt = 0;
367 440
(...skipping 22 matching lines...) Expand all
390 viewMatrix.mapPoints(devicePts, ptsRot, 2); 463 viewMatrix.mapPoints(devicePts, ptsRot, 2);
391 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); 464 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]);
392 if (hasCap) { 465 if (hasCap) {
393 lineLength += 2.f * halfDevStroke; 466 lineLength += 2.f * halfDevStroke;
394 } 467 }
395 468
396 SkRect bounds; 469 SkRect bounds;
397 bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); 470 bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY);
398 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); 471 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke);
399 if (fullDash) { 472 if (fullDash) {
400 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic es()); 473 setup_dashed_rect(bounds, geo.vertices(), curVIdx, combinedMatrix, s tartOffset,
401 SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex)); 474 devBloat, lineLength, halfDevStroke, devIntervals[ 0], devIntervals[1],
402 setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffse t, devBloat, 475 strokeWidth, capType, gp->getVertexStride());
403 lineLength, halfDevStroke);
404 } else { 476 } else {
405 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); 477 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
406 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); 478 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
407 setup_dashed_rect_pos(bounds, curVIdx, combinedMatrix, verts); 479 setup_dashed_rect_pos(bounds, curVIdx, combinedMatrix, verts);
408 } 480 }
409 curVIdx += 4; 481 curVIdx += 4;
410 } 482 }
411 483
412 if (hasStartRect) { 484 if (hasStartRect) {
413 SkASSERT(useAA); // so that we know bloatX and bloatY have been set 485 SkASSERT(useAA); // so that we know bloatX and bloatY have been set
414 startRect.outset(bloatX, bloatY); 486 startRect.outset(bloatX, bloatY);
415 if (fullDash) { 487 if (fullDash) {
416 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic es()); 488 setup_dashed_rect(startRect, geo.vertices(), curVIdx, combinedMatrix , startOffset,
417 SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex)); 489 devBloat, devIntervals[0], halfDevStroke, devInter vals[0],
418 setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOf fset, devBloat, 490 devIntervals[1], strokeWidth, capType, gp->getVert exStride());
419 devIntervals[0], halfDevStroke);
420 } else { 491 } else {
421 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); 492 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
422 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); 493 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
423 setup_dashed_rect_pos(startRect, curVIdx, combinedMatrix, verts); 494 setup_dashed_rect_pos(startRect, curVIdx, combinedMatrix, verts);
424 } 495 }
425 496
426 curVIdx += 4; 497 curVIdx += 4;
427 } 498 }
428 499
429 if (hasEndRect) { 500 if (hasEndRect) {
430 SkASSERT(useAA); // so that we know bloatX and bloatY have been set 501 SkASSERT(useAA); // so that we know bloatX and bloatY have been set
431 endRect.outset(bloatX, bloatY); 502 endRect.outset(bloatX, bloatY);
432 if (fullDash) { 503 if (fullDash) {
433 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic es()); 504 setup_dashed_rect(endRect, geo.vertices(), curVIdx, combinedMatrix, startOffset,
434 SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex)); 505 devBloat, devIntervals[0], halfDevStroke, devInter vals[0],
435 setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffs et, devBloat, 506 devIntervals[1], strokeWidth, capType, gp->getVert exStride());
436 devIntervals[0], halfDevStroke);
437 } else { 507 } else {
438 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); 508 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
439 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); 509 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
440 setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts); 510 setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts);
441 } 511 }
442 512
443 } 513 }
444 514
445 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); 515 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
446 target->drawIndexedInstances(pipelineBuilder, gp, kTriangles_GrPrimitiveType , 516 target->drawIndexedInstances(pipelineBuilder, gp, kTriangles_GrPrimitiveType ,
(...skipping 20 matching lines...) Expand all
467 * "dash position" of each vertex. In other words it is the vertex coords (in de vice space) if we 537 * "dash position" of each vertex. In other words it is the vertex coords (in de vice space) if we
468 * transform the line to be horizontal, with the start of line at the origin the n shifted to the 538 * transform the line to be horizontal, with the start of line at the origin the n shifted to the
469 * right by half the off interval. The line then goes in the positive x directio n. 539 * right by half the off interval. The line then goes in the positive x directio n.
470 */ 540 */
471 class DashingCircleEffect : public GrGeometryProcessor { 541 class DashingCircleEffect : public GrGeometryProcessor {
472 public: 542 public:
473 typedef SkPathEffect::DashInfo DashInfo; 543 typedef SkPathEffect::DashInfo DashInfo;
474 544
475 static GrGeometryProcessor* Create(GrColor, 545 static GrGeometryProcessor* Create(GrColor,
476 GrPrimitiveEdgeType edgeType, 546 GrPrimitiveEdgeType edgeType,
477 const DashInfo& info,
478 SkScalar radius,
479 const SkMatrix& localMatrix); 547 const SkMatrix& localMatrix);
480 548
481 virtual ~DashingCircleEffect(); 549 virtual ~DashingCircleEffect();
482 550
483 const char* name() const SK_OVERRIDE { return "DashingCircleEffect"; } 551 const char* name() const SK_OVERRIDE { return "DashingCircleEffect"; }
484 552
485 const Attribute* inPosition() const { return fInPosition; } 553 const Attribute* inPosition() const { return fInPosition; }
486 554
487 const Attribute* inCoord() const { return fInCoord; } 555 const Attribute* inDashParams() const { return fInDashParams; }
556
557 const Attribute* inCircleParams() const { return fInCircleParams; }
488 558
489 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } 559 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
490 560
491 SkScalar getRadius() const { return fRadius; }
492
493 SkScalar getCenterX() const { return fCenterX; }
494
495 SkScalar getIntervalLength() const { return fIntervalLength; }
496
497 virtual void getGLProcessorKey(const GrBatchTracker&, 561 virtual void getGLProcessorKey(const GrBatchTracker&,
498 const GrGLCaps&, 562 const GrGLCaps&,
499 GrProcessorKeyBuilder* b) const SK_OVERRIDE; 563 GrProcessorKeyBuilder* b) const SK_OVERRIDE;
500 564
501 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&, 565 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker&,
502 const GrGLCaps&) const SK_O VERRIDE; 566 const GrGLCaps&) const SK_O VERRIDE;
503 567
504 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const SK_OVERRIDE; 568 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const SK_OVERRIDE;
505 569
506 bool onCanMakeEqual(const GrBatchTracker&, 570 bool onCanMakeEqual(const GrBatchTracker&,
507 const GrGeometryProcessor&, 571 const GrGeometryProcessor&,
508 const GrBatchTracker&) const SK_OVERRIDE; 572 const GrBatchTracker&) const SK_OVERRIDE;
509 573
510 private: 574 private:
511 DashingCircleEffect(GrColor, GrPrimitiveEdgeType edgeType, const DashInfo& i nfo, 575 DashingCircleEffect(GrColor, GrPrimitiveEdgeType edgeType, const SkMatrix& l ocalMatrix);
512 SkScalar radius, const SkMatrix& localMatrix);
513 576
514 bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; 577 bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
515 578
516 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE; 579 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
517 580
518 GrPrimitiveEdgeType fEdgeType; 581 GrPrimitiveEdgeType fEdgeType;
519 const Attribute* fInPosition; 582 const Attribute* fInPosition;
520 const Attribute* fInCoord; 583 const Attribute* fInDashParams;
521 SkScalar fIntervalLength; 584 const Attribute* fInCircleParams;
522 SkScalar fRadius;
523 SkScalar fCenterX;
524 585
525 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 586 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
526 587
527 typedef GrGeometryProcessor INHERITED; 588 typedef GrGeometryProcessor INHERITED;
528 }; 589 };
529 590
530 ////////////////////////////////////////////////////////////////////////////// 591 //////////////////////////////////////////////////////////////////////////////
531 592
532 class GLDashingCircleEffect : public GrGLGeometryProcessor { 593 class GLDashingCircleEffect : public GrGLGeometryProcessor {
533 public: 594 public:
(...skipping 25 matching lines...) Expand all
559 fColor = GrColor_ILLEGAL; 620 fColor = GrColor_ILLEGAL;
560 fPrevRadius = SK_ScalarMin; 621 fPrevRadius = SK_ScalarMin;
561 fPrevCenterX = SK_ScalarMin; 622 fPrevCenterX = SK_ScalarMin;
562 fPrevIntervalLength = SK_ScalarMax; 623 fPrevIntervalLength = SK_ScalarMax;
563 } 624 }
564 625
565 void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { 626 void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
566 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); 627 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>();
567 const DashingCircleBatchTracker local = args.fBT.cast<DashingCircleBatchTrac ker>(); 628 const DashingCircleBatchTracker local = args.fBT.cast<DashingCircleBatchTrac ker>();
568 GrGLGPBuilder* pb = args.fPB; 629 GrGLGPBuilder* pb = args.fPB;
569 const char *paramName;
570 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co ord, and
571 // the total interval length of the dash.
572 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit y,
573 kVec3f_GrSLType, kDefault_GrSLPrecision ,
574 "params", &paramName);
575
576 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 630 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
577 631
578 // emit attributes 632 // emit attributes
579 vsBuilder->emitAttributes(dce); 633 vsBuilder->emitAttributes(dce);
580 634
581 GrGLVertToFrag v(kVec2f_GrSLType); 635 // XY are dashPos, Z is dashInterval
582 args.fPB->addVarying("Coord", &v); 636 GrGLVertToFrag dashParams(kVec3f_GrSLType);
583 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName); 637 args.fPB->addVarying("DashParam", &dashParams);
638 vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->f Name);
639
640 // xy, refer to circle radius - 0.5, z refers to cicles center x coord
641 GrGLVertToFrag circleParams(kVec2f_GrSLType);
642 args.fPB->addVarying("CircleParams", &circleParams);
643 vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams( )->fName);
584 644
585 // Setup pass through color 645 // Setup pass through color
586 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU LL, &fColorUniform); 646 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU LL, &fColorUniform);
587 647
588 // setup uniform viewMatrix 648 // setup uniform viewMatrix
589 this->addUniformViewMatrix(pb); 649 this->addUniformViewMatrix(pb);
590 650
591 // Setup position 651 // Setup position
592 SetupPosition(vsBuilder, gpArgs, dce.inPosition()->fName, dce.viewMatrix(), this->uViewM()); 652 SetupPosition(vsBuilder, gpArgs, dce.inPosition()->fName, dce.viewMatrix(), this->uViewM());
593 653
594 // emit transforms 654 // emit transforms
595 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName , dce.localMatrix(), 655 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName , dce.localMatrix(),
596 args.fTransformsIn, args.fTransformsOut); 656 args.fTransformsIn, args.fTransformsOut);
597 657
598 // transforms all points so that we can compare them to our test circle 658 // transforms all points so that we can compare them to our test circle
599 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 659 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
600 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s. z;\n", 660 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
601 v.fsIn(), v.fsIn(), paramName, paramName); 661 dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn (),
602 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", v.fsIn()); 662 dashParams.fsIn());
603 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); 663 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashPa rams.fsIn());
604 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n") ; 664 fsBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn() );
665 fsBuilder->codeAppend("float dist = length(center - fragPosShifted);");
605 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { 666 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) {
606 fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName); 667 fsBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn()) ;
607 fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n"); 668 fsBuilder->codeAppend("diff = 1.0 - diff;");
608 fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n"); 669 fsBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);");
609 } else { 670 } else {
610 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); 671 fsBuilder->codeAppendf("float alpha = 1.0;");
611 fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n", paramName); 672 fsBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circl eParams.fsIn());
612 } 673 }
613 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); 674 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
614 } 675 }
615 676
616 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman, 677 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman,
617 const GrPrimitiveProcessor& processor, 678 const GrPrimitiveProcessor& processor,
618 const GrBatchTracker& bt) { 679 const GrBatchTracker& bt) {
619 this->setUniformViewMatrix(pdman, processor.viewMatrix()); 680 this->setUniformViewMatrix(pdman, processor.viewMatrix());
620 681
621 const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
622 SkScalar radius = dce.getRadius();
623 SkScalar centerX = dce.getCenterX();
624 SkScalar intervalLength = dce.getIntervalLength();
625 if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fP revIntervalLength) {
626 pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength);
627 fPrevRadius = radius;
628 fPrevCenterX = centerX;
629 fPrevIntervalLength = intervalLength;
630 }
631
632 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( ); 682 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( );
633 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 683 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
634 GrGLfloat c[4]; 684 GrGLfloat c[4];
635 GrColorToRGBAFloat(local.fColor, c); 685 GrColorToRGBAFloat(local.fColor, c);
636 pdman.set4fv(fColorUniform, 1, c); 686 pdman.set4fv(fColorUniform, 1, c);
637 fColor = local.fColor; 687 fColor = local.fColor;
638 } 688 }
639 } 689 }
640 690
641 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, 691 void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp,
642 const GrBatchTracker& bt, 692 const GrBatchTracker& bt,
643 const GrGLCaps&, 693 const GrGLCaps&,
644 GrProcessorKeyBuilder* b) { 694 GrProcessorKeyBuilder* b) {
645 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( ); 695 const DashingCircleBatchTracker& local = bt.cast<DashingCircleBatchTracker>( );
646 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>(); 696 const DashingCircleEffect& dce = gp.cast<DashingCircleEffect>();
647 uint32_t key = 0; 697 uint32_t key = 0;
648 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0; 698 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0;
649 key |= ComputePosKey(gp.viewMatrix()) << 1; 699 key |= ComputePosKey(gp.viewMatrix()) << 1;
650 key |= dce.getEdgeType() << 8; 700 key |= dce.getEdgeType() << 8;
651 b->add32(key << 16 | local.fInputColorType); 701 b->add32(key << 16 | local.fInputColorType);
652 } 702 }
653 703
654 ////////////////////////////////////////////////////////////////////////////// 704 //////////////////////////////////////////////////////////////////////////////
655 705
656 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, 706 GrGeometryProcessor* DashingCircleEffect::Create(GrColor color,
657 GrPrimitiveEdgeType edgeType, 707 GrPrimitiveEdgeType edgeType,
658 const DashInfo& info,
659 SkScalar radius,
660 const SkMatrix& localMatrix) { 708 const SkMatrix& localMatrix) {
661 if (info.fCount != 2 || info.fIntervals[0] != 0) { 709 return SkNEW_ARGS(DashingCircleEffect, (color, edgeType, localMatrix));
662 return NULL;
663 }
664
665 return SkNEW_ARGS(DashingCircleEffect, (color, edgeType, info, radius, local Matrix));
666 } 710 }
667 711
668 DashingCircleEffect::~DashingCircleEffect() {} 712 DashingCircleEffect::~DashingCircleEffect() {}
669 713
670 void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* ou t) const { 714 void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* ou t) const {
671 out->setUnknownSingleComponent(); 715 out->setUnknownSingleComponent();
672 } 716 }
673 717
674 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt, 718 void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt,
675 const GrGLCaps& caps, 719 const GrGLCaps& caps,
676 GrProcessorKeyBuilder* b) const { 720 GrProcessorKeyBuilder* b) const {
677 GLDashingCircleEffect::GenKey(*this, bt, caps, b); 721 GLDashingCircleEffect::GenKey(*this, bt, caps, b);
678 } 722 }
679 723
680 GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack er& bt, 724 GrGLPrimitiveProcessor* DashingCircleEffect::createGLInstance(const GrBatchTrack er& bt,
681 const GrGLCaps&) c onst { 725 const GrGLCaps&) c onst {
682 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); 726 return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt));
683 } 727 }
684 728
685 DashingCircleEffect::DashingCircleEffect(GrColor color, 729 DashingCircleEffect::DashingCircleEffect(GrColor color,
686 GrPrimitiveEdgeType edgeType, 730 GrPrimitiveEdgeType edgeType,
687 const DashInfo& info,
688 SkScalar radius,
689 const SkMatrix& localMatrix) 731 const SkMatrix& localMatrix)
690 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { 732 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) {
691 this->initClassID<DashingCircleEffect>(); 733 this->initClassID<DashingCircleEffect>();
692 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); 734 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType));
693 fInCoord = &this->addVertexAttrib(Attribute("inCoord", kVec2f_GrVertexAttrib Type)); 735 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe rtexAttribType));
694 SkScalar onLen = info.fIntervals[0]; 736 fInCircleParams = &this->addVertexAttrib(Attribute("inCircleParams",
695 SkScalar offLen = info.fIntervals[1]; 737 kVec2f_GrVertexAttribType ));
696 fIntervalLength = onLen + offLen;
697 fRadius = radius;
698 fCenterX = SkScalarHalf(offLen);
699 } 738 }
700 739
701 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { 740 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const {
702 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); 741 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>();
703 return (fEdgeType == dce.fEdgeType && 742 return fEdgeType == dce.fEdgeType;
704 fIntervalLength == dce.fIntervalLength &&
705 fRadius == dce.fRadius &&
706 fCenterX == dce.fCenterX);
707 } 743 }
708 744
709 void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineI nfo& init) const { 745 void DashingCircleEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineI nfo& init) const {
710 DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>(); 746 DashingCircleBatchTracker* local = bt->cast<DashingCircleBatchTracker>();
711 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false); 747 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false);
712 local->fUsesLocalCoords = init.fUsesLocalCoords; 748 local->fUsesLocalCoords = init.fUsesLocalCoords;
713 } 749 }
714 750
715 bool DashingCircleEffect::onCanMakeEqual(const GrBatchTracker& m, 751 bool DashingCircleEffect::onCanMakeEqual(const GrBatchTracker& m,
716 const GrGeometryProcessor& that, 752 const GrGeometryProcessor& that,
717 const GrBatchTracker& t) const { 753 const GrBatchTracker& t) const {
718 const DashingCircleBatchTracker& mine = m.cast<DashingCircleBatchTracker>(); 754 const DashingCircleBatchTracker& mine = m.cast<DashingCircleBatchTracker>();
719 const DashingCircleBatchTracker& theirs = t.cast<DashingCircleBatchTracker>( ); 755 const DashingCircleBatchTracker& theirs = t.cast<DashingCircleBatchTracker>( );
720 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 756 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
721 that, theirs.fUsesLocalCoords) && 757 that, theirs.fUsesLocalCoords) &&
722 CanCombineOutput(mine.fInputColorType, mine.fColor, 758 CanCombineOutput(mine.fInputColorType, mine.fColor,
723 theirs.fInputColorType, theirs.fColor); 759 theirs.fInputColorType, theirs.fColor);
724 } 760 }
725 761
726 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect); 762 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect);
727 763
728 GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, 764 GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random,
729 GrContext*, 765 GrContext*,
730 const GrDrawTargetCaps& cap s, 766 const GrDrawTargetCaps& cap s,
731 GrTexture*[]) { 767 GrTexture*[]) {
732 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next ULessThan( 768 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next ULessThan(
733 kGrProcessorEdgeTypeCnt)); 769 kGrProcessorEdgeTypeCnt));
734 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f);
735 DashInfo info;
736 info.fCount = 2;
737 SkAutoTArray<SkScalar> intervals(info.fCount);
738 info.fIntervals = intervals.get();
739 info.fIntervals[0] = 0;
740 info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
741 info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]);
742
743 return DashingCircleEffect::Create(GrRandomColor(random), 770 return DashingCircleEffect::Create(GrRandomColor(random),
744 edgeType, info, strokeWidth, 771 edgeType, GrProcessorUnitTest::TestMatrix (random));
745 GrProcessorUnitTest::TestMatrix(random));
746 } 772 }
747 773
748 ////////////////////////////////////////////////////////////////////////////// 774 //////////////////////////////////////////////////////////////////////////////
749 775
750 class GLDashingLineEffect; 776 class GLDashingLineEffect;
751 777
752 struct DashingLineBatchTracker { 778 struct DashingLineBatchTracker {
753 GrGPInput fInputColorType; 779 GrGPInput fInputColorType;
754 GrColor fColor; 780 GrColor fColor;
755 bool fUsesLocalCoords; 781 bool fUsesLocalCoords;
756 }; 782 };
757 783
758 /* 784 /*
759 * This effect will draw a dashed line. The width of the dash is given by the st rokeWidth and the 785 * This effect will draw a dashed line. The width of the dash is given by the st rokeWidth and the
760 * length and spacing by the DashInfo. Both of the previous two parameters are i n device space. 786 * length and spacing by the DashInfo. Both of the previous two parameters are i n device space.
761 * This effect also requires the setting of a vec2 vertex attribute for the the four corners of the 787 * This effect also requires the setting of a vec2 vertex attribute for the the four corners of the
762 * bounding rect. This attribute is the "dash position" of each vertex. In other words it is the 788 * bounding rect. This attribute is the "dash position" of each vertex. In other words it is the
763 * vertex coords (in device space) if we transform the line to be horizontal, wi th the start of 789 * vertex coords (in device space) if we transform the line to be horizontal, wi th the start of
764 * line at the origin then shifted to the right by half the off interval. The li ne then goes in the 790 * line at the origin then shifted to the right by half the off interval. The li ne then goes in the
765 * positive x direction. 791 * positive x direction.
766 */ 792 */
767 class DashingLineEffect : public GrGeometryProcessor { 793 class DashingLineEffect : public GrGeometryProcessor {
768 public: 794 public:
769 typedef SkPathEffect::DashInfo DashInfo; 795 typedef SkPathEffect::DashInfo DashInfo;
770 796
771 static GrGeometryProcessor* Create(GrColor, 797 static GrGeometryProcessor* Create(GrColor,
772 GrPrimitiveEdgeType edgeType, 798 GrPrimitiveEdgeType edgeType,
773 const DashInfo& info,
774 SkScalar strokeWidth,
775 const SkMatrix& localMatrix); 799 const SkMatrix& localMatrix);
776 800
777 virtual ~DashingLineEffect(); 801 virtual ~DashingLineEffect();
778 802
779 const char* name() const SK_OVERRIDE { return "DashingEffect"; } 803 const char* name() const SK_OVERRIDE { return "DashingEffect"; }
780 804
781 const Attribute* inPosition() const { return fInPosition; } 805 const Attribute* inPosition() const { return fInPosition; }
782 806
783 const Attribute* inCoord() const { return fInCoord; } 807 const Attribute* inDashParams() const { return fInDashParams; }
808
809 const Attribute* inRectParams() const { return fInRectParams; }
784 810
785 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } 811 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
786 812
787 const SkRect& getRect() const { return fRect; }
788
789 SkScalar getIntervalLength() const { return fIntervalLength; }
790
791 virtual void getGLProcessorKey(const GrBatchTracker& bt, 813 virtual void getGLProcessorKey(const GrBatchTracker& bt,
792 const GrGLCaps& caps, 814 const GrGLCaps& caps,
793 GrProcessorKeyBuilder* b) const SK_OVERRIDE; 815 GrProcessorKeyBuilder* b) const SK_OVERRIDE;
794 816
795 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, 817 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
796 const GrGLCaps&) const SK_O VERRIDE; 818 const GrGLCaps&) const SK_O VERRIDE;
797 819
798 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const SK_OVERRIDE; 820 void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const SK_OVERRIDE;
799 821
800 bool onCanMakeEqual(const GrBatchTracker&, 822 bool onCanMakeEqual(const GrBatchTracker&,
801 const GrGeometryProcessor&, 823 const GrGeometryProcessor&,
802 const GrBatchTracker&) const SK_OVERRIDE; 824 const GrBatchTracker&) const SK_OVERRIDE;
803 825
804 private: 826 private:
805 DashingLineEffect(GrColor, GrPrimitiveEdgeType edgeType, const DashInfo& inf o, 827 DashingLineEffect(GrColor, GrPrimitiveEdgeType edgeType, const SkMatrix& loc alMatrix);
806 SkScalar strokeWidth, const SkMatrix& localMatrix);
807 828
808 bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; 829 bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
809 830
810 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE; 831 void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
811 832
812 GrPrimitiveEdgeType fEdgeType; 833 GrPrimitiveEdgeType fEdgeType;
813 const Attribute* fInPosition; 834 const Attribute* fInPosition;
814 const Attribute* fInCoord; 835 const Attribute* fInDashParams;
815 SkRect fRect; 836 const Attribute* fInRectParams;
816 SkScalar fIntervalLength;
817 837
818 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 838 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
819 839
820 typedef GrGeometryProcessor INHERITED; 840 typedef GrGeometryProcessor INHERITED;
821 }; 841 };
822 842
823 ////////////////////////////////////////////////////////////////////////////// 843 //////////////////////////////////////////////////////////////////////////////
824 844
825 class GLDashingLineEffect : public GrGLGeometryProcessor { 845 class GLDashingLineEffect : public GrGLGeometryProcessor {
826 public: 846 public:
827 GLDashingLineEffect(const GrGeometryProcessor&, const GrBatchTracker&); 847 GLDashingLineEffect(const GrGeometryProcessor&, const GrBatchTracker&);
828 848
829 void onEmitCode(EmitArgs&, GrGPArgs*) SK_OVERRIDE; 849 void onEmitCode(EmitArgs&, GrGPArgs*) SK_OVERRIDE;
830 850
831 static inline void GenKey(const GrGeometryProcessor&, 851 static inline void GenKey(const GrGeometryProcessor&,
832 const GrBatchTracker&, 852 const GrBatchTracker&,
833 const GrGLCaps&, 853 const GrGLCaps&,
834 GrProcessorKeyBuilder*); 854 GrProcessorKeyBuilder*);
835 855
836 virtual void setData(const GrGLProgramDataManager&, 856 virtual void setData(const GrGLProgramDataManager&,
837 const GrPrimitiveProcessor&, 857 const GrPrimitiveProcessor&,
838 const GrBatchTracker&) SK_OVERRIDE; 858 const GrBatchTracker&) SK_OVERRIDE;
839 859
840 private: 860 private:
841 GrColor fColor; 861 GrColor fColor;
842 UniformHandle fRectUniform;
843 UniformHandle fIntervalUniform;
844 UniformHandle fColorUniform; 862 UniformHandle fColorUniform;
845 SkRect fPrevRect;
846 SkScalar fPrevIntervalLength;
847 typedef GrGLGeometryProcessor INHERITED; 863 typedef GrGLGeometryProcessor INHERITED;
848 }; 864 };
849 865
850 GLDashingLineEffect::GLDashingLineEffect(const GrGeometryProcessor&, 866 GLDashingLineEffect::GLDashingLineEffect(const GrGeometryProcessor&,
851 const GrBatchTracker&) { 867 const GrBatchTracker&) {
852 fColor = GrColor_ILLEGAL; 868 fColor = GrColor_ILLEGAL;
853 fPrevRect.fLeft = SK_ScalarNaN;
854 fPrevIntervalLength = SK_ScalarMax;
855 } 869 }
856 870
857 void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { 871 void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
858 const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>(); 872 const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>();
859 const DashingLineBatchTracker& local = args.fBT.cast<DashingLineBatchTracker >(); 873 const DashingLineBatchTracker& local = args.fBT.cast<DashingLineBatchTracker >();
860 GrGLGPBuilder* pb = args.fPB; 874 GrGLGPBuilder* pb = args.fPB;
861 const char *rectName;
862 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5),
863 // respectively.
864 fRectUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility ,
865 kVec4f_GrSLType, kDefault_GrSLPrecision,
866 "rect",
867 &rectName);
868 const char *intervalName;
869 // The interval uniform's refers to the total length of the interval (on + o ff)
870 fIntervalUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibi lity,
871 kFloat_GrSLType, kDefault_GrSLPrecis ion,
872 "interval",
873 &intervalName);
874
875 875
876 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 876 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
877 877
878 // emit attributes 878 // emit attributes
879 vsBuilder->emitAttributes(de); 879 vsBuilder->emitAttributes(de);
880 880
881 GrGLVertToFrag v(kVec2f_GrSLType); 881 // XY refers to dashPos, Z is the dash interval length
882 args.fPB->addVarying("Coord", &v); 882 GrGLVertToFrag inDashParams(kVec3f_GrSLType);
883 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName); 883 args.fPB->addVarying("DashParams", &inDashParams);
884 vsBuilder->codeAppendf("%s = %s;", inDashParams.vsOut(), de.inDashParams()-> fName);
885
886 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5),
887 // respectively.
888 GrGLVertToFrag inRectParams(kVec4f_GrSLType);
889 args.fPB->addVarying("RectParams", &inRectParams);
890 vsBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()-> fName);
884 891
885 // Setup pass through color 892 // Setup pass through color
886 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU LL, &fColorUniform); 893 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NU LL, &fColorUniform);
887 894
888 // setup uniform viewMatrix 895 // setup uniform viewMatrix
889 this->addUniformViewMatrix(pb); 896 this->addUniformViewMatrix(pb);
890 897
891 // Setup position 898 // Setup position
892 SetupPosition(vsBuilder, gpArgs, de.inPosition()->fName, de.viewMatrix(), th is->uViewM()); 899 SetupPosition(vsBuilder, gpArgs, de.inPosition()->fName, de.viewMatrix(), th is->uViewM());
893 900
894 // emit transforms 901 // emit transforms
895 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(), 902 this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(),
896 args.fTransformsIn, args.fTransformsOut); 903 args.fTransformsIn, args.fTransformsOut);
897 904
898 // transforms all points so that we can compare them to our test rect 905 // transforms all points so that we can compare them to our test rect
899 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 906 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
900 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n ", 907 fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
901 v.fsIn(), v.fsIn(), intervalName, intervalName); 908 inDashParams.fsIn(), inDashParams.fsIn(), inDashParam s.fsIn(),
902 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", v.fsIn()); 909 inDashParams.fsIn());
910 fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDash Params.fsIn());
903 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { 911 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) {
904 // The amount of coverage removed in x and y by the edges is computed as a pair of negative 912 // The amount of coverage removed in x and y by the edges is computed as a pair of negative
905 // numbers, xSub and ySub. 913 // numbers, xSub and ySub.
906 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); 914 fsBuilder->codeAppend("float xSub, ySub;");
907 fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n" , rectName); 915 fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRe ctParams.fsIn());
908 fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n ", rectName); 916 fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inR ectParams.fsIn());
909 fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n" , rectName); 917 fsBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRe ctParams.fsIn());
910 fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n ", rectName); 918 fsBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inR ectParams.fsIn());
911 // Now compute coverage in x and y and multiply them to get the fraction of the pixel 919 // Now compute coverage in x and y and multiply them to get the fraction of the pixel
912 // covered. 920 // covered.
913 fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); 921 fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m ax(ySub, -1.0));");
914 } else { 922 } else {
915 // Assuming the bounding geometry is tight so no need to check y values 923 // Assuming the bounding geometry is tight so no need to check y values
916 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); 924 fsBuilder->codeAppendf("float alpha = 1.0;");
917 fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName); 925 fsBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;",
918 fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;\n", rectName); 926 inRectParams.fsIn());
927 fsBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;",
928 inRectParams.fsIn());
919 } 929 }
920 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); 930 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
921 } 931 }
922 932
923 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, 933 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman,
924 const GrPrimitiveProcessor& processor, 934 const GrPrimitiveProcessor& processor,
925 const GrBatchTracker& bt) { 935 const GrBatchTracker& bt) {
926 this->setUniformViewMatrix(pdman, processor.viewMatrix()); 936 this->setUniformViewMatrix(pdman, processor.viewMatrix());
927 937
928 const DashingLineEffect& de = processor.cast<DashingLineEffect>();
929 const SkRect& rect = de.getRect();
930 SkScalar intervalLength = de.getIntervalLength();
931 if (rect != fPrevRect || intervalLength != fPrevIntervalLength) {
932 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f,
933 rect.fRight - 0.5f, rect.fBottom - 0.5f);
934 pdman.set1f(fIntervalUniform, intervalLength);
935 fPrevRect = rect;
936 fPrevIntervalLength = intervalLength;
937 }
938
939 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); 938 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>();
940 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 939 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
941 GrGLfloat c[4]; 940 GrGLfloat c[4];
942 GrColorToRGBAFloat(local.fColor, c); 941 GrColorToRGBAFloat(local.fColor, c);
943 pdman.set4fv(fColorUniform, 1, c); 942 pdman.set4fv(fColorUniform, 1, c);
944 fColor = local.fColor; 943 fColor = local.fColor;
945 } 944 }
946 } 945 }
947 946
948 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, 947 void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp,
949 const GrBatchTracker& bt, 948 const GrBatchTracker& bt,
950 const GrGLCaps&, 949 const GrGLCaps&,
951 GrProcessorKeyBuilder* b) { 950 GrProcessorKeyBuilder* b) {
952 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>(); 951 const DashingLineBatchTracker& local = bt.cast<DashingLineBatchTracker>();
953 const DashingLineEffect& de = gp.cast<DashingLineEffect>(); 952 const DashingLineEffect& de = gp.cast<DashingLineEffect>();
954 uint32_t key = 0; 953 uint32_t key = 0;
955 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0; 954 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 : 0 x0;
956 key |= ComputePosKey(gp.viewMatrix()) << 1; 955 key |= ComputePosKey(gp.viewMatrix()) << 1;
957 key |= de.getEdgeType() << 8; 956 key |= de.getEdgeType() << 8;
958 b->add32(key << 16 | local.fInputColorType); 957 b->add32(key << 16 | local.fInputColorType);
959 } 958 }
960 959
961 ////////////////////////////////////////////////////////////////////////////// 960 //////////////////////////////////////////////////////////////////////////////
962 961
963 GrGeometryProcessor* DashingLineEffect::Create(GrColor color, 962 GrGeometryProcessor* DashingLineEffect::Create(GrColor color,
964 GrPrimitiveEdgeType edgeType, 963 GrPrimitiveEdgeType edgeType,
965 const DashInfo& info,
966 SkScalar strokeWidth,
967 const SkMatrix& localMatrix) { 964 const SkMatrix& localMatrix) {
968 if (info.fCount != 2) { 965 return SkNEW_ARGS(DashingLineEffect, (color, edgeType, localMatrix));
969 return NULL;
970 }
971
972 return SkNEW_ARGS(DashingLineEffect, (color, edgeType, info, strokeWidth, lo calMatrix));
973 } 966 }
974 967
975 DashingLineEffect::~DashingLineEffect() {} 968 DashingLineEffect::~DashingLineEffect() {}
976 969
977 void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 970 void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
978 out->setUnknownSingleComponent(); 971 out->setUnknownSingleComponent();
979 } 972 }
980 973
981 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt, 974 void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt,
982 const GrGLCaps& caps, 975 const GrGLCaps& caps,
983 GrProcessorKeyBuilder* b) const { 976 GrProcessorKeyBuilder* b) const {
984 GLDashingLineEffect::GenKey(*this, bt, caps, b); 977 GLDashingLineEffect::GenKey(*this, bt, caps, b);
985 } 978 }
986 979
987 GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker & bt, 980 GrGLPrimitiveProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker & bt,
988 const GrGLCaps&) con st { 981 const GrGLCaps&) con st {
989 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); 982 return SkNEW_ARGS(GLDashingLineEffect, (*this, bt));
990 } 983 }
991 984
992 DashingLineEffect::DashingLineEffect(GrColor color, 985 DashingLineEffect::DashingLineEffect(GrColor color,
993 GrPrimitiveEdgeType edgeType, 986 GrPrimitiveEdgeType edgeType,
994 const DashInfo& info,
995 SkScalar strokeWidth,
996 const SkMatrix& localMatrix) 987 const SkMatrix& localMatrix)
997 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) { 988 : INHERITED(color, SkMatrix::I(), localMatrix), fEdgeType(edgeType) {
998 this->initClassID<DashingLineEffect>(); 989 this->initClassID<DashingLineEffect>();
999 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType)); 990 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex AttribType));
1000 fInCoord = &this->addVertexAttrib(Attribute("inCoord", kVec2f_GrVertexAttrib Type)); 991 fInDashParams = &this->addVertexAttrib(Attribute("inDashParams", kVec3f_GrVe rtexAttribType));
1001 SkScalar onLen = info.fIntervals[0]; 992 fInRectParams = &this->addVertexAttrib(Attribute("inRect", kVec4f_GrVertexAt tribType));
1002 SkScalar offLen = info.fIntervals[1];
1003 SkScalar halfOffLen = SkScalarHalf(offLen);
1004 SkScalar halfStroke = SkScalarHalf(strokeWidth);
1005 fIntervalLength = onLen + offLen;
1006 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke);
1007 } 993 }
1008 994
1009 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { 995 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const {
1010 const DashingLineEffect& de = other.cast<DashingLineEffect>(); 996 const DashingLineEffect& de = other.cast<DashingLineEffect>();
1011 return (fEdgeType == de.fEdgeType && 997 return fEdgeType == de.fEdgeType;
1012 fRect == de.fRect &&
1013 fIntervalLength == de.fIntervalLength);
1014 } 998 }
1015 999
1016 void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInf o& init) const { 1000 void DashingLineEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInf o& init) const {
1017 DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>(); 1001 DashingLineBatchTracker* local = bt->cast<DashingLineBatchTracker>();
1018 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false); 1002 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), in it, false);
1019 local->fUsesLocalCoords = init.fUsesLocalCoords; 1003 local->fUsesLocalCoords = init.fUsesLocalCoords;
1020 } 1004 }
1021 1005
1022 bool DashingLineEffect::onCanMakeEqual(const GrBatchTracker& m, 1006 bool DashingLineEffect::onCanMakeEqual(const GrBatchTracker& m,
1023 const GrGeometryProcessor& that, 1007 const GrGeometryProcessor& that,
1024 const GrBatchTracker& t) const { 1008 const GrBatchTracker& t) const {
1025 const DashingLineBatchTracker& mine = m.cast<DashingLineBatchTracker>(); 1009 const DashingLineBatchTracker& mine = m.cast<DashingLineBatchTracker>();
1026 const DashingLineBatchTracker& theirs = t.cast<DashingLineBatchTracker>(); 1010 const DashingLineBatchTracker& theirs = t.cast<DashingLineBatchTracker>();
1027 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 1011 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
1028 that, theirs.fUsesLocalCoords) && 1012 that, theirs.fUsesLocalCoords) &&
1029 CanCombineOutput(mine.fInputColorType, mine.fColor, 1013 CanCombineOutput(mine.fInputColorType, mine.fColor,
1030 theirs.fInputColorType, theirs.fColor); 1014 theirs.fInputColorType, theirs.fColor);
1031 } 1015 }
1032 1016
1033 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect); 1017 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect);
1034 1018
1035 GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, 1019 GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random,
1036 GrContext*, 1020 GrContext*,
1037 const GrDrawTargetCaps& caps, 1021 const GrDrawTargetCaps& caps,
1038 GrTexture*[]) { 1022 GrTexture*[]) {
1039 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next ULessThan( 1023 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->next ULessThan(
1040 kGrProcessorEdgeTypeCnt)); 1024 kGrProcessorEdgeTypeCnt));
1041 SkScalar strokeWidth = random->nextRangeScalar(0, 100.f);
1042 DashInfo info;
1043 info.fCount = 2;
1044 SkAutoTArray<SkScalar> intervals(info.fCount);
1045 info.fIntervals = intervals.get();
1046 info.fIntervals[0] = random->nextRangeScalar(0, 10.f);
1047 info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
1048 info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fInterval s[1]);
1049 1025
1050 return DashingLineEffect::Create(GrRandomColor(random), 1026 return DashingLineEffect::Create(GrRandomColor(random),
1051 edgeType, info, strokeWidth, 1027 edgeType, GrProcessorUnitTest::TestMatrix(r andom));
1052 GrProcessorUnitTest::TestMatrix(random));
1053 } 1028 }
1054 1029
1055 ////////////////////////////////////////////////////////////////////////////// 1030 //////////////////////////////////////////////////////////////////////////////
1056 1031
1057 GrGeometryProcessor* GrDashingEffect::Create(GrColor color, 1032 static GrGeometryProcessor* create_dash_gp(GrColor color,
1058 GrPrimitiveEdgeType edgeType, 1033 GrPrimitiveEdgeType edgeType,
1059 const SkPathEffect::DashInfo& info, 1034 DashCap cap,
1060 SkScalar strokeWidth, 1035 const SkMatrix& localMatrix) {
1061 GrDashingEffect::DashCap cap,
1062 const SkMatrix& localMatrix) {
1063 switch (cap) { 1036 switch (cap) {
1064 case GrDashingEffect::kRound_DashCap: 1037 case kRound_DashCap:
1065 return DashingCircleEffect::Create(color, edgeType, info, 1038 return DashingCircleEffect::Create(color, edgeType, localMatrix);
1066 SkScalarHalf(strokeWidth), 1039 case kNonRound_DashCap:
1067 localMatrix); 1040 return DashingLineEffect::Create(color, edgeType, localMatrix);
1068 case GrDashingEffect::kNonRound_DashCap:
1069 return DashingLineEffect::Create(color, edgeType, info, strokeWidth, localMatrix);
1070 default: 1041 default:
1071 SkFAIL("Unexpected dashed cap."); 1042 SkFAIL("Unexpected dashed cap.");
1072 } 1043 }
1073 return NULL; 1044 return NULL;
1074 } 1045 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDashingEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698