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 "../GrAARectRenderer.h" | 10 #include "../GrAARectRenderer.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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", ¶mName); | |
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 } |
OLD | NEW |