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