Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 543623004: Removing vertex attrib indices (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: test Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698