OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrAARectRenderer.h" | 8 #include "GrAARectRenderer.h" |
9 #include "GrGpu.h" | 9 #include "GrGpu.h" |
10 #include "gl/builders/GrGLProgramBuilder.h" | 10 #include "gl/builders/GrGLProgramBuilder.h" |
11 #include "gl/GrGLProcessor.h" | 11 #include "gl/GrGLProcessor.h" |
12 #include "gl/GrGLGeometryProcessor.h" | 12 #include "gl/GrGLGeometryProcessor.h" |
13 #include "GrTBackendProcessorFactory.h" | 13 #include "GrTBackendProcessorFactory.h" |
14 #include "SkColorPriv.h" | 14 #include "SkColorPriv.h" |
15 #include "GrGeometryProcessor.h" | 15 #include "GrGeometryProcessor.h" |
16 | 16 |
17 /////////////////////////////////////////////////////////////////////////////// | 17 /////////////////////////////////////////////////////////////////////////////// |
18 | 18 class GrGLAlignedRectEffect; |
| 19 |
| 20 // Axis Aligned special case |
| 21 class GrAlignedRectEffect : public GrGeometryProcessor { |
| 22 public: |
| 23 static GrGeometryProcessor* Create() { |
| 24 GR_CREATE_STATIC_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ()); |
| 25 gAlignedRectEffect->ref(); |
| 26 return gAlignedRectEffect; |
| 27 } |
| 28 |
| 29 virtual ~GrAlignedRectEffect() {} |
| 30 |
| 31 static const char* Name() { return "AlignedRectEdge"; } |
| 32 |
| 33 const GrShaderVar& inRect() const { return fInRect; } |
| 34 |
| 35 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE { |
| 36 return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInsta
nce(); |
| 37 } |
| 38 |
| 39 class GLProcessor : public GrGLGeometryProcessor { |
| 40 public: |
| 41 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) |
| 42 : INHERITED (factory) {} |
| 43 |
| 44 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
| 45 // setup the varying for the Axis aligned rect effect |
| 46 // xy -> interpolated offset |
| 47 // zw -> w/2+0.5, h/2+0.5 |
| 48 GrGLVertToFrag v(kVec4f_GrSLType); |
| 49 args.fPB->addVarying("Rect", &v); |
| 50 |
| 51 const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inR
ect(); |
| 52 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 53 vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str()); |
| 54 |
| 55 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde
r(); |
| 56 // TODO: compute all these offsets, spans, and scales in the VS |
| 57 fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v
.fsIn()); |
| 58 fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v
.fsIn()); |
| 59 fsBuilder->codeAppend("\tfloat outset = 0.5;\n"); |
| 60 // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0
). For rects |
| 61 // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a
0 .. 1 range. |
| 62 fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n"); |
| 63 fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n"); |
| 64 // For rects < 1 pixel wide or tall, these scale factors are used to
cap the maximum |
| 65 // value of coverage that is used. In other words it is the coverage
that is |
| 66 // used in the interior of the rect after the ramp. |
| 67 fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\
n"); |
| 68 fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\
n"); |
| 69 |
| 70 // Compute the coverage for the rect's width |
| 71 fsBuilder->codeAppendf( |
| 72 "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.
0);\n", v.fsIn(), |
| 73 v.fsIn()); |
| 74 // Compute the coverage for the rect's height and merge with the wid
th |
| 75 fsBuilder->codeAppendf( |
| 76 "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0,
1.0);\n", |
| 77 v.fsIn(), v.fsIn()); |
| 78 |
| 79 |
| 80 fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput, |
| 81 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("cove
rage")).c_str()); |
| 82 } |
| 83 |
| 84 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBu
ilder*) {} |
| 85 |
| 86 virtual void setData(const GrGLProgramDataManager& pdman, const GrProces
sor&) SK_OVERRIDE {} |
| 87 |
| 88 private: |
| 89 typedef GrGLGeometryProcessor INHERITED; |
| 90 }; |
| 91 |
| 92 |
| 93 private: |
| 94 GrAlignedRectEffect() |
| 95 : fInRect(this->addVertexAttrib(GrShaderVar("inRect", |
| 96 kVec4f_GrSLType, |
| 97 GrShaderVar::kAttribute_Type
Modifier))) { |
| 98 } |
| 99 |
| 100 const GrShaderVar& fInRect; |
| 101 |
| 102 virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { retur
n true; } |
| 103 |
| 104 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR
IDE { |
| 105 inout->mulByUnknownAlpha(); |
| 106 } |
| 107 |
| 108 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| 109 |
| 110 typedef GrGeometryProcessor INHERITED; |
| 111 }; |
| 112 |
| 113 |
| 114 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect); |
| 115 |
| 116 GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random, |
| 117 GrContext* context, |
| 118 const GrDrawTargetCaps&, |
| 119 GrTexture* textures[]) { |
| 120 return GrAlignedRectEffect::Create(); |
| 121 } |
| 122 |
| 123 /////////////////////////////////////////////////////////////////////////////// |
| 124 class GrGLRectEffect; |
| 125 |
| 126 /** |
| 127 * The output of this effect is a modulation of the input color and coverage |
| 128 * for an arbitrarily oriented rect. The rect is specified as: |
| 129 * Center of the rect |
| 130 * Unit vector point down the height of the rect |
| 131 * Half width + 0.5 |
| 132 * Half height + 0.5 |
| 133 * The center and vector are stored in a vec4 varying ("RectEdge") with the |
| 134 * center in the xy components and the vector in the zw components. |
| 135 * The munged width and height are stored in a vec2 varying ("WidthHeight") |
| 136 * with the width in x and the height in y. |
| 137 */ |
| 138 |
| 139 class GrRectEffect : public GrGeometryProcessor { |
| 140 public: |
| 141 static GrGeometryProcessor* Create() { |
| 142 GR_CREATE_STATIC_PROCESSOR(gRectEffect, GrRectEffect, ()); |
| 143 gRectEffect->ref(); |
| 144 return gRectEffect; |
| 145 } |
| 146 |
| 147 virtual ~GrRectEffect() {} |
| 148 |
| 149 static const char* Name() { return "RectEdge"; } |
| 150 |
| 151 const GrShaderVar& inRectEdge() const { return fInRectEdge; } |
| 152 const GrShaderVar& inWidthHeight() const { return fInWidthHeight; } |
| 153 |
| 154 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE { |
| 155 return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance(); |
| 156 } |
| 157 |
| 158 class GLProcessor : public GrGLGeometryProcessor { |
| 159 public: |
| 160 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) |
| 161 : INHERITED (factory) {} |
| 162 |
| 163 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
| 164 // setup the varying for the center point and the unit vector |
| 165 // that points down the height of the rect |
| 166 GrGLVertToFrag rectEdge(kVec4f_GrSLType); |
| 167 args.fPB->addVarying("RectEdge", &rectEdge); |
| 168 |
| 169 const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>(); |
| 170 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 171 vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRe
ctEdge().c_str()); |
| 172 |
| 173 // setup the varying for width/2+.5 and height/2+.5 |
| 174 GrGLVertToFrag widthHeight(kVec2f_GrSLType); |
| 175 args.fPB->addVarying("WidthHeight", &widthHeight); |
| 176 vsBuilder->codeAppendf("%s = %s;", |
| 177 widthHeight.vsOut(), |
| 178 rectEffect.inWidthHeight().c_str()); |
| 179 |
| 180 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde
r(); |
| 181 // TODO: compute all these offsets, spans, and scales in the VS |
| 182 fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", w
idthHeight.fsIn()); |
| 183 fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", w
idthHeight.fsIn()); |
| 184 fsBuilder->codeAppend("\tfloat outset = 0.5;\n"); |
| 185 // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0
). For rects |
| 186 // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a
0 .. 1 range. |
| 187 fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n"); |
| 188 fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n"); |
| 189 // For rects < 1 pixel wide or tall, these scale factors are used to
cap the maximum |
| 190 // value of coverage that is used. In other words it is the coverage
that is |
| 191 // used in the interior of the rect after the ramp. |
| 192 fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\
n"); |
| 193 fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\
n"); |
| 194 |
| 195 // Compute the coverage for the rect's width |
| 196 fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n", |
| 197 fsBuilder->fragmentPosition(), rectEdge.fsIn(
)); |
| 198 fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offs
et.y * %s.z);\n", |
| 199 rectEdge.fsIn(), rectEdge.fsIn()); |
| 200 fsBuilder->codeAppendf( |
| 201 "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0)
;\n", |
| 202 widthHeight.fsIn()); |
| 203 |
| 204 // Compute the coverage for the rect's height and merge with the wid
th |
| 205 fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n", |
| 206 rectEdge.fsIn()); |
| 207 fsBuilder->codeAppendf( |
| 208 "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.
0, 1.0);\n", |
| 209 widthHeight.fsIn()); |
| 210 |
| 211 |
| 212 fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput, |
| 213 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("cove
rage")).c_str()); |
| 214 } |
| 215 |
| 216 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBu
ilder*) {} |
| 217 |
| 218 virtual void setData(const GrGLProgramDataManager& pdman, const GrProces
sor&) SK_OVERRIDE {} |
| 219 |
| 220 private: |
| 221 typedef GrGLGeometryProcessor INHERITED; |
| 222 }; |
| 223 |
| 224 |
| 225 |
| 226 private: |
| 227 GrRectEffect() |
| 228 : fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge", |
| 229 kVec4f_GrSLType, |
| 230 GrShaderVar::kAttribute_
TypeModifier))) |
| 231 , fInWidthHeight(this->addVertexAttrib( |
| 232 GrShaderVar("inWidthHeight", |
| 233 kVec2f_GrSLType, |
| 234 GrShaderVar::kAttribute_TypeModifier))) { |
| 235 this->setWillReadFragmentPosition(); |
| 236 } |
| 237 |
| 238 virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { retur
n true; } |
| 239 |
| 240 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR
IDE { |
| 241 inout->mulByUnknownAlpha(); |
| 242 } |
| 243 |
| 244 const GrShaderVar& fInRectEdge; |
| 245 const GrShaderVar& fInWidthHeight; |
| 246 |
| 247 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
| 248 |
| 249 typedef GrGeometryProcessor INHERITED; |
| 250 }; |
| 251 |
| 252 |
| 253 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect); |
| 254 |
| 255 GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random, |
| 256 GrContext* context, |
| 257 const GrDrawTargetCaps&, |
| 258 GrTexture* textures[]) { |
| 259 return GrRectEffect::Create(); |
| 260 } |
| 261 |
| 262 /////////////////////////////////////////////////////////////////////////////// |
| 263 |
19 namespace { | 264 namespace { |
20 extern const GrVertexAttrib gAARectAttribs[] = { | 265 extern const GrVertexAttrib gAARectAttribs[] = { |
21 {kVec2f_GrVertexAttribType, 0, kPosition_Gr
VertexAttribBinding}, | 266 {kVec2f_GrVertexAttribType, 0, kPosition_Gr
VertexAttribBinding}, |
22 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVer
texAttribBinding}, | 267 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVer
texAttribBinding}, |
23 {kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor), kCoverage_Gr
VertexAttribBinding}, | 268 {kFloat_GrVertexAttribType, sizeof(SkPoint) + sizeof(SkColor), kCoverage_Gr
VertexAttribBinding}, |
24 }; | 269 }; |
25 | 270 |
26 // Should the coverage be multiplied into the color attrib or use a separate att
rib. | 271 // Should the coverage be multiplied into the color attrib or use a separate att
rib. |
27 enum CoverageAttribType { | 272 enum CoverageAttribType { |
28 kUseColor_CoverageAttribType, | 273 kUseColor_CoverageAttribType, |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 } | 541 } |
297 } | 542 } |
298 | 543 |
299 target->setIndexSourceToBuffer(indexBuffer); | 544 target->setIndexSourceToBuffer(indexBuffer); |
300 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, | 545 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, |
301 kVertsPerAAFillRect, | 546 kVertsPerAAFillRect, |
302 kIndicesPerAAFillRect); | 547 kIndicesPerAAFillRect); |
303 target->resetIndexSource(); | 548 target->resetIndexSource(); |
304 } | 549 } |
305 | 550 |
| 551 namespace { |
| 552 |
| 553 // Rotated |
| 554 struct RectVertex { |
| 555 SkPoint fPos; |
| 556 SkPoint fCenter; |
| 557 SkPoint fDir; |
| 558 SkPoint fWidthHeight; |
| 559 }; |
| 560 |
| 561 // Rotated |
| 562 extern const GrVertexAttrib gAARectVertexAttribs[] = { |
| 563 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind
ing }, |
| 564 { kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexA
ttribBinding }, |
| 565 { kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexA
ttribBinding } |
| 566 }; |
| 567 |
| 568 // Axis Aligned |
| 569 struct AARectVertex { |
| 570 SkPoint fPos; |
| 571 SkPoint fOffset; |
| 572 SkPoint fWidthHeight; |
| 573 }; |
| 574 |
| 575 // Axis Aligned |
| 576 extern const GrVertexAttrib gAAAARectVertexAttribs[] = { |
| 577 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBind
ing }, |
| 578 { kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexA
ttribBinding }, |
| 579 }; |
| 580 |
| 581 }; |
| 582 |
| 583 void GrAARectRenderer::shaderFillAARect(GrDrawTarget* target, |
| 584 const SkRect& rect, |
| 585 const SkMatrix& combinedMatrix) { |
| 586 GrDrawState* drawState = target->drawState(); |
| 587 |
| 588 SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY()); |
| 589 combinedMatrix.mapPoints(¢er, 1); |
| 590 |
| 591 // compute transformed (0, 1) vector |
| 592 SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix:
:kMScaleY] }; |
| 593 dir.normalize(); |
| 594 |
| 595 // compute transformed (width, 0) and (0, height) vectors |
| 596 SkVector vec[2] = { |
| 597 { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] }, |
| 598 { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] } |
| 599 }; |
| 600 |
| 601 SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_Scalar
Half; |
| 602 SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_Scal
arHalf; |
| 603 drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVert
exAttribs), |
| 604 sizeof(RectVertex)); |
| 605 |
| 606 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
| 607 if (!geo.succeeded()) { |
| 608 SkDebugf("Failed to get space for vertices!\n"); |
| 609 return; |
| 610 } |
| 611 |
| 612 RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices()); |
| 613 |
| 614 GrGeometryProcessor* gp = GrRectEffect::Create(); |
| 615 drawState->setGeometryProcessor(gp)->unref(); |
| 616 |
| 617 for (int i = 0; i < 4; ++i) { |
| 618 verts[i].fCenter = center; |
| 619 verts[i].fDir = dir; |
| 620 verts[i].fWidthHeight.fX = newWidth; |
| 621 verts[i].fWidthHeight.fY = newHeight; |
| 622 } |
| 623 |
| 624 SkRect devRect; |
| 625 combinedMatrix.mapRect(&devRect, rect); |
| 626 |
| 627 SkRect devBounds = { |
| 628 devRect.fLeft - SK_ScalarHalf, |
| 629 devRect.fTop - SK_ScalarHalf, |
| 630 devRect.fRight + SK_ScalarHalf, |
| 631 devRect.fBottom + SK_ScalarHalf |
| 632 }; |
| 633 |
| 634 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop); |
| 635 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom); |
| 636 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom); |
| 637 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop); |
| 638 |
| 639 target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer()); |
| 640 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); |
| 641 target->resetIndexSource(); |
| 642 } |
| 643 |
| 644 void GrAARectRenderer::shaderFillAlignedAARect(GrDrawTarget* target, |
| 645 const SkRect& rect, |
| 646 const SkMatrix& combinedMatrix) { |
| 647 GrDrawState* drawState = target->drawState(); |
| 648 SkASSERT(combinedMatrix.rectStaysRect()); |
| 649 |
| 650 drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARect
VertexAttribs), |
| 651 sizeof(AARectVertex)); |
| 652 |
| 653 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
| 654 if (!geo.succeeded()) { |
| 655 SkDebugf("Failed to get space for vertices!\n"); |
| 656 return; |
| 657 } |
| 658 |
| 659 AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices()); |
| 660 |
| 661 GrGeometryProcessor* gp = GrAlignedRectEffect::Create(); |
| 662 drawState->setGeometryProcessor(gp)->unref(); |
| 663 |
| 664 SkRect devRect; |
| 665 combinedMatrix.mapRect(&devRect, rect); |
| 666 |
| 667 SkRect devBounds = { |
| 668 devRect.fLeft - SK_ScalarHalf, |
| 669 devRect.fTop - SK_ScalarHalf, |
| 670 devRect.fRight + SK_ScalarHalf, |
| 671 devRect.fBottom + SK_ScalarHalf |
| 672 }; |
| 673 |
| 674 SkPoint widthHeight = { |
| 675 SkScalarHalf(devRect.width()) + SK_ScalarHalf, |
| 676 SkScalarHalf(devRect.height()) + SK_ScalarHalf |
| 677 }; |
| 678 |
| 679 verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop); |
| 680 verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY); |
| 681 verts[0].fWidthHeight = widthHeight; |
| 682 |
| 683 verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom); |
| 684 verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY); |
| 685 verts[1].fWidthHeight = widthHeight; |
| 686 |
| 687 verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom); |
| 688 verts[2].fOffset = widthHeight; |
| 689 verts[2].fWidthHeight = widthHeight; |
| 690 |
| 691 verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop); |
| 692 verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY); |
| 693 verts[3].fWidthHeight = widthHeight; |
| 694 |
| 695 target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer()); |
| 696 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); |
| 697 target->resetIndexSource(); |
| 698 } |
| 699 |
306 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 700 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
307 const SkRect& rect, | 701 const SkRect& rect, |
308 const SkMatrix& combinedMatrix, | 702 const SkMatrix& combinedMatrix, |
309 const SkRect& devRect, | 703 const SkRect& devRect, |
310 const SkStrokeRec& stroke) { | 704 const SkStrokeRec& stroke) { |
311 SkVector devStrokeSize; | 705 SkVector devStrokeSize; |
312 SkScalar width = stroke.getWidth(); | 706 SkScalar width = stroke.getWidth(); |
313 if (width > 0) { | 707 if (width > 0) { |
314 devStrokeSize.set(width, width); | 708 devStrokeSize.set(width, width); |
315 combinedMatrix.mapVectors(&devStrokeSize, 1); | 709 combinedMatrix.mapVectors(&devStrokeSize, 1); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 // can't call mapRect for devInside since it calls sort | 905 // can't call mapRect for devInside since it calls sort |
512 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; | 906 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; |
513 | 907 |
514 if (devInside.isEmpty()) { | 908 if (devInside.isEmpty()) { |
515 this->fillAARect(target, devOutside, SkMatrix::I(), devOutside); | 909 this->fillAARect(target, devOutside, SkMatrix::I(), devOutside); |
516 return; | 910 return; |
517 } | 911 } |
518 | 912 |
519 this->geometryStrokeAARect(target, devOutside, devOutsideAssist, devInside,
true); | 913 this->geometryStrokeAARect(target, devOutside, devOutsideAssist, devInside,
true); |
520 } | 914 } |
OLD | NEW |