Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrOvalRenderer.h" | 8 #include "GrOvalRenderer.h" |
| 9 | 9 |
| 10 #include "GrEffect.h" | 10 #include "GrEffect.h" |
| 11 #include "gl/GrGLEffect.h" | 11 #include "gl/GrGLEffect.h" |
| 12 #include "gl/GrGLSL.h" | 12 #include "gl/GrGLSL.h" |
| 13 #include "GrTBackendEffectFactory.h" | 13 #include "GrTBackendEffectFactory.h" |
| 14 | 14 |
| 15 #include "GrDrawState.h" | 15 #include "GrDrawState.h" |
| 16 #include "GrDrawTarget.h" | 16 #include "GrDrawTarget.h" |
| 17 #include "SkStrokeRec.h" | 17 #include "SkStrokeRec.h" |
| 18 | 18 |
| 19 SK_DEFINE_INST_COUNT(GrOvalRenderer) | 19 SK_DEFINE_INST_COUNT(GrOvalRenderer) |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 struct CircleVertex { | 23 struct CircleVertex { |
| 24 GrPoint fPos; | 24 GrPoint fPos; |
| 25 GrPoint fCenter; | 25 GrPoint fOffset; |
| 26 SkScalar fOuterRadius; | 26 SkScalar fOuterRadius; |
| 27 SkScalar fInnerRadius; | 27 SkScalar fInnerRadius; |
| 28 }; | 28 }; |
| 29 | 29 |
| 30 struct EllipseVertex { | 30 struct EllipseVertex { |
| 31 GrPoint fPos; | 31 GrPoint fPos; |
| 32 GrPoint fCenter; | |
| 33 SkScalar fOuterXRadius; | 32 SkScalar fOuterXRadius; |
| 34 SkScalar fOuterXYRatio; | |
| 35 SkScalar fInnerXRadius; | 33 SkScalar fInnerXRadius; |
| 36 SkScalar fInnerXYRatio; | 34 GrPoint fOuterOffset; |
| 35 GrPoint fInnerOffset; | |
| 37 }; | 36 }; |
| 38 | 37 |
| 39 inline bool circle_stays_circle(const SkMatrix& m) { | 38 inline bool circle_stays_circle(const SkMatrix& m) { |
| 40 return m.isSimilarity(); | 39 return m.isSimilarity(); |
| 41 } | 40 } |
| 42 | 41 |
| 43 } | 42 } |
| 44 | 43 |
| 45 /////////////////////////////////////////////////////////////////////////////// | 44 /////////////////////////////////////////////////////////////////////////////// |
| 46 | 45 |
| 47 /** | 46 /** |
| 48 * The output of this effect is a modulation of the input color and coverage for a circle, | 47 * The output of this effect is a modulation of the input color and coverage for a circle, |
| 49 * specified as center_x, center_y, x_radius, inner radius and outer radius in w indow space | 48 * specified as offset_x, offset_y (both from center point), outer radius and in ner radius. |
| 50 * (y-down). | |
| 51 */ | 49 */ |
| 52 | 50 |
| 53 class CircleEdgeEffect : public GrEffect { | 51 class CircleEdgeEffect : public GrEffect { |
| 54 public: | 52 public: |
| 55 static GrEffectRef* Create(bool stroke) { | 53 static GrEffectRef* Create(bool stroke) { |
| 56 // we go through this so we only have one copy of each effect (stroked/f illed) | 54 // we go through this so we only have one copy of each effect (stroked/f illed) |
| 57 static SkAutoTUnref<GrEffectRef> gCircleStrokeEdgeEffectRef( | 55 static SkAutoTUnref<GrEffectRef> gCircleStrokeEdgeEffectRef( |
| 58 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEff ect, (true))))); | 56 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEff ect, (true))))); |
| 59 static SkAutoTUnref<GrEffectRef> gCircleFillEdgeEffectRef( | 57 static SkAutoTUnref<GrEffectRef> gCircleFillEdgeEffectRef( |
| 60 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEff ect, (false))))); | 58 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEff ect, (false))))); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 const char* inputColor, | 93 const char* inputColor, |
| 96 const TextureSamplerArray& samplers) SK_OVERRIDE { | 94 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 97 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>(); | 95 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>(); |
| 98 const char *vsName, *fsName; | 96 const char *vsName, *fsName; |
| 99 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName) ; | 97 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName) ; |
| 100 | 98 |
| 101 const SkString* attrName = | 99 const SkString* attrName = |
| 102 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]); | 100 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]); |
| 103 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); | 101 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); |
| 104 | 102 |
| 105 builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n", | 103 builder->fsCodeAppendf("\tfloat d = length(%s.xy);\n", fsName); |
| 106 builder->fragmentPosition(), fsName); | |
| 107 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0 );\n", fsName); | 104 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0 );\n", fsName); |
| 108 if (circleEffect.isStroked()) { | 105 if (circleEffect.isStroked()) { |
| 109 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0 , 1.0);\n", fsName); | 106 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0 , 1.0);\n", fsName); |
| 110 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); | 107 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); |
| 111 } | 108 } |
| 109 | |
| 112 SkString modulate; | 110 SkString modulate; |
| 113 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); | 111 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); |
| 114 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() ); | 112 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() ); |
| 115 } | 113 } |
| 116 | 114 |
| 117 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { | 115 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { |
| 118 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>(); | 116 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>(); |
| 119 | 117 |
| 120 return circleEffect.isStroked() ? 0x1 : 0x0; | 118 return circleEffect.isStroked() ? 0x1 : 0x0; |
| 121 } | 119 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 151 GrContext* context, | 149 GrContext* context, |
| 152 const GrDrawTargetCaps&, | 150 const GrDrawTargetCaps&, |
| 153 GrTexture* textures[]) { | 151 GrTexture* textures[]) { |
| 154 return CircleEdgeEffect::Create(random->nextBool()); | 152 return CircleEdgeEffect::Create(random->nextBool()); |
| 155 } | 153 } |
| 156 | 154 |
| 157 /////////////////////////////////////////////////////////////////////////////// | 155 /////////////////////////////////////////////////////////////////////////////// |
| 158 | 156 |
| 159 /** | 157 /** |
| 160 * The output of this effect is a modulation of the input color and coverage for an axis-aligned | 158 * The output of this effect is a modulation of the input color and coverage for an axis-aligned |
| 161 * ellipse, specified as center_x, center_y, x_radius, x_radius/y_radius in wind ow space (y-down). | 159 * ellipse, specified as outer and inner radii, and outer and inner offsets fro m center. |
| 162 */ | 160 */ |
| 163 | 161 |
| 164 class EllipseEdgeEffect : public GrEffect { | 162 class EllipseEdgeEffect : public GrEffect { |
| 165 public: | 163 public: |
| 166 static GrEffectRef* Create(bool stroke) { | 164 static GrEffectRef* Create(bool stroke) { |
| 167 // we go through this so we only have one copy of each effect (stroked/f illed) | 165 // we go through this so we only have one copy of each effect (stroked/f illed) |
| 168 static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef( | 166 static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef( |
| 169 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (true))))); | 167 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (true))))); |
| 170 static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef( | 168 static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef( |
| 171 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (false))))); | 169 CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEf fect, (false))))); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 200 : INHERITED (factory) {} | 198 : INHERITED (factory) {} |
| 201 | 199 |
| 202 virtual void emitCode(GrGLShaderBuilder* builder, | 200 virtual void emitCode(GrGLShaderBuilder* builder, |
| 203 const GrDrawEffect& drawEffect, | 201 const GrDrawEffect& drawEffect, |
| 204 EffectKey key, | 202 EffectKey key, |
| 205 const char* outputColor, | 203 const char* outputColor, |
| 206 const char* inputColor, | 204 const char* inputColor, |
| 207 const TextureSamplerArray& samplers) SK_OVERRIDE { | 205 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 208 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); | 206 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); |
| 209 | 207 |
| 210 const char *vsCenterName, *fsCenterName; | 208 const char *vsRadiiName, *fsRadiiName; |
| 211 const char *vsEdgeName, *fsEdgeName; | 209 const char *vsOffsetsName, *fsOffsetsName; |
| 212 | 210 |
| 213 builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName); | 211 builder->addVarying(kVec2f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName); |
| 214 const SkString* attr0Name = | 212 const SkString* attr0Name = |
| 215 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]); | 213 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[0]); |
| 216 builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_st r()); | 214 builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr0Name->c_str ()); |
| 217 | 215 |
| 218 builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fs EdgeName); | 216 builder->addVarying(kVec4f_GrSLType, "EllipseOffsets", &vsOffsetsNam e, &fsOffsetsName); |
| 219 const SkString* attr1Name = | 217 const SkString* attr1Name = |
| 220 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]); | 218 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]); |
| 221 builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str( )); | 219 builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetsName, attr1Name->c_s tr()); |
| 222 | 220 |
| 223 // translate to origin | 221 // get length of offset |
| 224 builder->fsCodeAppendf("\tvec2 outerOffset = (%s.xy - %s.xy);\n", | 222 builder->fsCodeAppendf("\tfloat dOuter = length(%s.xy);\n", fsOffset sName); |
| 225 builder->fragmentPosition(), fsCenterName); | |
| 226 builder->fsCodeAppend("\tvec2 innerOffset = outerOffset;\n"); | |
| 227 // scale y by xRadius/yRadius | |
| 228 builder->fsCodeAppendf("\touterOffset.y *= %s.y;\n", fsEdgeName); | |
| 229 builder->fsCodeAppend("\tfloat dOuter = length(outerOffset);\n"); | |
| 230 // compare outer lengths against xOuterRadius | 223 // compare outer lengths against xOuterRadius |
| 231 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", | 224 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", |
| 232 fsEdgeName); | 225 fsRadiiName); |
| 233 | 226 |
| 234 if (ellipseEffect.isStroked()) { | 227 if (ellipseEffect.isStroked()) { |
| 235 builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName) ; | 228 builder->fsCodeAppendf("\tfloat dInner = length(%s.zw);\n", fsOf fsetsName); |
| 236 builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n") ; | |
| 237 | 229 |
| 238 // compare inner lengths against xInnerRadius | 230 // compare inner lengths against xInnerRadius |
| 239 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.z, 0.0, 1.0);\n", | 231 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.y, 0.0, 1.0);\n", |
| 240 fsEdgeName); | 232 fsRadiiName); |
| 241 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); | 233 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); |
| 242 } | 234 } |
| 243 | 235 |
| 244 SkString modulate; | 236 SkString modulate; |
| 245 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); | 237 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); |
| 246 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() ); | 238 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() ); |
| 247 } | 239 } |
| 248 | 240 |
| 249 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { | 241 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { |
| 250 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); | 242 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 } | 369 } |
| 378 } | 370 } |
| 379 | 371 |
| 380 // The radii are outset for two reasons. First, it allows the shader to simp ly perform | 372 // The radii are outset for two reasons. First, it allows the shader to simp ly perform |
| 381 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use d to compute the | 373 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use d to compute the |
| 382 // verts of the bounding box that is rendered and the outset ensures the box will cover all | 374 // verts of the bounding box that is rendered and the outset ensures the box will cover all |
| 383 // pixels partially covered by the circle. | 375 // pixels partially covered by the circle. |
| 384 outerRadius += SK_ScalarHalf; | 376 outerRadius += SK_ScalarHalf; |
| 385 innerRadius -= SK_ScalarHalf; | 377 innerRadius -= SK_ScalarHalf; |
| 386 | 378 |
| 387 for (int i = 0; i < 4; ++i) { | |
| 388 verts[i].fCenter = center; | |
| 389 verts[i].fOuterRadius = outerRadius; | |
| 390 verts[i].fInnerRadius = innerRadius; | |
| 391 } | |
| 392 | |
| 393 SkRect bounds = SkRect::MakeLTRB( | 379 SkRect bounds = SkRect::MakeLTRB( |
| 394 center.fX - outerRadius, | 380 center.fX - outerRadius, |
| 395 center.fY - outerRadius, | 381 center.fY - outerRadius, |
| 396 center.fX + outerRadius, | 382 center.fX + outerRadius, |
| 397 center.fY + outerRadius | 383 center.fY + outerRadius |
| 398 ); | 384 ); |
| 399 | 385 |
| 400 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); | 386 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); |
| 387 verts[0].fOffset = SkPoint::Make(-outerRadius, -outerRadius); | |
| 388 verts[0].fOuterRadius = outerRadius; | |
| 389 verts[0].fInnerRadius = innerRadius; | |
| 390 | |
| 401 verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 391 verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
| 392 verts[1].fOffset = SkPoint::Make(outerRadius, -outerRadius); | |
| 393 verts[1].fOuterRadius = outerRadius; | |
| 394 verts[1].fInnerRadius = innerRadius; | |
| 395 | |
| 402 verts[2].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); | 396 verts[2].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); |
| 397 verts[2].fOffset = SkPoint::Make(-outerRadius, outerRadius); | |
| 398 verts[2].fOuterRadius = outerRadius; | |
| 399 verts[2].fInnerRadius = innerRadius; | |
| 400 | |
| 403 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); | 401 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); |
| 402 verts[3].fOffset = SkPoint::Make(outerRadius, outerRadius); | |
| 403 verts[3].fOuterRadius = outerRadius; | |
| 404 verts[3].fInnerRadius = innerRadius; | |
| 404 | 405 |
| 405 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds); | 406 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds); |
| 406 } | 407 } |
| 407 | 408 |
| 408 void GrOvalRenderer::drawEllipse(GrDrawTarget* target, | 409 void GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| 409 const GrPaint& paint, | 410 const GrPaint& paint, |
| 410 const GrRect& ellipse, | 411 const GrRect& ellipse, |
| 411 const SkStrokeRec& stroke) | 412 const SkStrokeRec& stroke) |
| 412 { | 413 { |
| 413 GrDrawState* drawState = target->drawState(); | 414 GrDrawState* drawState = target->drawState(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 innerXRadius = SkMaxScalar(0, xRadius - scaledStroke.fX); | 489 innerXRadius = SkMaxScalar(0, xRadius - scaledStroke.fX); |
| 489 innerRatio = innerXRadius/innerYRadius; | 490 innerRatio = innerXRadius/innerYRadius; |
| 490 } | 491 } |
| 491 } | 492 } |
| 492 xRadius += scaledStroke.fX; | 493 xRadius += scaledStroke.fX; |
| 493 yRadius += scaledStroke.fY; | 494 yRadius += scaledStroke.fY; |
| 494 } | 495 } |
| 495 | 496 |
| 496 SkScalar outerRatio = SkScalarDiv(xRadius, yRadius); | 497 SkScalar outerRatio = SkScalarDiv(xRadius, yRadius); |
| 497 | 498 |
| 498 for (int i = 0; i < 4; ++i) { | 499 // We've extended the outer x radius out half a pixel to antialias. |
| 499 verts[i].fCenter = center; | 500 // This will also expand the rect so all the pixels will be captured. |
| 500 verts[i].fOuterXRadius = xRadius + 0.5f; | 501 xRadius += SK_ScalarHalf; |
| 501 verts[i].fOuterXYRatio = outerRatio; | 502 yRadius += SK_ScalarHalf; |
| 502 verts[i].fInnerXRadius = innerXRadius - 0.5f; | 503 innerXRadius -= SK_ScalarHalf; |
| 503 verts[i].fInnerXYRatio = innerRatio; | |
| 504 } | |
| 505 | 504 |
| 506 SkScalar L = -xRadius; | 505 SkRect bounds = SkRect::MakeLTRB( |
| 507 SkScalar R = +xRadius; | 506 center.fX - xRadius, |
| 508 SkScalar T = -yRadius; | 507 center.fY - yRadius, |
| 509 SkScalar B = +yRadius; | 508 center.fX + xRadius, |
| 509 center.fY + yRadius | |
| 510 ); | |
| 510 | 511 |
| 511 // We've extended the outer x radius out half a pixel to antialias. | 512 // The offsets are created by scaling the y radius by the appropriate ratio. This way we end up |
| 512 // Expand the drawn rect here so all the pixels will be captured. | 513 // with a circle equation which can be checked quickly in the shader. We nee d one offset for |
| 513 L += center.fX - SK_ScalarHalf; | 514 // outer and one for inner because they have different scale factors -- othe rwise we end up with |
| 514 R += center.fX + SK_ScalarHalf; | 515 // non-uniform strokes. |
| 515 T += center.fY - SK_ScalarHalf; | 516 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); |
| 516 B += center.fY + SK_ScalarHalf; | 517 verts[0].fOuterXRadius = xRadius; |
| 518 verts[0].fInnerXRadius = innerXRadius; | |
| 519 verts[0].fOuterOffset = SkPoint::Make(-xRadius, -outerRatio*yRadius); | |
| 520 verts[0].fInnerOffset = SkPoint::Make(-xRadius, -innerRatio*yRadius); | |
| 517 | 521 |
| 518 verts[0].fPos = SkPoint::Make(L, T); | 522 verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
| 519 verts[1].fPos = SkPoint::Make(R, T); | 523 verts[1].fOuterXRadius = xRadius; |
| 520 verts[2].fPos = SkPoint::Make(L, B); | 524 verts[1].fInnerXRadius = innerXRadius; |
| 521 verts[3].fPos = SkPoint::Make(R, B); | 525 verts[1].fOuterOffset = SkPoint::Make(xRadius, -outerRatio*yRadius); |
| 526 verts[1].fInnerOffset = SkPoint::Make(xRadius, -innerRatio*yRadius); | |
| 522 | 527 |
| 523 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); | 528 verts[2].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); |
| 529 verts[2].fOuterXRadius = xRadius; | |
| 530 verts[2].fInnerXRadius = innerXRadius; | |
| 531 verts[2].fOuterOffset = SkPoint::Make(-xRadius, outerRatio*yRadius); | |
| 532 verts[2].fInnerOffset = SkPoint::Make(-xRadius, innerRatio*yRadius); | |
| 533 | |
| 534 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); | |
| 535 verts[3].fOuterXRadius = xRadius; | |
| 536 verts[3].fInnerXRadius = innerXRadius; | |
| 537 verts[3].fOuterOffset = SkPoint::Make(xRadius, outerRatio*yRadius); | |
| 538 verts[3].fInnerOffset = SkPoint::Make(xRadius, innerRatio*yRadius); | |
| 539 | |
|
robertphillips
2013/04/10 23:18:39
For the rect edge passing the bounds actually slow
| |
| 540 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds); | |
| 524 } | 541 } |
| OLD | NEW |