Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
| 10 | 10 |
| 11 #include "GrContext.h" | 11 #include "GrContext.h" |
| 12 #include "GrDrawState.h" | 12 #include "GrDrawState.h" |
| 13 #include "GrDrawTargetCaps.h" | 13 #include "GrDrawTargetCaps.h" |
| 14 #include "GrEffect.h" | |
| 14 #include "GrPathUtils.h" | 15 #include "GrPathUtils.h" |
| 16 #include "GrTBackendEffectFactory.h" | |
| 15 #include "SkString.h" | 17 #include "SkString.h" |
| 16 #include "SkStrokeRec.h" | 18 #include "SkStrokeRec.h" |
| 17 #include "SkTrace.h" | 19 #include "SkTrace.h" |
| 18 | 20 |
| 19 #include "effects/GrEdgeEffect.h" | 21 #include "gl/GrGLEffect.h" |
| 22 #include "gl/GrGLSL.h" | |
| 20 | 23 |
| 21 GrAAConvexPathRenderer::GrAAConvexPathRenderer() { | 24 GrAAConvexPathRenderer::GrAAConvexPathRenderer() { |
| 22 } | 25 } |
| 23 | 26 |
| 24 namespace { | 27 namespace { |
| 25 | 28 |
| 26 struct Segment { | 29 struct Segment { |
| 27 enum { | 30 enum { |
| 28 // These enum values are assumed in member functions below. | 31 // These enum values are assumed in member functions below. |
| 29 kLine = 0, | 32 kLine = 0, |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 idxs[i + 11] = v + 1; | 427 idxs[i + 11] = v + 1; |
| 425 | 428 |
| 426 v += 6; | 429 v += 6; |
| 427 i += 12; | 430 i += 12; |
| 428 } | 431 } |
| 429 } | 432 } |
| 430 } | 433 } |
| 431 | 434 |
| 432 } | 435 } |
| 433 | 436 |
| 437 /////////////////////////////////////////////////////////////////////////////// | |
| 438 | |
| 439 /* | |
| 440 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first | |
| 441 * two components of the vertex attribute. Coverage is based on signed | |
| 442 * distance with negative being inside, positive outside. The edge is specified in | |
| 443 * window space (y-down). If either the third or fourth component of the interpo lated | |
| 444 * vertex coord is > 0 then the pixel is considered outside the edge. This is us ed to | |
| 445 * attempt to trim to a portion of the infinite quad. | |
| 446 * Requires shader derivative instruction support. | |
| 447 */ | |
| 448 | |
| 449 class QuadEdgeEffect : public GrEffect { | |
| 450 public: | |
| 451 | |
| 452 static GrEffectRef* Create() { | |
| 453 // we go through this so we only have one copy of each effect | |
| 454 static GrEffectRef* gQuadEdgeEffectRef = | |
| 455 CreateEffectRef(AutoEffectUnref(SkNEW(QuadEdgeEffect))); | |
| 456 static SkAutoTUnref<GrEffectRef> gUnref(gQuadEdgeEffectRef); | |
| 457 | |
| 458 gQuadEdgeEffectRef->ref(); | |
| 459 return gQuadEdgeEffectRef; | |
| 460 } | |
| 461 | |
| 462 virtual ~QuadEdgeEffect() {} | |
| 463 | |
| 464 static const char* Name() { return "QuadEdge"; } | |
| 465 | |
| 466 virtual void getConstantColorComponents(GrColor* color, | |
| 467 uint32_t* validFlags) const SK_OVERR IDE { | |
| 468 *validFlags = 0; | |
| 469 } | |
| 470 | |
| 471 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | |
| 472 return GrTBackendEffectFactory<QuadEdgeEffect>::getInstance(); | |
| 473 } | |
| 474 | |
| 475 class GLEffect : public GrGLEffect { | |
| 476 public: | |
| 477 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | |
| 478 : INHERITED (factory) {} | |
| 479 | |
| 480 virtual void emitCode(GrGLShaderBuilder* builder, | |
| 481 const GrDrawEffect& drawEffect, | |
| 482 EffectKey key, | |
| 483 const char* outputColor, | |
| 484 const char* inputColor, | |
| 485 const TextureSamplerArray& samplers) SK_OVERRIDE { | |
| 486 const char *vsName, *fsName; | |
| 487 const SkString* attrName = | |
| 488 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]); | |
| 489 builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); | |
| 490 | |
| 491 GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport()); | |
| 492 builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); | |
| 493 | |
| 494 // keep the derivative instructions outside the conditional | |
| 495 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | |
| 496 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | |
| 497 builder->fsCodeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsNa me, fsName); | |
| 498 // today we know z and w are in device space. We could use derivativ es | |
| 499 builder->fsCodeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, | |
| 500 fsName); | |
| 501 builder->fsCodeAppendf ("\t\t} else {\n"); | |
| 502 builder->fsCodeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvd x.y,\n" | |
|
robertphillips
2013/03/31 22:59:08
line these up?
| |
| 503 "\t\t\t 2.0*%s.x*duvdy.x - duv dy.y);\n", | |
| 504 fsName, fsName); | |
| 505 builder->fsCodeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fs Name, fsName, | |
| 506 fsName); | |
| 507 builder->fsCodeAppendf("\t\t\tedgeAlpha = " | |
|
robertphillips
2013/03/31 22:59:08
same here?
| |
| 508 "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1. 0);\n\t\t}\n"); | |
| 509 if (kES2_GrGLBinding == builder->ctxInfo().binding()) { | |
|
robertphillips
2013/03/31 22:59:08
I thought I saw this done differently recently (in
| |
| 510 builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); | |
| 511 } | |
| 512 | |
| 513 SkString modulate; | |
| 514 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); | |
| 515 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() ); | |
| 516 | |
| 517 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); | |
| 518 } | |
| 519 | |
| 520 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { | |
| 521 return 0x0; | |
| 522 } | |
| 523 | |
| 524 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {} | |
| 525 | |
| 526 private: | |
| 527 typedef GrGLEffect INHERITED; | |
| 528 }; | |
| 529 | |
| 530 private: | |
| 531 QuadEdgeEffect() { | |
| 532 this->addVertexAttrib(kVec4f_GrSLType); | |
| 533 } | |
| 534 | |
| 535 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
| 536 return true; | |
| 537 } | |
| 538 | |
| 539 GR_DECLARE_EFFECT_TEST; | |
| 540 | |
| 541 typedef GrEffect INHERITED; | |
| 542 }; | |
| 543 | |
| 544 GR_DEFINE_EFFECT_TEST(QuadEdgeEffect); | |
| 545 | |
| 546 GrEffectRef* QuadEdgeEffect::TestCreate(SkMWCRandom* random, | |
| 547 GrContext*, | |
| 548 const GrDrawTargetCaps& caps, | |
| 549 GrTexture*[]) { | |
| 550 // Doesn't work without derivative instructions. | |
| 551 GrAssert(caps.shaderDerivativeSupport()); | |
| 552 return QuadEdgeEffect::Create(); | |
| 553 } | |
| 554 | |
| 555 /////////////////////////////////////////////////////////////////////////////// | |
| 556 | |
| 434 bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path, | 557 bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path, |
| 435 const SkStrokeRec& stroke, | 558 const SkStrokeRec& stroke, |
| 436 const GrDrawTarget* target, | 559 const GrDrawTarget* target, |
| 437 bool antiAlias) const { | 560 bool antiAlias) const { |
| 438 return (target->caps()->shaderDerivativeSupport() && antiAlias && | 561 return (target->caps()->shaderDerivativeSupport() && antiAlias && |
| 439 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex() ); | 562 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex() ); |
| 440 } | 563 } |
| 441 | 564 |
| 442 bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, | 565 bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, |
| 443 const SkStrokeRec&, | 566 const SkStrokeRec&, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); | 616 drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); |
| 494 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); | 617 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); |
| 495 | 618 |
| 496 enum { | 619 enum { |
| 497 // the edge effects share this stage with glyph rendering | 620 // the edge effects share this stage with glyph rendering |
| 498 // (kGlyphMaskStage in GrTextContext) && SW path rendering | 621 // (kGlyphMaskStage in GrTextContext) && SW path rendering |
| 499 // (kPathMaskStage in GrSWMaskHelper) | 622 // (kPathMaskStage in GrSWMaskHelper) |
| 500 kEdgeEffectStage = GrPaint::kTotalStages, | 623 kEdgeEffectStage = GrPaint::kTotalStages, |
| 501 }; | 624 }; |
| 502 static const int kEdgeAttrIndex = 1; | 625 static const int kEdgeAttrIndex = 1; |
| 503 GrEffectRef* quadEffect = GrEdgeEffect::Create(GrEdgeEffect::kQuad_EdgeType) ; | 626 GrEffectRef* quadEffect = QuadEdgeEffect::Create(); |
| 504 drawState->setEffect(kEdgeEffectStage, quadEffect, kEdgeAttrIndex)->unref(); | 627 drawState->setEffect(kEdgeEffectStage, quadEffect, kEdgeAttrIndex)->unref(); |
| 505 | 628 |
| 506 GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount); | 629 GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount); |
| 507 if (!arg.succeeded()) { | 630 if (!arg.succeeded()) { |
| 508 return false; | 631 return false; |
| 509 } | 632 } |
| 510 GrAssert(sizeof(QuadVertex) == drawState->getVertexSize()); | 633 GrAssert(sizeof(QuadVertex) == drawState->getVertexSize()); |
| 511 verts = reinterpret_cast<QuadVertex*>(arg.vertices()); | 634 verts = reinterpret_cast<QuadVertex*>(arg.vertices()); |
| 512 idxs = reinterpret_cast<uint16_t*>(arg.indices()); | 635 idxs = reinterpret_cast<uint16_t*>(arg.indices()); |
| 513 | 636 |
| 514 create_vertices(segments, fanPt, verts, idxs); | 637 create_vertices(segments, fanPt, verts, idxs); |
| 515 | 638 |
| 516 target->drawIndexed(kTriangles_GrPrimitiveType, | 639 target->drawIndexed(kTriangles_GrPrimitiveType, |
| 517 0, // start vertex | 640 0, // start vertex |
| 518 0, // start index | 641 0, // start index |
| 519 vCount, | 642 vCount, |
| 520 iCount); | 643 iCount); |
| 521 | 644 |
| 522 return true; | 645 return true; |
| 523 } | 646 } |
| OLD | NEW |