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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); | 58 SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); |
59 // Current we do don't handle Round or Square cap dashes | 59 // Current we do don't handle Round or Square cap dashes |
60 if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { | 60 if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { |
61 return false; | 61 return false; |
62 } | 62 } |
63 | 63 |
64 return true; | 64 return true; |
65 } | 65 } |
66 | 66 |
67 namespace { | 67 namespace { |
68 | |
69 struct DashLineVertex { | 68 struct DashLineVertex { |
70 SkPoint fPos; | 69 SkPoint fPos; |
71 SkPoint fDashPos; | 70 SkPoint fDashPos; |
72 }; | 71 }; |
73 | |
74 extern const GrVertexAttrib gDashLineVertexAttribs[] = { | |
75 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind
ing }, | |
76 { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexA
ttribBinding }, | |
77 }; | 72 }; |
78 | 73 |
79 }; | |
80 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, | 74 static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale, |
81 const SkMatrix& viewMatrix, const SkPoint pts[2]) { | 75 const SkMatrix& viewMatrix, const SkPoint pts[2]) { |
82 SkVector vecSrc = pts[1] - pts[0]; | 76 SkVector vecSrc = pts[1] - pts[0]; |
83 SkScalar magSrc = vecSrc.length(); | 77 SkScalar magSrc = vecSrc.length(); |
84 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; | 78 SkScalar invSrc = magSrc ? SkScalarInvert(magSrc) : 0; |
85 vecSrc.scale(invSrc); | 79 vecSrc.scale(invSrc); |
86 | 80 |
87 SkVector vecSrcPerp; | 81 SkVector vecSrcPerp; |
88 vecSrc.rotateCW(&vecSrcPerp); | 82 vecSrc.rotateCW(&vecSrcPerp); |
89 viewMatrix.mapVectors(&vecSrc, 1); | 83 viewMatrix.mapVectors(&vecSrc, 1); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 lineDone = true; | 328 lineDone = true; |
335 | 329 |
336 SkPoint devicePts[2]; | 330 SkPoint devicePts[2]; |
337 vm.mapPoints(devicePts, ptsRot, 2); | 331 vm.mapPoints(devicePts, ptsRot, 2); |
338 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); | 332 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
339 if (hasCap) { | 333 if (hasCap) { |
340 lineLength += 2.f * halfDevStroke; | 334 lineLength += 2.f * halfDevStroke; |
341 } | 335 } |
342 devIntervals[0] = lineLength; | 336 devIntervals[0] = lineLength; |
343 } | 337 } |
| 338 |
| 339 const GrGeometryProcessor* gp; |
344 bool fullDash = devIntervals[1] > 0.f || useAA; | 340 bool fullDash = devIntervals[1] > 0.f || useAA; |
345 if (fullDash) { | 341 if (fullDash) { |
346 SkPathEffect::DashInfo devInfo; | 342 SkPathEffect::DashInfo devInfo; |
347 devInfo.fPhase = devPhase; | 343 devInfo.fPhase = devPhase; |
348 devInfo.fCount = 2; | 344 devInfo.fCount = 2; |
349 devInfo.fIntervals = devIntervals; | 345 devInfo.fIntervals = devIntervals; |
350 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : | 346 GrPrimitiveEdgeType edgeType= useAA ? kFillAA_GrProcessorEdgeType : |
351 kFillBW_GrProcessorEdgeType; | 347 kFillBW_GrProcessorEdgeType; |
352 bool isRoundCap = SkPaint::kRound_Cap == cap; | 348 bool isRoundCap = SkPaint::kRound_Cap == cap; |
353 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_
DashCap : | 349 GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_
DashCap : |
354 GrDashingEffect::kNonRou
nd_DashCap; | 350 GrDashingEffect::kNonRou
nd_DashCap; |
355 drawState->setGeometryProcessor( | 351 gp = GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType); |
356 GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType)
)->unref(); | |
357 | |
358 // Set up the vertex data for the line and start/end dashes | |
359 drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDash
LineVertexAttribs), | |
360 sizeof(DashLineVerte
x)); | |
361 } else { | 352 } else { |
362 // Set up the vertex data for the line and start/end dashes | 353 // Set up the vertex data for the line and start/end dashes |
363 drawState->setGeometryProcessor( | 354 gp = GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_
GPType); |
364 GrDefaultGeoProcFactory::CreateAndSetAttribs( | |
365 drawState, | |
366 GrDefaultGeoProcFactory::kPosition_GPType))->unref(); | |
367 } | 355 } |
368 | 356 |
| 357 drawState->setGeometryProcessor(gp)->unref(); |
| 358 |
369 int totalRectCnt = 0; | 359 int totalRectCnt = 0; |
370 | 360 |
371 totalRectCnt += !lineDone ? 1 : 0; | 361 totalRectCnt += !lineDone ? 1 : 0; |
372 totalRectCnt += hasStartRect ? 1 : 0; | 362 totalRectCnt += hasStartRect ? 1 : 0; |
373 totalRectCnt += hasEndRect ? 1 : 0; | 363 totalRectCnt += hasEndRect ? 1 : 0; |
374 | 364 |
375 GrDrawTarget::AutoReleaseGeometry geo(target, | 365 GrDrawTarget::AutoReleaseGeometry geo(target, |
376 totalRectCnt * 4, | 366 totalRectCnt * 4, |
377 drawState->getVertexStride(), 0); | 367 gp->getVertexStride(), 0); |
378 if (!geo.succeeded()) { | 368 if (!geo.succeeded()) { |
379 SkDebugf("Failed to get space for vertices!\n"); | 369 SkDebugf("Failed to get space for vertices!\n"); |
380 return false; | 370 return false; |
381 } | 371 } |
382 | 372 |
383 int curVIdx = 0; | 373 int curVIdx = 0; |
384 | 374 |
385 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { | 375 if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) { |
386 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices | 376 // need to adjust this for round caps to correctly set the dashPos attri
b on vertices |
387 startOffset -= halfDevStroke; | 377 startOffset -= halfDevStroke; |
388 } | 378 } |
389 | 379 |
390 // Draw interior part of dashed line | 380 // Draw interior part of dashed line |
391 if (!lineDone) { | 381 if (!lineDone) { |
392 SkPoint devicePts[2]; | 382 SkPoint devicePts[2]; |
393 vm.mapPoints(devicePts, ptsRot, 2); | 383 vm.mapPoints(devicePts, ptsRot, 2); |
394 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); | 384 SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]); |
395 if (hasCap) { | 385 if (hasCap) { |
396 lineLength += 2.f * halfDevStroke; | 386 lineLength += 2.f * halfDevStroke; |
397 } | 387 } |
398 | 388 |
399 SkRect bounds; | 389 SkRect bounds; |
400 bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); | 390 bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY); |
401 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); | 391 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke); |
402 if (fullDash) { | 392 if (fullDash) { |
403 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); | 393 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); |
| 394 SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex)); |
404 setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffse
t, devBloat, | 395 setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffse
t, devBloat, |
405 lineLength, halfDevStroke); | 396 lineLength, halfDevStroke); |
406 } else { | 397 } else { |
407 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); | 398 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); |
| 399 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
408 setup_dashed_rect_pos(bounds, curVIdx, combinedMatrix, verts); | 400 setup_dashed_rect_pos(bounds, curVIdx, combinedMatrix, verts); |
409 } | 401 } |
410 curVIdx += 4; | 402 curVIdx += 4; |
411 } | 403 } |
412 | 404 |
413 if (hasStartRect) { | 405 if (hasStartRect) { |
414 SkASSERT(useAA); // so that we know bloatX and bloatY have been set | 406 SkASSERT(useAA); // so that we know bloatX and bloatY have been set |
415 startRect.outset(bloatX, bloatY); | 407 startRect.outset(bloatX, bloatY); |
416 if (fullDash) { | 408 if (fullDash) { |
417 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); | 409 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); |
| 410 SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex)); |
418 setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOf
fset, devBloat, | 411 setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOf
fset, devBloat, |
419 devIntervals[0], halfDevStroke); | 412 devIntervals[0], halfDevStroke); |
420 } else { | 413 } else { |
421 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); | 414 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); |
| 415 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
422 setup_dashed_rect_pos(startRect, curVIdx, combinedMatrix, verts); | 416 setup_dashed_rect_pos(startRect, curVIdx, combinedMatrix, verts); |
423 } | 417 } |
424 | 418 |
425 curVIdx += 4; | 419 curVIdx += 4; |
426 } | 420 } |
427 | 421 |
428 if (hasEndRect) { | 422 if (hasEndRect) { |
429 SkASSERT(useAA); // so that we know bloatX and bloatY have been set | 423 SkASSERT(useAA); // so that we know bloatX and bloatY have been set |
430 endRect.outset(bloatX, bloatY); | 424 endRect.outset(bloatX, bloatY); |
431 if (fullDash) { | 425 if (fullDash) { |
432 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); | 426 DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertic
es()); |
| 427 SkASSERT(gp->getVertexStride() == sizeof(DashLineVertex)); |
433 setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffs
et, devBloat, | 428 setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffs
et, devBloat, |
434 devIntervals[0], halfDevStroke); | 429 devIntervals[0], halfDevStroke); |
435 } else { | 430 } else { |
436 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); | 431 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices()); |
| 432 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); |
437 setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts); | 433 setup_dashed_rect_pos(endRect, curVIdx, combinedMatrix, verts); |
438 } | 434 } |
439 | 435 |
440 } | 436 } |
441 | 437 |
442 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); | 438 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); |
443 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, totalRec
tCnt, 4, 6); | 439 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, totalRec
tCnt, 4, 6); |
444 target->resetIndexSource(); | 440 target->resetIndexSource(); |
445 return true; | 441 return true; |
446 } | 442 } |
(...skipping 15 matching lines...) Expand all Loading... |
462 typedef SkPathEffect::DashInfo DashInfo; | 458 typedef SkPathEffect::DashInfo DashInfo; |
463 | 459 |
464 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, | 460 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, |
465 const DashInfo& info, | 461 const DashInfo& info, |
466 SkScalar radius); | 462 SkScalar radius); |
467 | 463 |
468 virtual ~DashingCircleEffect(); | 464 virtual ~DashingCircleEffect(); |
469 | 465 |
470 static const char* Name() { return "DashingCircleEffect"; } | 466 static const char* Name() { return "DashingCircleEffect"; } |
471 | 467 |
472 const GrShaderVar& inCoord() const { return fInCoord; } | 468 const GrAttribute* inPosition() const { return fInPosition; } |
| 469 |
| 470 const GrAttribute* inCoord() const { return fInCoord; } |
473 | 471 |
474 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 472 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } |
475 | 473 |
476 SkScalar getRadius() const { return fRadius; } | 474 SkScalar getRadius() const { return fRadius; } |
477 | 475 |
478 SkScalar getCenterX() const { return fCenterX; } | 476 SkScalar getCenterX() const { return fCenterX; } |
479 | 477 |
480 SkScalar getIntervalLength() const { return fIntervalLength; } | 478 SkScalar getIntervalLength() const { return fIntervalLength; } |
481 | 479 |
482 typedef GLDashingCircleEffect GLProcessor; | 480 typedef GLDashingCircleEffect GLProcessor; |
483 | 481 |
484 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; | 482 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; |
485 | 483 |
486 private: | 484 private: |
487 DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkSc
alar radius); | 485 DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkSc
alar radius); |
488 | 486 |
489 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; | 487 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; |
490 | 488 |
491 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; | 489 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; |
492 | 490 |
493 GrPrimitiveEdgeType fEdgeType; | 491 GrPrimitiveEdgeType fEdgeType; |
494 const GrShaderVar& fInCoord; | 492 const GrAttribute* fInPosition; |
| 493 const GrAttribute* fInCoord; |
495 SkScalar fIntervalLength; | 494 SkScalar fIntervalLength; |
496 SkScalar fRadius; | 495 SkScalar fRadius; |
497 SkScalar fCenterX; | 496 SkScalar fCenterX; |
498 | 497 |
499 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 498 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
500 | 499 |
501 typedef GrGeometryProcessor INHERITED; | 500 typedef GrGeometryProcessor INHERITED; |
502 }; | 501 }; |
503 | 502 |
504 ////////////////////////////////////////////////////////////////////////////// | 503 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 27 matching lines...) Expand all Loading... |
532 void GLDashingCircleEffect::emitCode(const EmitArgs& args) { | 531 void GLDashingCircleEffect::emitCode(const EmitArgs& args) { |
533 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); | 532 const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); |
534 const char *paramName; | 533 const char *paramName; |
535 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co
ord, and | 534 // The param uniforms, xyz, refer to circle radius - 0.5, cicles center x co
ord, and |
536 // the total interval length of the dash. | 535 // the total interval length of the dash. |
537 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, | 536 fParamUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibilit
y, |
538 kVec3f_GrSLType, | 537 kVec3f_GrSLType, |
539 "params", | 538 "params", |
540 ¶mName); | 539 ¶mName); |
541 | 540 |
| 541 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 542 |
542 GrGLVertToFrag v(kVec2f_GrSLType); | 543 GrGLVertToFrag v(kVec2f_GrSLType); |
543 args.fPB->addVarying("Coord", &v); | 544 args.fPB->addVarying("Coord", &v); |
| 545 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dce.inCoord()->fName); |
544 | 546 |
545 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 547 // setup coord outputs |
546 vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str()); | 548 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), dce.inPositi
on()->fName); |
| 549 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), dce.inPosition(
)->fName); |
547 | 550 |
548 // setup position varying | 551 // setup position varying |
549 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), | 552 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), |
550 vsBuilder->inPosition()); | 553 dce.inPosition()->fName); |
551 | 554 |
552 // transforms all points so that we can compare them to our test circle | 555 // transforms all points so that we can compare them to our test circle |
553 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 556 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
554 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.
z;\n", | 557 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.
z;\n", |
555 v.fsIn(), v.fsIn(), paramName, paramName); | 558 v.fsIn(), v.fsIn(), paramName, paramName); |
556 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); | 559 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); |
557 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); | 560 fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName); |
558 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n")
; | 561 fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n")
; |
559 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { | 562 if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) { |
560 fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName); | 563 fsBuilder->codeAppendf("\t\tfloat diff = dist - %s.x;\n", paramName); |
561 fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n"); | 564 fsBuilder->codeAppend("\t\tdiff = 1.0 - diff;\n"); |
562 fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n"); | 565 fsBuilder->codeAppend("\t\tfloat alpha = clamp(diff, 0.0, 1.0);\n"); |
563 } else { | 566 } else { |
564 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); | 567 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); |
565 fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n",
paramName); | 568 fsBuilder->codeAppendf("\t\talpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;\n",
paramName); |
566 } | 569 } |
567 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutput, | 570 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
568 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("alpha")).c_s
tr()); | |
569 } | 571 } |
570 | 572 |
571 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman | 573 void GLDashingCircleEffect::setData(const GrGLProgramDataManager& pdman |
572 , const GrProcessor& processor) { | 574 , const GrProcessor& processor) { |
573 const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); | 575 const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>(); |
574 SkScalar radius = dce.getRadius(); | 576 SkScalar radius = dce.getRadius(); |
575 SkScalar centerX = dce.getCenterX(); | 577 SkScalar centerX = dce.getCenterX(); |
576 SkScalar intervalLength = dce.getIntervalLength(); | 578 SkScalar intervalLength = dce.getIntervalLength(); |
577 if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fP
revIntervalLength) { | 579 if (radius != fPrevRadius || centerX != fPrevCenterX || intervalLength != fP
revIntervalLength) { |
578 pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength); | 580 pdman.set3f(fParamUniform, radius - 0.5f, centerX, intervalLength); |
(...skipping 25 matching lines...) Expand all Loading... |
604 void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) con
st { | 606 void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) con
st { |
605 inout->mulByUnknownAlpha(); | 607 inout->mulByUnknownAlpha(); |
606 } | 608 } |
607 | 609 |
608 const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const
{ | 610 const GrBackendGeometryProcessorFactory& DashingCircleEffect::getFactory() const
{ |
609 return GrTBackendGeometryProcessorFactory<DashingCircleEffect>::getInstance(
); | 611 return GrTBackendGeometryProcessorFactory<DashingCircleEffect>::getInstance(
); |
610 } | 612 } |
611 | 613 |
612 DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const Das
hInfo& info, | 614 DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const Das
hInfo& info, |
613 SkScalar radius) | 615 SkScalar radius) |
614 : fEdgeType(edgeType) | 616 : fEdgeType(edgeType) { |
615 , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord", | 617 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); |
616 kVec2f_GrSLType, | 618 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); |
617 GrShaderVar::kAttribute_TypeMod
ifier))) { | |
618 SkScalar onLen = info.fIntervals[0]; | 619 SkScalar onLen = info.fIntervals[0]; |
619 SkScalar offLen = info.fIntervals[1]; | 620 SkScalar offLen = info.fIntervals[1]; |
620 fIntervalLength = onLen + offLen; | 621 fIntervalLength = onLen + offLen; |
621 fRadius = radius; | 622 fRadius = radius; |
622 fCenterX = SkScalarHalf(offLen); | 623 fCenterX = SkScalarHalf(offLen); |
623 } | 624 } |
624 | 625 |
625 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { | 626 bool DashingCircleEffect::onIsEqual(const GrGeometryProcessor& other) const { |
626 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); | 627 const DashingCircleEffect& dce = other.cast<DashingCircleEffect>(); |
627 return (fEdgeType == dce.fEdgeType && | 628 return (fEdgeType == dce.fEdgeType && |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 typedef SkPathEffect::DashInfo DashInfo; | 669 typedef SkPathEffect::DashInfo DashInfo; |
669 | 670 |
670 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, | 671 static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, |
671 const DashInfo& info, | 672 const DashInfo& info, |
672 SkScalar strokeWidth); | 673 SkScalar strokeWidth); |
673 | 674 |
674 virtual ~DashingLineEffect(); | 675 virtual ~DashingLineEffect(); |
675 | 676 |
676 static const char* Name() { return "DashingEffect"; } | 677 static const char* Name() { return "DashingEffect"; } |
677 | 678 |
678 const GrShaderVar& inCoord() const { return fInCoord; } | 679 const GrAttribute* inPosition() const { return fInPosition; } |
| 680 |
| 681 const GrAttribute* inCoord() const { return fInCoord; } |
679 | 682 |
680 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } | 683 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } |
681 | 684 |
682 const SkRect& getRect() const { return fRect; } | 685 const SkRect& getRect() const { return fRect; } |
683 | 686 |
684 SkScalar getIntervalLength() const { return fIntervalLength; } | 687 SkScalar getIntervalLength() const { return fIntervalLength; } |
685 | 688 |
686 typedef GLDashingLineEffect GLProcessor; | 689 typedef GLDashingLineEffect GLProcessor; |
687 | 690 |
688 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; | 691 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE; |
689 | 692 |
690 private: | 693 private: |
691 DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScal
ar strokeWidth); | 694 DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScal
ar strokeWidth); |
692 | 695 |
693 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; | 696 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; |
694 | 697 |
695 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; | 698 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE; |
696 | 699 |
697 GrPrimitiveEdgeType fEdgeType; | 700 GrPrimitiveEdgeType fEdgeType; |
698 const GrShaderVar& fInCoord; | 701 const GrAttribute* fInPosition; |
| 702 const GrAttribute* fInCoord; |
699 SkRect fRect; | 703 SkRect fRect; |
700 SkScalar fIntervalLength; | 704 SkScalar fIntervalLength; |
701 | 705 |
702 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; | 706 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
703 | 707 |
704 typedef GrGeometryProcessor INHERITED; | 708 typedef GrGeometryProcessor INHERITED; |
705 }; | 709 }; |
706 | 710 |
707 ////////////////////////////////////////////////////////////////////////////// | 711 ////////////////////////////////////////////////////////////////////////////// |
708 | 712 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 kVec4f_GrSLType, | 744 kVec4f_GrSLType, |
741 "rect", | 745 "rect", |
742 &rectName); | 746 &rectName); |
743 const char *intervalName; | 747 const char *intervalName; |
744 // The interval uniform's refers to the total length of the interval (on + o
ff) | 748 // The interval uniform's refers to the total length of the interval (on + o
ff) |
745 fIntervalUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 749 fIntervalUniform = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
746 kFloat_GrSLType, | 750 kFloat_GrSLType, |
747 "interval", | 751 "interval", |
748 &intervalName); | 752 &intervalName); |
749 | 753 |
| 754 |
| 755 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 756 |
750 GrGLVertToFrag v(kVec2f_GrSLType); | 757 GrGLVertToFrag v(kVec2f_GrSLType); |
751 args.fPB->addVarying("Coord", &v); | 758 args.fPB->addVarying("Coord", &v); |
752 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); | 759 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), de.inCoord()->fName); |
753 vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str()); | 760 |
| 761 // setup coord outputs |
| 762 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), de.inPositio
n()->fName); |
| 763 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), de.inPosition()
->fName); |
754 | 764 |
755 // setup position varying | 765 // setup position varying |
756 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), | 766 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vs
Builder->uViewM(), |
757 vsBuilder->inPosition()); | 767 de.inPosition()->fName); |
758 | 768 |
759 // transforms all points so that we can compare them to our test rect | 769 // transforms all points so that we can compare them to our test rect |
760 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 770 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
761 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n
", | 771 fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n
", |
762 v.fsIn(), v.fsIn(), intervalName, intervalName); | 772 v.fsIn(), v.fsIn(), intervalName, intervalName); |
763 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); | 773 fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n",
v.fsIn()); |
764 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { | 774 if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) { |
765 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative | 775 // The amount of coverage removed in x and y by the edges is computed as
a pair of negative |
766 // numbers, xSub and ySub. | 776 // numbers, xSub and ySub. |
767 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); | 777 fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); |
768 fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n"
, rectName); | 778 fsBuilder->codeAppendf("\t\txSub = min(fragPosShifted.x - %s.x, 0.0);\n"
, rectName); |
769 fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n
", rectName); | 779 fsBuilder->codeAppendf("\t\txSub += min(%s.z - fragPosShifted.x, 0.0);\n
", rectName); |
770 fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n"
, rectName); | 780 fsBuilder->codeAppendf("\t\tySub = min(fragPosShifted.y - %s.y, 0.0);\n"
, rectName); |
771 fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n
", rectName); | 781 fsBuilder->codeAppendf("\t\tySub += min(%s.w - fragPosShifted.y, 0.0);\n
", rectName); |
772 // Now compute coverage in x and y and multiply them to get the fraction
of the pixel | 782 // Now compute coverage in x and y and multiply them to get the fraction
of the pixel |
773 // covered. | 783 // covered. |
774 fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0
+ max(ySub, -1.0));\n"); | 784 fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0
+ max(ySub, -1.0));\n"); |
775 } else { | 785 } else { |
776 // Assuming the bounding geometry is tight so no need to check y values | 786 // Assuming the bounding geometry is tight so no need to check y values |
777 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); | 787 fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); |
778 fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ?
1.0 : 0.0;\n", rectName); | 788 fsBuilder->codeAppendf("\t\talpha *= (fragPosShifted.x - %s.x) > -0.5 ?
1.0 : 0.0;\n", rectName); |
779 fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ?
1.0 : 0.0;\n", rectName); | 789 fsBuilder->codeAppendf("\t\talpha *= (%s.z - fragPosShifted.x) >= -0.5 ?
1.0 : 0.0;\n", rectName); |
780 } | 790 } |
781 fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutput, | 791 fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); |
782 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("alpha")).c_s
tr()); | |
783 } | 792 } |
784 | 793 |
785 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, | 794 void GLDashingLineEffect::setData(const GrGLProgramDataManager& pdman, |
786 const GrProcessor& processor) { | 795 const GrProcessor& processor) { |
787 const DashingLineEffect& de = processor.cast<DashingLineEffect>(); | 796 const DashingLineEffect& de = processor.cast<DashingLineEffect>(); |
788 const SkRect& rect = de.getRect(); | 797 const SkRect& rect = de.getRect(); |
789 SkScalar intervalLength = de.getIntervalLength(); | 798 SkScalar intervalLength = de.getIntervalLength(); |
790 if (rect != fPrevRect || intervalLength != fPrevIntervalLength) { | 799 if (rect != fPrevRect || intervalLength != fPrevIntervalLength) { |
791 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, | 800 pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, |
792 rect.fRight - 0.5f, rect.fBottom - 0.5f); | 801 rect.fRight - 0.5f, rect.fBottom - 0.5f); |
(...skipping 26 matching lines...) Expand all Loading... |
819 void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 828 void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
820 inout->mulByUnknownAlpha(); | 829 inout->mulByUnknownAlpha(); |
821 } | 830 } |
822 | 831 |
823 const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const { | 832 const GrBackendGeometryProcessorFactory& DashingLineEffect::getFactory() const { |
824 return GrTBackendGeometryProcessorFactory<DashingLineEffect>::getInstance(); | 833 return GrTBackendGeometryProcessorFactory<DashingLineEffect>::getInstance(); |
825 } | 834 } |
826 | 835 |
827 DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInf
o& info, | 836 DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInf
o& info, |
828 SkScalar strokeWidth) | 837 SkScalar strokeWidth) |
829 : fEdgeType(edgeType) | 838 : fEdgeType(edgeType) { |
830 , fInCoord(this->addVertexAttrib(GrShaderVar("inCoord", | 839 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVert
exAttribType)); |
831 kVec2f_GrSLType, | 840 fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttr
ibType)); |
832 GrShaderVar::kAttribute_TypeMod
ifier))) { | |
833 SkScalar onLen = info.fIntervals[0]; | 841 SkScalar onLen = info.fIntervals[0]; |
834 SkScalar offLen = info.fIntervals[1]; | 842 SkScalar offLen = info.fIntervals[1]; |
835 SkScalar halfOffLen = SkScalarHalf(offLen); | 843 SkScalar halfOffLen = SkScalarHalf(offLen); |
836 SkScalar halfStroke = SkScalarHalf(strokeWidth); | 844 SkScalar halfStroke = SkScalarHalf(strokeWidth); |
837 fIntervalLength = onLen + offLen; | 845 fIntervalLength = onLen + offLen; |
838 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); | 846 fRect.set(halfOffLen, -halfStroke, halfOffLen + onLen, halfStroke); |
839 } | 847 } |
840 | 848 |
841 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { | 849 bool DashingLineEffect::onIsEqual(const GrGeometryProcessor& other) const { |
842 const DashingLineEffect& de = other.cast<DashingLineEffect>(); | 850 const DashingLineEffect& de = other.cast<DashingLineEffect>(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 switch (cap) { | 882 switch (cap) { |
875 case GrDashingEffect::kRound_DashCap: | 883 case GrDashingEffect::kRound_DashCap: |
876 return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(stro
keWidth)); | 884 return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(stro
keWidth)); |
877 case GrDashingEffect::kNonRound_DashCap: | 885 case GrDashingEffect::kNonRound_DashCap: |
878 return DashingLineEffect::Create(edgeType, info, strokeWidth); | 886 return DashingLineEffect::Create(edgeType, info, strokeWidth); |
879 default: | 887 default: |
880 SkFAIL("Unexpected dashed cap."); | 888 SkFAIL("Unexpected dashed cap."); |
881 } | 889 } |
882 return NULL; | 890 return NULL; |
883 } | 891 } |
OLD | NEW |