| 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 "gl/builders/GrGLProgramBuilder.h" | 8 #include "gl/builders/GrGLProgramBuilder.h" |
| 9 #include "GrOvalRenderer.h" | 9 #include "GrOvalRenderer.h" |
| 10 | 10 |
| 11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
| 12 #include "gl/GrGLEffect.h" | 12 #include "gl/GrGLEffect.h" |
| 13 #include "gl/GrGLSL.h" | 13 #include "gl/GrGLSL.h" |
| 14 #include "gl/GrGLVertexEffect.h" | 14 #include "gl/GrGLGeometryProcessor.h" |
| 15 #include "GrTBackendEffectFactory.h" | 15 #include "GrTBackendEffectFactory.h" |
| 16 | 16 |
| 17 #include "GrDrawState.h" | 17 #include "GrDrawState.h" |
| 18 #include "GrDrawTarget.h" | 18 #include "GrDrawTarget.h" |
| 19 #include "GrGpu.h" | 19 #include "GrGpu.h" |
| 20 | 20 |
| 21 #include "SkRRect.h" | 21 #include "SkRRect.h" |
| 22 #include "SkStrokeRec.h" | 22 #include "SkStrokeRec.h" |
| 23 #include "SkTLazy.h" | 23 #include "SkTLazy.h" |
| 24 | 24 |
| 25 #include "effects/GrVertexEffect.h" | 25 #include "effects/GrGeometryProcessor.h" |
| 26 #include "effects/GrRRectEffect.h" | 26 #include "effects/GrRRectEffect.h" |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 struct CircleVertex { | 30 struct CircleVertex { |
| 31 SkPoint fPos; | 31 SkPoint fPos; |
| 32 SkPoint fOffset; | 32 SkPoint fOffset; |
| 33 SkScalar fOuterRadius; | 33 SkScalar fOuterRadius; |
| 34 SkScalar fInnerRadius; | 34 SkScalar fInnerRadius; |
| 35 }; | 35 }; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 53 | 53 |
| 54 } | 54 } |
| 55 | 55 |
| 56 /////////////////////////////////////////////////////////////////////////////// | 56 /////////////////////////////////////////////////////////////////////////////// |
| 57 | 57 |
| 58 /** | 58 /** |
| 59 * The output of this effect is a modulation of the input color and coverage for
a circle, | 59 * The output of this effect is a modulation of the input color and coverage for
a circle, |
| 60 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. | 60 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. |
| 61 */ | 61 */ |
| 62 | 62 |
| 63 class CircleEdgeEffect : public GrVertexEffect { | 63 class CircleEdgeEffect : public GrGeometryProcessor { |
| 64 public: | 64 public: |
| 65 static GrEffect* Create(bool stroke) { | 65 static GrEffect* Create(bool stroke) { |
| 66 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); | 66 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); |
| 67 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); | 67 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); |
| 68 | 68 |
| 69 if (stroke) { | 69 if (stroke) { |
| 70 gCircleStrokeEdge->ref(); | 70 gCircleStrokeEdge->ref(); |
| 71 return gCircleStrokeEdge; | 71 return gCircleStrokeEdge; |
| 72 } else { | 72 } else { |
| 73 gCircleFillEdge->ref(); | 73 gCircleFillEdge->ref(); |
| 74 return gCircleFillEdge; | 74 return gCircleFillEdge; |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 | 77 |
| 78 virtual void getConstantColorComponents(GrColor* color, | 78 virtual void getConstantColorComponents(GrColor* color, |
| 79 uint32_t* validFlags) const SK_OVERR
IDE { | 79 uint32_t* validFlags) const SK_OVERR
IDE { |
| 80 *validFlags = 0; | 80 *validFlags = 0; |
| 81 } | 81 } |
| 82 | 82 |
| 83 const GrShaderVar& aCircleEdge() const { return fAttrCircleEdge; } |
| 84 |
| 83 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 85 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { |
| 84 return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance(); | 86 return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance(); |
| 85 } | 87 } |
| 86 | 88 |
| 87 virtual ~CircleEdgeEffect() {} | 89 virtual ~CircleEdgeEffect() {} |
| 88 | 90 |
| 89 static const char* Name() { return "CircleEdge"; } | 91 static const char* Name() { return "CircleEdge"; } |
| 90 | 92 |
| 91 inline bool isStroked() const { return fStroke; } | 93 inline bool isStroked() const { return fStroke; } |
| 92 | 94 |
| 93 class GLEffect : public GrGLVertexEffect { | 95 class GLEffect : public GrGLGeometryProcessor { |
| 94 public: | 96 public: |
| 95 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | 97 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) |
| 96 : INHERITED (factory) {} | 98 : INHERITED (factory) {} |
| 97 | 99 |
| 98 virtual void emitCode(GrGLFullProgramBuilder* builder, | 100 virtual void emitCode(GrGLFullProgramBuilder* builder, |
| 99 const GrDrawEffect& drawEffect, | 101 const GrDrawEffect& drawEffect, |
| 100 const GrEffectKey& key, | 102 const GrEffectKey& key, |
| 101 const char* outputColor, | 103 const char* outputColor, |
| 102 const char* inputColor, | 104 const char* inputColor, |
| 103 const TransformedCoordsArray&, | 105 const TransformedCoordsArray&, |
| 104 const TextureSamplerArray& samplers) SK_OVERRIDE { | 106 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 105 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE
dgeEffect>(); | 107 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE
dgeEffect>(); |
| 106 const char *vsName, *fsName; | 108 const char *vsName, *fsName; |
| 107 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName)
; | 109 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName)
; |
| 108 | 110 |
| 109 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); | 111 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
();; |
| 110 const SkString* attr0Name = | 112 vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.aCircleE
dge().c_str()); |
| 111 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi
ces()[0]); | |
| 112 vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str()); | |
| 113 | 113 |
| 114 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 114 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); |
| 115 fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName); | 115 fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName); |
| 116 fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0
);\n", fsName); | 116 fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0
);\n", fsName); |
| 117 if (circleEffect.isStroked()) { | 117 if (circleEffect.isStroked()) { |
| 118 fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0
, 1.0);\n", fsName); | 118 fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0
, 1.0);\n", fsName); |
| 119 fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n"); | 119 fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n"); |
| 120 } | 120 } |
| 121 | 121 |
| 122 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, | 122 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
| 123 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); | 123 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); |
| 124 } | 124 } |
| 125 | 125 |
| 126 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, | 126 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, |
| 127 GrEffectKeyBuilder* b) { | 127 GrEffectKeyBuilder* b) { |
| 128 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE
dgeEffect>(); | 128 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE
dgeEffect>(); |
| 129 b->add32(circleEffect.isStroked()); | 129 b->add32(circleEffect.isStroked()); |
| 130 } | 130 } |
| 131 | 131 |
| 132 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&)
SK_OVERRIDE {} | 132 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&)
SK_OVERRIDE {} |
| 133 | 133 |
| 134 private: | 134 private: |
| 135 typedef GrGLVertexEffect INHERITED; | 135 typedef GrGLGeometryProcessor INHERITED; |
| 136 }; | 136 }; |
| 137 | 137 |
| 138 | 138 |
| 139 private: | 139 private: |
| 140 CircleEdgeEffect(bool stroke) : GrVertexEffect() { | 140 CircleEdgeEffect(bool stroke) |
| 141 this->addVertexAttrib(kVec4f_GrSLType); | 141 : GrGeometryProcessor() |
| 142 , fAttrCircleEdge(this->addVertexAttrib( |
| 143 GrShaderVar("aCircleEdge", |
| 144 kVec4f_GrSLType, |
| 145 GrShaderVar::kAttribute_TypeModifier))) { |
| 142 fStroke = stroke; | 146 fStroke = stroke; |
| 143 } | 147 } |
| 144 | 148 |
| 145 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 149 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { |
| 146 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other); | 150 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other); |
| 147 return cee.fStroke == fStroke; | 151 return cee.fStroke == fStroke; |
| 148 } | 152 } |
| 149 | 153 |
| 154 const GrShaderVar& fAttrCircleEdge; |
| 150 bool fStroke; | 155 bool fStroke; |
| 151 | 156 |
| 152 GR_DECLARE_EFFECT_TEST; | 157 GR_DECLARE_EFFECT_TEST; |
| 153 | 158 |
| 154 typedef GrVertexEffect INHERITED; | 159 typedef GrGeometryProcessor INHERITED; |
| 155 }; | 160 }; |
| 156 | 161 |
| 157 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); | 162 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); |
| 158 | 163 |
| 159 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, | 164 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, |
| 160 GrContext* context, | 165 GrContext* context, |
| 161 const GrDrawTargetCaps&, | 166 const GrDrawTargetCaps&, |
| 162 GrTexture* textures[]) { | 167 GrTexture* textures[]) { |
| 163 return CircleEdgeEffect::Create(random->nextBool()); | 168 return CircleEdgeEffect::Create(random->nextBool()); |
| 164 } | 169 } |
| 165 | 170 |
| 166 /////////////////////////////////////////////////////////////////////////////// | 171 /////////////////////////////////////////////////////////////////////////////// |
| 167 | 172 |
| 168 /** | 173 /** |
| 169 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned | 174 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned |
| 170 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, | 175 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, |
| 171 * in both x and y directions. | 176 * in both x and y directions. |
| 172 * | 177 * |
| 173 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. | 178 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. |
| 174 */ | 179 */ |
| 175 | 180 |
| 176 class EllipseEdgeEffect : public GrVertexEffect { | 181 class EllipseEdgeEffect : public GrGeometryProcessor { |
| 177 public: | 182 public: |
| 178 static GrEffect* Create(bool stroke) { | 183 static GrEffect* Create(bool stroke) { |
| 179 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); | 184 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); |
| 180 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); | 185 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); |
| 181 | 186 |
| 182 if (stroke) { | 187 if (stroke) { |
| 183 gEllipseStrokeEdge->ref(); | 188 gEllipseStrokeEdge->ref(); |
| 184 return gEllipseStrokeEdge; | 189 return gEllipseStrokeEdge; |
| 185 } else { | 190 } else { |
| 186 gEllipseFillEdge->ref(); | 191 gEllipseFillEdge->ref(); |
| 187 return gEllipseFillEdge; | 192 return gEllipseFillEdge; |
| 188 } | 193 } |
| 189 } | 194 } |
| 190 | 195 |
| 191 virtual void getConstantColorComponents(GrColor* color, | 196 virtual void getConstantColorComponents(GrColor* color, |
| 192 uint32_t* validFlags) const SK_OVERR
IDE { | 197 uint32_t* validFlags) const SK_OVERR
IDE { |
| 193 *validFlags = 0; | 198 *validFlags = 0; |
| 194 } | 199 } |
| 195 | 200 |
| 196 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 201 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { |
| 197 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); | 202 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); |
| 198 } | 203 } |
| 199 | 204 |
| 200 virtual ~EllipseEdgeEffect() {} | 205 virtual ~EllipseEdgeEffect() {} |
| 201 | 206 |
| 202 static const char* Name() { return "EllipseEdge"; } | 207 static const char* Name() { return "EllipseEdge"; } |
| 203 | 208 |
| 209 const GrShaderVar& aEllipseOffset() const { return fAttrEllipseOffset; } |
| 210 const GrShaderVar& aEllipseRadii() const { return fAttrEllipseRadii; } |
| 211 |
| 204 inline bool isStroked() const { return fStroke; } | 212 inline bool isStroked() const { return fStroke; } |
| 205 | 213 |
| 206 class GLEffect : public GrGLVertexEffect { | 214 class GLEffect : public GrGLGeometryProcessor { |
| 207 public: | 215 public: |
| 208 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | 216 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) |
| 209 : INHERITED (factory) {} | 217 : INHERITED (factory) {} |
| 210 | 218 |
| 211 virtual void emitCode(GrGLFullProgramBuilder* builder, | 219 virtual void emitCode(GrGLFullProgramBuilder* builder, |
| 212 const GrDrawEffect& drawEffect, | 220 const GrDrawEffect& drawEffect, |
| 213 const GrEffectKey& key, | 221 const GrEffectKey& key, |
| 214 const char* outputColor, | 222 const char* outputColor, |
| 215 const char* inputColor, | 223 const char* inputColor, |
| 216 const TransformedCoordsArray&, | 224 const TransformedCoordsArray&, |
| 217 const TextureSamplerArray& samplers) SK_OVERRIDE { | 225 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 218 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip
seEdgeEffect>(); | 226 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip
seEdgeEffect>(); |
| 219 | 227 |
| 220 const char *vsOffsetName, *fsOffsetName; | 228 const char *vsOffsetName, *fsOffsetName; |
| 221 const char *vsRadiiName, *fsRadiiName; | 229 const char *vsRadiiName, *fsRadiiName; |
| 222 | 230 |
| 223 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName
, &fsOffsetName); | 231 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName
, &fsOffsetName); |
| 224 | 232 |
| 225 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); | 233 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); |
| 226 const SkString* attr0Name = | 234 vsBuilder->codeAppendf("%s = %s;", vsOffsetName, |
| 227 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi
ces()[0]); | 235 ellipseEffect.aEllipseOffset().c_str()); |
| 228 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_st
r()); | |
| 229 | 236 |
| 230 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &
fsRadiiName); | 237 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &
fsRadiiName); |
| 231 const SkString* attr1Name = | 238 vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.aEllip
seRadii().c_str()); |
| 232 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi
ces()[1]); | |
| 233 vsBuilder->codeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str
()); | |
| 234 | 239 |
| 235 // for outer curve | 240 // for outer curve |
| 236 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 241 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); |
| 237 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset
Name, fsRadiiName); | 242 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset
Name, fsRadiiName); |
| 238 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); | 243 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); |
| 239 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs
RadiiName); | 244 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs
RadiiName); |
| 240 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); | 245 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); |
| 241 // avoid calling inversesqrt on zero. | 246 // avoid calling inversesqrt on zero. |
| 242 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); | 247 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); |
| 243 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); | 248 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 259 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, | 264 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, |
| 260 GrEffectKeyBuilder* b) { | 265 GrEffectKeyBuilder* b) { |
| 261 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip
seEdgeEffect>(); | 266 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip
seEdgeEffect>(); |
| 262 b->add32(ellipseEffect.isStroked()); | 267 b->add32(ellipseEffect.isStroked()); |
| 263 } | 268 } |
| 264 | 269 |
| 265 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&)
SK_OVERRIDE { | 270 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&)
SK_OVERRIDE { |
| 266 } | 271 } |
| 267 | 272 |
| 268 private: | 273 private: |
| 269 typedef GrGLVertexEffect INHERITED; | 274 typedef GrGLGeometryProcessor INHERITED; |
| 270 }; | 275 }; |
| 271 | 276 |
| 272 private: | 277 private: |
| 273 EllipseEdgeEffect(bool stroke) : GrVertexEffect() { | 278 EllipseEdgeEffect(bool stroke) |
| 274 this->addVertexAttrib(kVec2f_GrSLType); | 279 : GrGeometryProcessor() |
| 275 this->addVertexAttrib(kVec4f_GrSLType); | 280 , fAttrEllipseOffset(this->addVertexAttrib( |
| 281 GrShaderVar("aEllipseOffset", |
| 282 kVec2f_GrSLType, |
| 283 GrShaderVar::kAttribute_TypeModifier))) |
| 284 , fAttrEllipseRadii(this->addVertexAttrib( |
| 285 GrShaderVar("aEllipseRadii", |
| 286 kVec4f_GrSLType, |
| 287 GrShaderVar::kAttribute_TypeModifier))) { |
| 276 fStroke = stroke; | 288 fStroke = stroke; |
| 277 } | 289 } |
| 278 | 290 |
| 279 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 291 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { |
| 280 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other); | 292 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other); |
| 281 return eee.fStroke == fStroke; | 293 return eee.fStroke == fStroke; |
| 282 } | 294 } |
| 283 | 295 |
| 296 const GrShaderVar& fAttrEllipseOffset; |
| 297 const GrShaderVar& fAttrEllipseRadii; |
| 284 bool fStroke; | 298 bool fStroke; |
| 285 | 299 |
| 286 GR_DECLARE_EFFECT_TEST; | 300 GR_DECLARE_EFFECT_TEST; |
| 287 | 301 |
| 288 typedef GrVertexEffect INHERITED; | 302 typedef GrGeometryProcessor INHERITED; |
| 289 }; | 303 }; |
| 290 | 304 |
| 291 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); | 305 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); |
| 292 | 306 |
| 293 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, | 307 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, |
| 294 GrContext* context, | 308 GrContext* context, |
| 295 const GrDrawTargetCaps&, | 309 const GrDrawTargetCaps&, |
| 296 GrTexture* textures[]) { | 310 GrTexture* textures[]) { |
| 297 return EllipseEdgeEffect::Create(random->nextBool()); | 311 return EllipseEdgeEffect::Create(random->nextBool()); |
| 298 } | 312 } |
| 299 | 313 |
| 300 /////////////////////////////////////////////////////////////////////////////// | 314 /////////////////////////////////////////////////////////////////////////////// |
| 301 | 315 |
| 302 /** | 316 /** |
| 303 * The output of this effect is a modulation of the input color and coverage for
an ellipse, | 317 * The output of this effect is a modulation of the input color and coverage for
an ellipse, |
| 304 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The | 318 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The |
| 305 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by | 319 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by |
| 306 * using differentials. | 320 * using differentials. |
| 307 * | 321 * |
| 308 * The result is device-independent and can be used with any affine matrix. | 322 * The result is device-independent and can be used with any affine matrix. |
| 309 */ | 323 */ |
| 310 | 324 |
| 311 class DIEllipseEdgeEffect : public GrVertexEffect { | 325 class DIEllipseEdgeEffect : public GrGeometryProcessor { |
| 312 public: | 326 public: |
| 313 enum Mode { kStroke = 0, kHairline, kFill }; | 327 enum Mode { kStroke = 0, kHairline, kFill }; |
| 314 | 328 |
| 315 static GrEffect* Create(Mode mode) { | 329 static GrEffect* Create(Mode mode) { |
| 316 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok
e)); | 330 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok
e)); |
| 317 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai
rline)); | 331 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai
rline)); |
| 318 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); | 332 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); |
| 319 | 333 |
| 320 if (kStroke == mode) { | 334 if (kStroke == mode) { |
| 321 gEllipseStrokeEdge->ref(); | 335 gEllipseStrokeEdge->ref(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 335 } | 349 } |
| 336 | 350 |
| 337 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 351 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { |
| 338 return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance(); | 352 return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance(); |
| 339 } | 353 } |
| 340 | 354 |
| 341 virtual ~DIEllipseEdgeEffect() {} | 355 virtual ~DIEllipseEdgeEffect() {} |
| 342 | 356 |
| 343 static const char* Name() { return "DIEllipseEdge"; } | 357 static const char* Name() { return "DIEllipseEdge"; } |
| 344 | 358 |
| 359 const GrShaderVar& aEllipseOffsets0() const { return fAttrEllipseOffsets0; } |
| 360 const GrShaderVar& aEllipseOffsets1() const { return fAttrEllipseOffsets1; } |
| 361 |
| 345 inline Mode getMode() const { return fMode; } | 362 inline Mode getMode() const { return fMode; } |
| 346 | 363 |
| 347 class GLEffect : public GrGLVertexEffect { | 364 class GLEffect : public GrGLGeometryProcessor { |
| 348 public: | 365 public: |
| 349 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | 366 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) |
| 350 : INHERITED (factory) {} | 367 : INHERITED (factory) {} |
| 351 | 368 |
| 352 virtual void emitCode(GrGLFullProgramBuilder* builder, | 369 virtual void emitCode(GrGLFullProgramBuilder* builder, |
| 353 const GrDrawEffect& drawEffect, | 370 const GrDrawEffect& drawEffect, |
| 354 const GrEffectKey& key, | 371 const GrEffectKey& key, |
| 355 const char* outputColor, | 372 const char* outputColor, |
| 356 const char* inputColor, | 373 const char* inputColor, |
| 357 const TransformedCoordsArray&, | 374 const TransformedCoordsArray&, |
| 358 const TextureSamplerArray& samplers) SK_OVERRIDE { | 375 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 359 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE
llipseEdgeEffect>(); | 376 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE
llipseEdgeEffect>(); |
| 360 | 377 |
| 361 const char *vsOffsetName0, *fsOffsetName0; | 378 const char *vsOffsetName0, *fsOffsetName0; |
| 362 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", | 379 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", |
| 363 &vsOffsetName0, &fsOffsetName0); | 380 &vsOffsetName0, &fsOffsetName0); |
| 364 | 381 |
| 365 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); | 382 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); |
| 366 const SkString* attr0Name = | 383 vsBuilder->codeAppendf("%s = %s;", vsOffsetName0, |
| 367 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi
ces()[0]); | 384 ellipseEffect.aEllipseOffsets0().c_str()); |
| 368 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_s
tr()); | |
| 369 const char *vsOffsetName1, *fsOffsetName1; | 385 const char *vsOffsetName1, *fsOffsetName1; |
| 370 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", | 386 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", |
| 371 &vsOffsetName1, &fsOffsetName1); | 387 &vsOffsetName1, &fsOffsetName1); |
| 372 const SkString* attr1Name = | 388 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, |
| 373 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi
ces()[1]); | 389 ellipseEffect.aEllipseOffsets1().c_str()); |
| 374 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_s
tr()); | |
| 375 | 390 |
| 376 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 391 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); |
| 377 SkAssertResult(fsBuilder->enableFeature( | 392 SkAssertResult(fsBuilder->enableFeature( |
| 378 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)
); | 393 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)
); |
| 379 // for outer curve | 394 // for outer curve |
| 380 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam
e0); | 395 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam
e0); |
| 381 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); | 396 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); |
| 382 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); | 397 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); |
| 383 fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); | 398 fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); |
| 384 fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s
.y*duvdx.y,\n" | 399 fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s
.y*duvdx.y,\n" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 const DIEllipseEdgeEffect& ellipseEffect = | 434 const DIEllipseEdgeEffect& ellipseEffect = |
| 420 drawEffect.castEffect<DIEllipseEdgeEffect>(); | 435 drawEffect.castEffect<DIEllipseEdgeEffect>(); |
| 421 | 436 |
| 422 b->add32(ellipseEffect.getMode()); | 437 b->add32(ellipseEffect.getMode()); |
| 423 } | 438 } |
| 424 | 439 |
| 425 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&)
SK_OVERRIDE { | 440 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&)
SK_OVERRIDE { |
| 426 } | 441 } |
| 427 | 442 |
| 428 private: | 443 private: |
| 429 typedef GrGLVertexEffect INHERITED; | 444 typedef GrGLGeometryProcessor INHERITED; |
| 430 }; | 445 }; |
| 431 | 446 |
| 432 private: | 447 private: |
| 433 DIEllipseEdgeEffect(Mode mode) : GrVertexEffect() { | 448 DIEllipseEdgeEffect(Mode mode) |
| 434 this->addVertexAttrib(kVec2f_GrSLType); | 449 : GrGeometryProcessor() |
| 435 this->addVertexAttrib(kVec2f_GrSLType); | 450 , fAttrEllipseOffsets0(this->addVertexAttrib( |
| 451 GrShaderVar("aEllipseOffsets0", |
| 452 kVec2f_GrSLType, |
| 453 GrShaderVar::kAttribute_TypeModifier))) |
| 454 , fAttrEllipseOffsets1(this->addVertexAttrib( |
| 455 GrShaderVar("aEllipseOffsets1", |
| 456 kVec2f_GrSLType, |
| 457 GrShaderVar::kAttribute_TypeModifier))) { |
| 436 fMode = mode; | 458 fMode = mode; |
| 437 } | 459 } |
| 438 | 460 |
| 439 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 461 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { |
| 440 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other); | 462 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other); |
| 441 return eee.fMode == fMode; | 463 return eee.fMode == fMode; |
| 442 } | 464 } |
| 443 | 465 |
| 466 const GrShaderVar& fAttrEllipseOffsets0; |
| 467 const GrShaderVar& fAttrEllipseOffsets1; |
| 444 Mode fMode; | 468 Mode fMode; |
| 445 | 469 |
| 446 GR_DECLARE_EFFECT_TEST; | 470 GR_DECLARE_EFFECT_TEST; |
| 447 | 471 |
| 448 typedef GrVertexEffect INHERITED; | 472 typedef GrGeometryProcessor INHERITED; |
| 449 }; | 473 }; |
| 450 | 474 |
| 451 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); | 475 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); |
| 452 | 476 |
| 453 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, | 477 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, |
| 454 GrContext* context, | 478 GrContext* context, |
| 455 const GrDrawTargetCaps&, | 479 const GrDrawTargetCaps&, |
| 456 GrTexture* textures[]) { | 480 GrTexture* textures[]) { |
| 457 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); | 481 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); |
| 458 } | 482 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 halfWidth = SkScalarHalf(strokeWidth); | 569 halfWidth = SkScalarHalf(strokeWidth); |
| 546 } | 570 } |
| 547 | 571 |
| 548 outerRadius += halfWidth; | 572 outerRadius += halfWidth; |
| 549 if (isStrokeOnly) { | 573 if (isStrokeOnly) { |
| 550 innerRadius = radius - halfWidth; | 574 innerRadius = radius - halfWidth; |
| 551 } | 575 } |
| 552 } | 576 } |
| 553 | 577 |
| 554 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0)
; | 578 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0)
; |
| 555 static const int kCircleEdgeAttrIndex = 1; | 579 drawState->setGeometryProcessor(effect)->unref(); |
| 556 drawState->setGeometryProcessor(effect, kCircleEdgeAttrIndex)->unref(); | |
| 557 | 580 |
| 558 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform | 581 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform |
| 559 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use
d to compute the | 582 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use
d to compute the |
| 560 // verts of the bounding box that is rendered and the outset ensures the box
will cover all | 583 // verts of the bounding box that is rendered and the outset ensures the box
will cover all |
| 561 // pixels partially covered by the circle. | 584 // pixels partially covered by the circle. |
| 562 outerRadius += SK_ScalarHalf; | 585 outerRadius += SK_ScalarHalf; |
| 563 innerRadius -= SK_ScalarHalf; | 586 innerRadius -= SK_ScalarHalf; |
| 564 | 587 |
| 565 SkRect bounds = SkRect::MakeLTRB( | 588 SkRect bounds = SkRect::MakeLTRB( |
| 566 center.fX - outerRadius, | 589 center.fX - outerRadius, |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 if (!geo.succeeded()) { | 710 if (!geo.succeeded()) { |
| 688 GrPrintf("Failed to get space for vertices!\n"); | 711 GrPrintf("Failed to get space for vertices!\n"); |
| 689 return false; | 712 return false; |
| 690 } | 713 } |
| 691 | 714 |
| 692 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 715 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| 693 | 716 |
| 694 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && | 717 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && |
| 695 innerXRadius > 0 && innerYRadiu
s > 0); | 718 innerXRadius > 0 && innerYRadiu
s > 0); |
| 696 | 719 |
| 697 static const int kEllipseCenterAttrIndex = 1; | 720 drawState->setGeometryProcessor(effect)->unref(); |
| 698 static const int kEllipseEdgeAttrIndex = 2; | |
| 699 drawState->setGeometryProcessor(effect, kEllipseCenterAttrIndex, kEllipseEdg
eAttrIndex)->unref(); | |
| 700 | 721 |
| 701 // Compute the reciprocals of the radii here to save time in the shader | 722 // Compute the reciprocals of the radii here to save time in the shader |
| 702 SkScalar xRadRecip = SkScalarInvert(xRadius); | 723 SkScalar xRadRecip = SkScalarInvert(xRadius); |
| 703 SkScalar yRadRecip = SkScalarInvert(yRadius); | 724 SkScalar yRadRecip = SkScalarInvert(yRadius); |
| 704 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 725 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
| 705 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 726 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
| 706 | 727 |
| 707 // We've extended the outer x radius out half a pixel to antialias. | 728 // We've extended the outer x radius out half a pixel to antialias. |
| 708 // This will also expand the rect so all the pixels will be captured. | 729 // This will also expand the rect so all the pixels will be captured. |
| 709 // TODO: Consider if we should use sqrt(2)/2 instead | 730 // TODO: Consider if we should use sqrt(2)/2 instead |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 826 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
| 806 if (!geo.succeeded()) { | 827 if (!geo.succeeded()) { |
| 807 GrPrintf("Failed to get space for vertices!\n"); | 828 GrPrintf("Failed to get space for vertices!\n"); |
| 808 return false; | 829 return false; |
| 809 } | 830 } |
| 810 | 831 |
| 811 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); | 832 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); |
| 812 | 833 |
| 813 GrEffect* effect = DIEllipseEdgeEffect::Create(mode); | 834 GrEffect* effect = DIEllipseEdgeEffect::Create(mode); |
| 814 | 835 |
| 815 static const int kEllipseOuterOffsetAttrIndex = 1; | 836 drawState->setGeometryProcessor(effect)->unref(); |
| 816 static const int kEllipseInnerOffsetAttrIndex = 2; | |
| 817 drawState->setGeometryProcessor(effect, kEllipseOuterOffsetAttrIndex, | |
| 818 kEllipseInnerOffsetAttrIndex)->unref(); | |
| 819 | 837 |
| 820 // This expands the outer rect so that after CTM we end up with a half-pixel
border | 838 // This expands the outer rect so that after CTM we end up with a half-pixel
border |
| 821 SkScalar a = vm[SkMatrix::kMScaleX]; | 839 SkScalar a = vm[SkMatrix::kMScaleX]; |
| 822 SkScalar b = vm[SkMatrix::kMSkewX]; | 840 SkScalar b = vm[SkMatrix::kMSkewX]; |
| 823 SkScalar c = vm[SkMatrix::kMSkewY]; | 841 SkScalar c = vm[SkMatrix::kMSkewY]; |
| 824 SkScalar d = vm[SkMatrix::kMScaleY]; | 842 SkScalar d = vm[SkMatrix::kMScaleY]; |
| 825 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); | 843 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); |
| 826 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); | 844 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); |
| 827 // This adjusts the "radius" to include the half-pixel border | 845 // This adjusts the "radius" to include the half-pixel border |
| 828 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); | 846 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 if (isStrokeOnly) { | 1073 if (isStrokeOnly) { |
| 1056 innerRadius = xRadius - halfWidth; | 1074 innerRadius = xRadius - halfWidth; |
| 1057 } | 1075 } |
| 1058 outerRadius += halfWidth; | 1076 outerRadius += halfWidth; |
| 1059 bounds.outset(halfWidth, halfWidth); | 1077 bounds.outset(halfWidth, halfWidth); |
| 1060 } | 1078 } |
| 1061 | 1079 |
| 1062 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); | 1080 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
| 1063 | 1081 |
| 1064 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); | 1082 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); |
| 1065 static const int kCircleEdgeAttrIndex = 1; | 1083 drawState->setGeometryProcessor(effect)->unref(); |
| 1066 drawState->setGeometryProcessor(effect, kCircleEdgeAttrIndex)->unref(); | |
| 1067 | 1084 |
| 1068 // The radii are outset for two reasons. First, it allows the shader to
simply perform | 1085 // The radii are outset for two reasons. First, it allows the shader to
simply perform |
| 1069 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the | 1086 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the |
| 1070 // verts of the bounding box that is rendered and the outset ensures the
box will cover all | 1087 // verts of the bounding box that is rendered and the outset ensures the
box will cover all |
| 1071 // pixels partially covered by the circle. | 1088 // pixels partially covered by the circle. |
| 1072 outerRadius += SK_ScalarHalf; | 1089 outerRadius += SK_ScalarHalf; |
| 1073 innerRadius -= SK_ScalarHalf; | 1090 innerRadius -= SK_ScalarHalf; |
| 1074 | 1091 |
| 1075 // Expand the rect so all the pixels will be captured. | 1092 // Expand the rect so all the pixels will be captured. |
| 1076 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 1093 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 1176 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
| 1160 | 1177 |
| 1161 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 1178 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
| 1162 if (!geo.succeeded()) { | 1179 if (!geo.succeeded()) { |
| 1163 GrPrintf("Failed to get space for vertices!\n"); | 1180 GrPrintf("Failed to get space for vertices!\n"); |
| 1164 return false; | 1181 return false; |
| 1165 } | 1182 } |
| 1166 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 1183 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| 1167 | 1184 |
| 1168 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); | 1185 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); |
| 1169 static const int kEllipseOffsetAttrIndex = 1; | 1186 drawState->setGeometryProcessor(effect)->unref(); |
| 1170 static const int kEllipseRadiiAttrIndex = 2; | |
| 1171 drawState->setGeometryProcessor(effect, | |
| 1172 kEllipseOffsetAttrIndex, | |
| 1173 kEllipseRadiiAttrIndex)->unref(); | |
| 1174 | 1187 |
| 1175 // Compute the reciprocals of the radii here to save time in the shader | 1188 // Compute the reciprocals of the radii here to save time in the shader |
| 1176 SkScalar xRadRecip = SkScalarInvert(xRadius); | 1189 SkScalar xRadRecip = SkScalarInvert(xRadius); |
| 1177 SkScalar yRadRecip = SkScalarInvert(yRadius); | 1190 SkScalar yRadRecip = SkScalarInvert(yRadius); |
| 1178 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 1191 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
| 1179 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 1192 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
| 1180 | 1193 |
| 1181 // Extend the radii out half a pixel to antialias. | 1194 // Extend the radii out half a pixel to antialias. |
| 1182 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; | 1195 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; |
| 1183 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; | 1196 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 | 1239 |
| 1227 // drop out the middle quad if we're stroked | 1240 // drop out the middle quad if we're stroked |
| 1228 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1241 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
| 1229 SK_ARRAY_COUNT(gRRectIndices); | 1242 SK_ARRAY_COUNT(gRRectIndices); |
| 1230 target->setIndexSourceToBuffer(indexBuffer); | 1243 target->setIndexSourceToBuffer(indexBuffer); |
| 1231 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); | 1244 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); |
| 1232 } | 1245 } |
| 1233 | 1246 |
| 1234 return true; | 1247 return true; |
| 1235 } | 1248 } |
| OLD | NEW |