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

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: feedback inc 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 const GrShaderVar kAttrCircleEdge("aCircleEdge",
64 kVec4f_GrSLType,
65 GrShaderVar::kAttribute_TypeModifier);
66
67 class CircleEdgeEffect : public GrGeometryProcessor {
64 public: 68 public:
65 static GrEffect* Create(bool stroke) { 69 static GrEffect* Create(bool stroke) {
66 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); 70 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true));
67 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); 71 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false));
68 72
69 if (stroke) { 73 if (stroke) {
70 gCircleStrokeEdge->ref(); 74 gCircleStrokeEdge->ref();
71 return gCircleStrokeEdge; 75 return gCircleStrokeEdge;
72 } else { 76 } else {
73 gCircleFillEdge->ref(); 77 gCircleFillEdge->ref();
74 return gCircleFillEdge; 78 return gCircleFillEdge;
75 } 79 }
76 } 80 }
77 81
78 virtual void getConstantColorComponents(GrColor* color, 82 virtual void getConstantColorComponents(GrColor* color,
79 uint32_t* validFlags) const SK_OVERR IDE { 83 uint32_t* validFlags) const SK_OVERR IDE {
80 *validFlags = 0; 84 *validFlags = 0;
81 } 85 }
82 86
83 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 87 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
84 return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance(); 88 return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance();
85 } 89 }
86 90
87 virtual ~CircleEdgeEffect() {} 91 virtual ~CircleEdgeEffect() {}
88 92
89 static const char* Name() { return "CircleEdge"; } 93 static const char* Name() { return "CircleEdge"; }
90 94
91 inline bool isStroked() const { return fStroke; } 95 inline bool isStroked() const { return fStroke; }
92 96
93 class GLEffect : public GrGLVertexEffect { 97 class GLEffect : public GrGLGeometryProcessor {
94 public: 98 public:
95 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 99 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
96 : INHERITED (factory) {} 100 : INHERITED (factory) {}
97 101
98 virtual void emitCode(GrGLFullProgramBuilder* builder, 102 virtual void emitCode(GrGLFullProgramBuilder* builder,
99 const GrDrawEffect& drawEffect, 103 const GrDrawEffect& drawEffect,
100 const GrEffectKey& key, 104 const GrEffectKey& key,
101 const char* outputColor, 105 const char* outputColor,
102 const char* inputColor, 106 const char* inputColor,
103 const TransformedCoordsArray&, 107 const TransformedCoordsArray&,
104 const TextureSamplerArray& samplers) SK_OVERRIDE { 108 const TextureSamplerArray& samplers) SK_OVERRIDE {
105 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>(); 109 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>();
106 const char *vsName, *fsName; 110 const char *vsName, *fsName;
107 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName) ; 111 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName) ;
108 112
109 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder (); 113 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder ();;
110 const SkString* attr0Name = 114 vsBuilder->codeAppendf("\t%s = %s;\n", vsName, kAttrCircleEdge.c_str ());
111 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[0]);
112 vsBuilder->codeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
113 115
114 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder(); 116 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder();
115 fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName); 117 fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName);
116 fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0 );\n", fsName); 118 fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0 );\n", fsName);
117 if (circleEffect.isStroked()) { 119 if (circleEffect.isStroked()) {
118 fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0 , 1.0);\n", fsName); 120 fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0 , 1.0);\n", fsName);
119 fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n"); 121 fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n");
120 } 122 }
121 123
122 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 124 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
123 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA lpha")).c_str()); 125 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA lpha")).c_str());
124 } 126 }
125 127
126 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, 128 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
127 GrEffectKeyBuilder* b) { 129 GrEffectKeyBuilder* b) {
128 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>(); 130 const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleE dgeEffect>();
129 b->add32(circleEffect.isStroked()); 131 b->add32(circleEffect.isStroked());
130 } 132 }
131 133
132 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {} 134 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {}
133 135
134 private: 136 private:
135 typedef GrGLVertexEffect INHERITED; 137 typedef GrGLGeometryProcessor INHERITED;
136 }; 138 };
137 139
138 140
139 private: 141 private:
140 CircleEdgeEffect(bool stroke) : GrVertexEffect() { 142 CircleEdgeEffect(bool stroke) : GrGeometryProcessor() {
141 this->addVertexAttrib(kVec4f_GrSLType); 143 this->addVertexAttrib(kAttrCircleEdge);
142 fStroke = stroke; 144 fStroke = stroke;
143 } 145 }
144 146
145 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 147 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
146 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other); 148 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other);
147 return cee.fStroke == fStroke; 149 return cee.fStroke == fStroke;
148 } 150 }
149 151
150 bool fStroke; 152 bool fStroke;
151 153
152 GR_DECLARE_EFFECT_TEST; 154 GR_DECLARE_EFFECT_TEST;
153 155
154 typedef GrVertexEffect INHERITED; 156 typedef GrGeometryProcessor INHERITED;
155 }; 157 };
156 158
157 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); 159 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect);
158 160
159 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, 161 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random,
160 GrContext* context, 162 GrContext* context,
161 const GrDrawTargetCaps&, 163 const GrDrawTargetCaps&,
162 GrTexture* textures[]) { 164 GrTexture* textures[]) {
163 return CircleEdgeEffect::Create(random->nextBool()); 165 return CircleEdgeEffect::Create(random->nextBool());
164 } 166 }
165 167
166 /////////////////////////////////////////////////////////////////////////////// 168 ///////////////////////////////////////////////////////////////////////////////
167 169
168 /** 170 /**
169 * The output of this effect is a modulation of the input color and coverage for an axis-aligned 171 * 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, 172 * 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. 173 * in both x and y directions.
172 * 174 *
173 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. 175 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0.
174 */ 176 */
175 177
176 class EllipseEdgeEffect : public GrVertexEffect { 178 const GrShaderVar kAttrEllipseOffset("aEllipseOffset",
179 kVec2f_GrSLType,
180 GrShaderVar::kAttribute_TypeModifier);
181
182 const GrShaderVar kAttrEllipseRadii("aEllipseRadii",
183 kVec4f_GrSLType,
184 GrShaderVar::kAttribute_TypeModifier);
185
186 class EllipseEdgeEffect : public GrGeometryProcessor {
177 public: 187 public:
178 static GrEffect* Create(bool stroke) { 188 static GrEffect* Create(bool stroke) {
179 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); 189 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true));
180 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); 190 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false));
181 191
182 if (stroke) { 192 if (stroke) {
183 gEllipseStrokeEdge->ref(); 193 gEllipseStrokeEdge->ref();
184 return gEllipseStrokeEdge; 194 return gEllipseStrokeEdge;
185 } else { 195 } else {
186 gEllipseFillEdge->ref(); 196 gEllipseFillEdge->ref();
187 return gEllipseFillEdge; 197 return gEllipseFillEdge;
188 } 198 }
189 } 199 }
190 200
191 virtual void getConstantColorComponents(GrColor* color, 201 virtual void getConstantColorComponents(GrColor* color,
192 uint32_t* validFlags) const SK_OVERR IDE { 202 uint32_t* validFlags) const SK_OVERR IDE {
193 *validFlags = 0; 203 *validFlags = 0;
194 } 204 }
195 205
196 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 206 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
197 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); 207 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance();
198 } 208 }
199 209
200 virtual ~EllipseEdgeEffect() {} 210 virtual ~EllipseEdgeEffect() {}
201 211
202 static const char* Name() { return "EllipseEdge"; } 212 static const char* Name() { return "EllipseEdge"; }
203 213
204 inline bool isStroked() const { return fStroke; } 214 inline bool isStroked() const { return fStroke; }
205 215
206 class GLEffect : public GrGLVertexEffect { 216 class GLEffect : public GrGLGeometryProcessor {
207 public: 217 public:
208 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 218 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
209 : INHERITED (factory) {} 219 : INHERITED (factory) {}
210 220
211 virtual void emitCode(GrGLFullProgramBuilder* builder, 221 virtual void emitCode(GrGLFullProgramBuilder* builder,
212 const GrDrawEffect& drawEffect, 222 const GrDrawEffect& drawEffect,
213 const GrEffectKey& key, 223 const GrEffectKey& key,
214 const char* outputColor, 224 const char* outputColor,
215 const char* inputColor, 225 const char* inputColor,
216 const TransformedCoordsArray&, 226 const TransformedCoordsArray&,
217 const TextureSamplerArray& samplers) SK_OVERRIDE { 227 const TextureSamplerArray& samplers) SK_OVERRIDE {
218 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); 228 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
219 229
220 const char *vsOffsetName, *fsOffsetName; 230 const char *vsOffsetName, *fsOffsetName;
221 const char *vsRadiiName, *fsRadiiName; 231 const char *vsRadiiName, *fsRadiiName;
222 232
223 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName , &fsOffsetName); 233 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName , &fsOffsetName);
224 234
225 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder (); 235 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder ();
226 const SkString* attr0Name = 236 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName, kAttrEllipseOff set.c_str());
227 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[0]);
228 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_st r());
229 237
230 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName); 238 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName);
231 const SkString* attr1Name = 239 vsBuilder->codeAppendf("\t%s = %s;\n", vsRadiiName, kAttrEllipseRadi i.c_str());
232 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[1]);
233 vsBuilder->codeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str ());
234 240
235 // for outer curve 241 // for outer curve
236 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder(); 242 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder();
237 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset Name, fsRadiiName); 243 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset Name, fsRadiiName);
238 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n"); 244 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n");
239 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs RadiiName); 245 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs RadiiName);
240 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); 246 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
241 // avoid calling inversesqrt on zero. 247 // avoid calling inversesqrt on zero.
242 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); 248 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
243 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); 249 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
(...skipping 15 matching lines...) Expand all
259 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, 265 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
260 GrEffectKeyBuilder* b) { 266 GrEffectKeyBuilder* b) {
261 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); 267 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
262 b->add32(ellipseEffect.isStroked()); 268 b->add32(ellipseEffect.isStroked());
263 } 269 }
264 270
265 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE { 271 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {
266 } 272 }
267 273
268 private: 274 private:
269 typedef GrGLVertexEffect INHERITED; 275 typedef GrGLGeometryProcessor INHERITED;
270 }; 276 };
271 277
272 private: 278 private:
273 EllipseEdgeEffect(bool stroke) : GrVertexEffect() { 279 EllipseEdgeEffect(bool stroke) : GrGeometryProcessor() {
274 this->addVertexAttrib(kVec2f_GrSLType); 280 this->addVertexAttrib(kAttrEllipseOffset);
275 this->addVertexAttrib(kVec4f_GrSLType); 281 this->addVertexAttrib(kAttrEllipseRadii);
276 fStroke = stroke; 282 fStroke = stroke;
277 } 283 }
278 284
279 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 285 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
280 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other); 286 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other);
281 return eee.fStroke == fStroke; 287 return eee.fStroke == fStroke;
282 } 288 }
283 289
284 bool fStroke; 290 bool fStroke;
285 291
286 GR_DECLARE_EFFECT_TEST; 292 GR_DECLARE_EFFECT_TEST;
287 293
288 typedef GrVertexEffect INHERITED; 294 typedef GrGeometryProcessor INHERITED;
289 }; 295 };
290 296
291 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); 297 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect);
292 298
293 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, 299 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random,
294 GrContext* context, 300 GrContext* context,
295 const GrDrawTargetCaps&, 301 const GrDrawTargetCaps&,
296 GrTexture* textures[]) { 302 GrTexture* textures[]) {
297 return EllipseEdgeEffect::Create(random->nextBool()); 303 return EllipseEdgeEffect::Create(random->nextBool());
298 } 304 }
299 305
300 /////////////////////////////////////////////////////////////////////////////// 306 ///////////////////////////////////////////////////////////////////////////////
301 307
302 /** 308 /**
303 * The output of this effect is a modulation of the input color and coverage for an ellipse, 309 * 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 310 * 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 311 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c orrected by
306 * using differentials. 312 * using differentials.
307 * 313 *
308 * The result is device-independent and can be used with any affine matrix. 314 * The result is device-independent and can be used with any affine matrix.
309 */ 315 */
310 316
311 class DIEllipseEdgeEffect : public GrVertexEffect { 317 const GrShaderVar kAttrEllipseOffsets0("aEllipseOffsets0",
318 kVec2f_GrSLType,
319 GrShaderVar::kAttribute_TypeModifier);
320
321 const GrShaderVar kAttrEllipseOffsets1("aEllipseOffsets1",
322 kVec2f_GrSLType,
323 GrShaderVar::kAttribute_TypeModifier);
324
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 15 matching lines...) Expand all
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
345 inline Mode getMode() const { return fMode; } 359 inline Mode getMode() const { return fMode; }
346 360
347 class GLEffect : public GrGLVertexEffect { 361 class GLEffect : public GrGLGeometryProcessor {
348 public: 362 public:
349 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 363 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
350 : INHERITED (factory) {} 364 : INHERITED (factory) {}
351 365
352 virtual void emitCode(GrGLFullProgramBuilder* builder, 366 virtual void emitCode(GrGLFullProgramBuilder* builder,
353 const GrDrawEffect& drawEffect, 367 const GrDrawEffect& drawEffect,
354 const GrEffectKey& key, 368 const GrEffectKey& key,
355 const char* outputColor, 369 const char* outputColor,
356 const char* inputColor, 370 const char* inputColor,
357 const TransformedCoordsArray&, 371 const TransformedCoordsArray&,
358 const TextureSamplerArray& samplers) SK_OVERRIDE { 372 const TextureSamplerArray& samplers) SK_OVERRIDE {
359 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE llipseEdgeEffect>(); 373 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE llipseEdgeEffect>();
360 374
361 const char *vsOffsetName0, *fsOffsetName0; 375 const char *vsOffsetName0, *fsOffsetName0;
362 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", 376 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
363 &vsOffsetName0, &fsOffsetName0); 377 &vsOffsetName0, &fsOffsetName0);
364 378
365 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder (); 379 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder ();
366 const SkString* attr0Name = 380 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName0, kAttrEllipseOf fsets0.c_str());
367 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[0]);
368 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_s tr());
369 const char *vsOffsetName1, *fsOffsetName1; 381 const char *vsOffsetName1, *fsOffsetName1;
370 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", 382 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
371 &vsOffsetName1, &fsOffsetName1); 383 &vsOffsetName1, &fsOffsetName1);
372 const SkString* attr1Name = 384 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, kAttrEllipseOf fsets1.c_str());
373 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[1]);
374 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_s tr());
375 385
376 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder(); 386 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder();
377 SkAssertResult(fsBuilder->enableFeature( 387 SkAssertResult(fsBuilder->enableFeature(
378 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature) ); 388 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature) );
379 // for outer curve 389 // for outer curve
380 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam e0); 390 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam e0);
381 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n"); 391 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n");
382 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); 392 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
383 fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); 393 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" 394 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 = 429 const DIEllipseEdgeEffect& ellipseEffect =
420 drawEffect.castEffect<DIEllipseEdgeEffect>(); 430 drawEffect.castEffect<DIEllipseEdgeEffect>();
421 431
422 b->add32(ellipseEffect.getMode()); 432 b->add32(ellipseEffect.getMode());
423 } 433 }
424 434
425 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE { 435 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {
426 } 436 }
427 437
428 private: 438 private:
429 typedef GrGLVertexEffect INHERITED; 439 typedef GrGLGeometryProcessor INHERITED;
430 }; 440 };
431 441
432 private: 442 private:
433 DIEllipseEdgeEffect(Mode mode) : GrVertexEffect() { 443 DIEllipseEdgeEffect(Mode mode) : GrGeometryProcessor() {
434 this->addVertexAttrib(kVec2f_GrSLType); 444 this->addVertexAttrib(kAttrEllipseOffsets0);
435 this->addVertexAttrib(kVec2f_GrSLType); 445 this->addVertexAttrib(kAttrEllipseOffsets1);
436 fMode = mode; 446 fMode = mode;
437 } 447 }
438 448
439 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 449 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
440 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other); 450 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other);
441 return eee.fMode == fMode; 451 return eee.fMode == fMode;
442 } 452 }
443 453
444 Mode fMode; 454 Mode fMode;
445 455
446 GR_DECLARE_EFFECT_TEST; 456 GR_DECLARE_EFFECT_TEST;
447 457
448 typedef GrVertexEffect INHERITED; 458 typedef GrGeometryProcessor INHERITED;
449 }; 459 };
450 460
451 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); 461 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect);
452 462
453 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, 463 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
454 GrContext* context, 464 GrContext* context,
455 const GrDrawTargetCaps&, 465 const GrDrawTargetCaps&,
456 GrTexture* textures[]) { 466 GrTexture* textures[]) {
457 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); 467 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2)));
458 } 468 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 halfWidth = SkScalarHalf(strokeWidth); 555 halfWidth = SkScalarHalf(strokeWidth);
546 } 556 }
547 557
548 outerRadius += halfWidth; 558 outerRadius += halfWidth;
549 if (isStrokeOnly) { 559 if (isStrokeOnly) {
550 innerRadius = radius - halfWidth; 560 innerRadius = radius - halfWidth;
551 } 561 }
552 } 562 }
553 563
554 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0) ; 564 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0) ;
555 static const int kCircleEdgeAttrIndex = 1; 565 drawState->setGeometryProcessor(effect)->unref();
556 drawState->setGeometryProcessor(effect, kCircleEdgeAttrIndex)->unref();
557 566
558 // The radii are outset for two reasons. First, it allows the shader to simp ly perform 567 // 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 568 // 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 569 // verts of the bounding box that is rendered and the outset ensures the box will cover all
561 // pixels partially covered by the circle. 570 // pixels partially covered by the circle.
562 outerRadius += SK_ScalarHalf; 571 outerRadius += SK_ScalarHalf;
563 innerRadius -= SK_ScalarHalf; 572 innerRadius -= SK_ScalarHalf;
564 573
565 SkRect bounds = SkRect::MakeLTRB( 574 SkRect bounds = SkRect::MakeLTRB(
566 center.fX - outerRadius, 575 center.fX - outerRadius,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 if (!geo.succeeded()) { 696 if (!geo.succeeded()) {
688 GrPrintf("Failed to get space for vertices!\n"); 697 GrPrintf("Failed to get space for vertices!\n");
689 return false; 698 return false;
690 } 699 }
691 700
692 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 701 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
693 702
694 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && 703 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly &&
695 innerXRadius > 0 && innerYRadiu s > 0); 704 innerXRadius > 0 && innerYRadiu s > 0);
696 705
697 static const int kEllipseCenterAttrIndex = 1; 706 drawState->setGeometryProcessor(effect)->unref();
698 static const int kEllipseEdgeAttrIndex = 2;
699 drawState->setGeometryProcessor(effect, kEllipseCenterAttrIndex, kEllipseEdg eAttrIndex)->unref();
700 707
701 // Compute the reciprocals of the radii here to save time in the shader 708 // Compute the reciprocals of the radii here to save time in the shader
702 SkScalar xRadRecip = SkScalarInvert(xRadius); 709 SkScalar xRadRecip = SkScalarInvert(xRadius);
703 SkScalar yRadRecip = SkScalarInvert(yRadius); 710 SkScalar yRadRecip = SkScalarInvert(yRadius);
704 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 711 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
705 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 712 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
706 713
707 // We've extended the outer x radius out half a pixel to antialias. 714 // 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. 715 // This will also expand the rect so all the pixels will be captured.
709 // TODO: Consider if we should use sqrt(2)/2 instead 716 // 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); 812 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
806 if (!geo.succeeded()) { 813 if (!geo.succeeded()) {
807 GrPrintf("Failed to get space for vertices!\n"); 814 GrPrintf("Failed to get space for vertices!\n");
808 return false; 815 return false;
809 } 816 }
810 817
811 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); 818 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
812 819
813 GrEffect* effect = DIEllipseEdgeEffect::Create(mode); 820 GrEffect* effect = DIEllipseEdgeEffect::Create(mode);
814 821
815 static const int kEllipseOuterOffsetAttrIndex = 1; 822 drawState->setGeometryProcessor(effect)->unref();
816 static const int kEllipseInnerOffsetAttrIndex = 2;
817 drawState->setGeometryProcessor(effect, kEllipseOuterOffsetAttrIndex,
818 kEllipseInnerOffsetAttrIndex)->unref();
819 823
820 // This expands the outer rect so that after CTM we end up with a half-pixel border 824 // This expands the outer rect so that after CTM we end up with a half-pixel border
821 SkScalar a = vm[SkMatrix::kMScaleX]; 825 SkScalar a = vm[SkMatrix::kMScaleX];
822 SkScalar b = vm[SkMatrix::kMSkewX]; 826 SkScalar b = vm[SkMatrix::kMSkewX];
823 SkScalar c = vm[SkMatrix::kMSkewY]; 827 SkScalar c = vm[SkMatrix::kMSkewY];
824 SkScalar d = vm[SkMatrix::kMScaleY]; 828 SkScalar d = vm[SkMatrix::kMScaleY];
825 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); 829 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
826 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); 830 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
827 // This adjusts the "radius" to include the half-pixel border 831 // This adjusts the "radius" to include the half-pixel border
828 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); 832 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 if (isStrokeOnly) { 1059 if (isStrokeOnly) {
1056 innerRadius = xRadius - halfWidth; 1060 innerRadius = xRadius - halfWidth;
1057 } 1061 }
1058 outerRadius += halfWidth; 1062 outerRadius += halfWidth;
1059 bounds.outset(halfWidth, halfWidth); 1063 bounds.outset(halfWidth, halfWidth);
1060 } 1064 }
1061 1065
1062 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 1066 isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
1063 1067
1064 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); 1068 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly);
1065 static const int kCircleEdgeAttrIndex = 1; 1069 drawState->setGeometryProcessor(effect)->unref();
1066 drawState->setGeometryProcessor(effect, kCircleEdgeAttrIndex)->unref();
1067 1070
1068 // The radii are outset for two reasons. First, it allows the shader to simply perform 1071 // 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 1072 // 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 1073 // verts of the bounding box that is rendered and the outset ensures the box will cover all
1071 // pixels partially covered by the circle. 1074 // pixels partially covered by the circle.
1072 outerRadius += SK_ScalarHalf; 1075 outerRadius += SK_ScalarHalf;
1073 innerRadius -= SK_ScalarHalf; 1076 innerRadius -= SK_ScalarHalf;
1074 1077
1075 // Expand the rect so all the pixels will be captured. 1078 // Expand the rect so all the pixels will be captured.
1076 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1079 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); 1162 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
1160 1163
1161 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); 1164 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
1162 if (!geo.succeeded()) { 1165 if (!geo.succeeded()) {
1163 GrPrintf("Failed to get space for vertices!\n"); 1166 GrPrintf("Failed to get space for vertices!\n");
1164 return false; 1167 return false;
1165 } 1168 }
1166 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 1169 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
1167 1170
1168 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); 1171 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly);
1169 static const int kEllipseOffsetAttrIndex = 1; 1172 drawState->setGeometryProcessor(effect)->unref();
1170 static const int kEllipseRadiiAttrIndex = 2;
1171 drawState->setGeometryProcessor(effect,
1172 kEllipseOffsetAttrIndex,
1173 kEllipseRadiiAttrIndex)->unref();
1174 1173
1175 // Compute the reciprocals of the radii here to save time in the shader 1174 // Compute the reciprocals of the radii here to save time in the shader
1176 SkScalar xRadRecip = SkScalarInvert(xRadius); 1175 SkScalar xRadRecip = SkScalarInvert(xRadius);
1177 SkScalar yRadRecip = SkScalarInvert(yRadius); 1176 SkScalar yRadRecip = SkScalarInvert(yRadius);
1178 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 1177 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
1179 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 1178 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
1180 1179
1181 // Extend the radii out half a pixel to antialias. 1180 // Extend the radii out half a pixel to antialias.
1182 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; 1181 SkScalar xOuterRadius = xRadius + SK_ScalarHalf;
1183 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; 1182 SkScalar yOuterRadius = yRadius + SK_ScalarHalf;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 1225
1227 // drop out the middle quad if we're stroked 1226 // drop out the middle quad if we're stroked
1228 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1227 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1229 SK_ARRAY_COUNT(gRRectIndices); 1228 SK_ARRAY_COUNT(gRRectIndices);
1230 target->setIndexSourceToBuffer(indexBuffer); 1229 target->setIndexSourceToBuffer(indexBuffer);
1231 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); 1230 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds);
1232 } 1231 }
1233 1232
1234 return true; 1233 return true;
1235 } 1234 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698