| 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 |