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

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: warning fixed 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
« no previous file with comments | « src/gpu/GrDrawState.h ('k') | src/gpu/GrRODrawState.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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& inCircleEdge() const { return fInCircleEdge; }
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.inCircle Edge().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 : fInCircleEdge(this->addVertexAttrib(
142 GrShaderVar("inCircleEdge",
143 kVec4f_GrSLType,
144 GrShaderVar::kAttribute_TypeModifier))) {
142 fStroke = stroke; 145 fStroke = stroke;
143 } 146 }
144 147
145 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 148 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
146 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other); 149 const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other);
147 return cee.fStroke == fStroke; 150 return cee.fStroke == fStroke;
148 } 151 }
149 152
153 const GrShaderVar& fInCircleEdge;
150 bool fStroke; 154 bool fStroke;
151 155
152 GR_DECLARE_EFFECT_TEST; 156 GR_DECLARE_EFFECT_TEST;
153 157
154 typedef GrVertexEffect INHERITED; 158 typedef GrGeometryProcessor INHERITED;
155 }; 159 };
156 160
157 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); 161 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect);
158 162
159 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, 163 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random,
160 GrContext* context, 164 GrContext* context,
161 const GrDrawTargetCaps&, 165 const GrDrawTargetCaps&,
162 GrTexture* textures[]) { 166 GrTexture* textures[]) {
163 return CircleEdgeEffect::Create(random->nextBool()); 167 return CircleEdgeEffect::Create(random->nextBool());
164 } 168 }
165 169
166 /////////////////////////////////////////////////////////////////////////////// 170 ///////////////////////////////////////////////////////////////////////////////
167 171
168 /** 172 /**
169 * The output of this effect is a modulation of the input color and coverage for an axis-aligned 173 * 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, 174 * 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. 175 * in both x and y directions.
172 * 176 *
173 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. 177 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0.
174 */ 178 */
175 179
176 class EllipseEdgeEffect : public GrVertexEffect { 180 class EllipseEdgeEffect : public GrGeometryProcessor {
177 public: 181 public:
178 static GrEffect* Create(bool stroke) { 182 static GrEffect* Create(bool stroke) {
179 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); 183 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true));
180 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); 184 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false));
181 185
182 if (stroke) { 186 if (stroke) {
183 gEllipseStrokeEdge->ref(); 187 gEllipseStrokeEdge->ref();
184 return gEllipseStrokeEdge; 188 return gEllipseStrokeEdge;
185 } else { 189 } else {
186 gEllipseFillEdge->ref(); 190 gEllipseFillEdge->ref();
187 return gEllipseFillEdge; 191 return gEllipseFillEdge;
188 } 192 }
189 } 193 }
190 194
191 virtual void getConstantColorComponents(GrColor* color, 195 virtual void getConstantColorComponents(GrColor* color,
192 uint32_t* validFlags) const SK_OVERR IDE { 196 uint32_t* validFlags) const SK_OVERR IDE {
193 *validFlags = 0; 197 *validFlags = 0;
194 } 198 }
195 199
196 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 200 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
197 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); 201 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance();
198 } 202 }
199 203
200 virtual ~EllipseEdgeEffect() {} 204 virtual ~EllipseEdgeEffect() {}
201 205
202 static const char* Name() { return "EllipseEdge"; } 206 static const char* Name() { return "EllipseEdge"; }
203 207
208 const GrShaderVar& inEllipseOffset() const { return fInEllipseOffset; }
209 const GrShaderVar& inEllipseRadii() const { return fInEllipseRadii; }
210
204 inline bool isStroked() const { return fStroke; } 211 inline bool isStroked() const { return fStroke; }
205 212
206 class GLEffect : public GrGLVertexEffect { 213 class GLEffect : public GrGLGeometryProcessor {
207 public: 214 public:
208 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 215 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
209 : INHERITED (factory) {} 216 : INHERITED (factory) {}
210 217
211 virtual void emitCode(GrGLFullProgramBuilder* builder, 218 virtual void emitCode(GrGLFullProgramBuilder* builder,
212 const GrDrawEffect& drawEffect, 219 const GrDrawEffect& drawEffect,
213 const GrEffectKey& key, 220 const GrEffectKey& key,
214 const char* outputColor, 221 const char* outputColor,
215 const char* inputColor, 222 const char* inputColor,
216 const TransformedCoordsArray&, 223 const TransformedCoordsArray&,
217 const TextureSamplerArray& samplers) SK_OVERRIDE { 224 const TextureSamplerArray& samplers) SK_OVERRIDE {
218 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); 225 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
219 226
220 const char *vsOffsetName, *fsOffsetName; 227 const char *vsOffsetName, *fsOffsetName;
221 const char *vsRadiiName, *fsRadiiName; 228 const char *vsRadiiName, *fsRadiiName;
222 229
223 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName , &fsOffsetName); 230 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName , &fsOffsetName);
224 231
225 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder (); 232 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder ();
226 const SkString* attr0Name = 233 vsBuilder->codeAppendf("%s = %s;", vsOffsetName,
227 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[0]); 234 ellipseEffect.inEllipseOffset().c_str());
228 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_st r());
229 235
230 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName); 236 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName);
231 const SkString* attr1Name = 237 vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inElli pseRadii().c_str());
232 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[1]);
233 vsBuilder->codeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str ());
234 238
235 // for outer curve 239 // for outer curve
236 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder(); 240 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder();
237 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset Name, fsRadiiName); 241 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset Name, fsRadiiName);
238 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n"); 242 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n");
239 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs RadiiName); 243 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs RadiiName);
240 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); 244 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
241 // avoid calling inversesqrt on zero. 245 // avoid calling inversesqrt on zero.
242 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); 246 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
243 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); 247 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
(...skipping 15 matching lines...) Expand all
259 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, 263 static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
260 GrEffectKeyBuilder* b) { 264 GrEffectKeyBuilder* b) {
261 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>(); 265 const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<Ellip seEdgeEffect>();
262 b->add32(ellipseEffect.isStroked()); 266 b->add32(ellipseEffect.isStroked());
263 } 267 }
264 268
265 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE { 269 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {
266 } 270 }
267 271
268 private: 272 private:
269 typedef GrGLVertexEffect INHERITED; 273 typedef GrGLGeometryProcessor INHERITED;
270 }; 274 };
271 275
272 private: 276 private:
273 EllipseEdgeEffect(bool stroke) : GrVertexEffect() { 277 EllipseEdgeEffect(bool stroke)
274 this->addVertexAttrib(kVec2f_GrSLType); 278 : fInEllipseOffset(this->addVertexAttrib(
275 this->addVertexAttrib(kVec4f_GrSLType); 279 GrShaderVar("inEllipseOffset",
280 kVec2f_GrSLType,
281 GrShaderVar::kAttribute_TypeModifier)))
282 , fInEllipseRadii(this->addVertexAttrib(
283 GrShaderVar("inEllipseRadii",
284 kVec4f_GrSLType,
285 GrShaderVar::kAttribute_TypeModifier))) {
276 fStroke = stroke; 286 fStroke = stroke;
277 } 287 }
278 288
279 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 289 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
280 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other); 290 const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other);
281 return eee.fStroke == fStroke; 291 return eee.fStroke == fStroke;
282 } 292 }
283 293
294 const GrShaderVar& fInEllipseOffset;
295 const GrShaderVar& fInEllipseRadii;
284 bool fStroke; 296 bool fStroke;
285 297
286 GR_DECLARE_EFFECT_TEST; 298 GR_DECLARE_EFFECT_TEST;
287 299
288 typedef GrVertexEffect INHERITED; 300 typedef GrGeometryProcessor INHERITED;
289 }; 301 };
290 302
291 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); 303 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect);
292 304
293 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, 305 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random,
294 GrContext* context, 306 GrContext* context,
295 const GrDrawTargetCaps&, 307 const GrDrawTargetCaps&,
296 GrTexture* textures[]) { 308 GrTexture* textures[]) {
297 return EllipseEdgeEffect::Create(random->nextBool()); 309 return EllipseEdgeEffect::Create(random->nextBool());
298 } 310 }
299 311
300 /////////////////////////////////////////////////////////////////////////////// 312 ///////////////////////////////////////////////////////////////////////////////
301 313
302 /** 314 /**
303 * The output of this effect is a modulation of the input color and coverage for an ellipse, 315 * 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 316 * 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 317 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c orrected by
306 * using differentials. 318 * using differentials.
307 * 319 *
308 * The result is device-independent and can be used with any affine matrix. 320 * The result is device-independent and can be used with any affine matrix.
309 */ 321 */
310 322
311 class DIEllipseEdgeEffect : public GrVertexEffect { 323 class DIEllipseEdgeEffect : public GrGeometryProcessor {
312 public: 324 public:
313 enum Mode { kStroke = 0, kHairline, kFill }; 325 enum Mode { kStroke = 0, kHairline, kFill };
314 326
315 static GrEffect* Create(Mode mode) { 327 static GrEffect* Create(Mode mode) {
316 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok e)); 328 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok e));
317 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai rline)); 329 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai rline));
318 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); 330 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill));
319 331
320 if (kStroke == mode) { 332 if (kStroke == mode) {
321 gEllipseStrokeEdge->ref(); 333 gEllipseStrokeEdge->ref();
(...skipping 13 matching lines...) Expand all
335 } 347 }
336 348
337 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 349 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
338 return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance(); 350 return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance();
339 } 351 }
340 352
341 virtual ~DIEllipseEdgeEffect() {} 353 virtual ~DIEllipseEdgeEffect() {}
342 354
343 static const char* Name() { return "DIEllipseEdge"; } 355 static const char* Name() { return "DIEllipseEdge"; }
344 356
357 const GrShaderVar& inEllipseOffsets0() const { return fInEllipseOffsets0; }
358 const GrShaderVar& inEllipseOffsets1() const { return fInEllipseOffsets1; }
359
345 inline Mode getMode() const { return fMode; } 360 inline Mode getMode() const { return fMode; }
346 361
347 class GLEffect : public GrGLVertexEffect { 362 class GLEffect : public GrGLGeometryProcessor {
348 public: 363 public:
349 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 364 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
350 : INHERITED (factory) {} 365 : INHERITED (factory) {}
351 366
352 virtual void emitCode(GrGLFullProgramBuilder* builder, 367 virtual void emitCode(GrGLFullProgramBuilder* builder,
353 const GrDrawEffect& drawEffect, 368 const GrDrawEffect& drawEffect,
354 const GrEffectKey& key, 369 const GrEffectKey& key,
355 const char* outputColor, 370 const char* outputColor,
356 const char* inputColor, 371 const char* inputColor,
357 const TransformedCoordsArray&, 372 const TransformedCoordsArray&,
358 const TextureSamplerArray& samplers) SK_OVERRIDE { 373 const TextureSamplerArray& samplers) SK_OVERRIDE {
359 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE llipseEdgeEffect>(); 374 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE llipseEdgeEffect>();
360 375
361 const char *vsOffsetName0, *fsOffsetName0; 376 const char *vsOffsetName0, *fsOffsetName0;
362 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", 377 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
363 &vsOffsetName0, &fsOffsetName0); 378 &vsOffsetName0, &fsOffsetName0);
364 379
365 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder (); 380 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder ();
366 const SkString* attr0Name = 381 vsBuilder->codeAppendf("%s = %s;", vsOffsetName0,
367 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[0]); 382 ellipseEffect.inEllipseOffsets0().c_str());
368 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_s tr());
369 const char *vsOffsetName1, *fsOffsetName1; 383 const char *vsOffsetName1, *fsOffsetName1;
370 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", 384 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
371 &vsOffsetName1, &fsOffsetName1); 385 &vsOffsetName1, &fsOffsetName1);
372 const SkString* attr1Name = 386 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1,
373 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndi ces()[1]); 387 ellipseEffect.inEllipseOffsets1().c_str());
374 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_s tr());
375 388
376 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder(); 389 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui lder();
377 SkAssertResult(fsBuilder->enableFeature( 390 SkAssertResult(fsBuilder->enableFeature(
378 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature) ); 391 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature) );
379 // for outer curve 392 // for outer curve
380 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam e0); 393 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam e0);
381 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n"); 394 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset ) - 1.0;\n");
382 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); 395 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
383 fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); 396 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" 397 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 = 432 const DIEllipseEdgeEffect& ellipseEffect =
420 drawEffect.castEffect<DIEllipseEdgeEffect>(); 433 drawEffect.castEffect<DIEllipseEdgeEffect>();
421 434
422 b->add32(ellipseEffect.getMode()); 435 b->add32(ellipseEffect.getMode());
423 } 436 }
424 437
425 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE { 438 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {
426 } 439 }
427 440
428 private: 441 private:
429 typedef GrGLVertexEffect INHERITED; 442 typedef GrGLGeometryProcessor INHERITED;
430 }; 443 };
431 444
432 private: 445 private:
433 DIEllipseEdgeEffect(Mode mode) : GrVertexEffect() { 446 DIEllipseEdgeEffect(Mode mode)
434 this->addVertexAttrib(kVec2f_GrSLType); 447 : fInEllipseOffsets0(this->addVertexAttrib(
435 this->addVertexAttrib(kVec2f_GrSLType); 448 GrShaderVar("inEllipseOffsets0",
449 kVec2f_GrSLType,
450 GrShaderVar::kAttribute_TypeModifier)))
451 , fInEllipseOffsets1(this->addVertexAttrib(
452 GrShaderVar("inEllipseOffsets1",
453 kVec2f_GrSLType,
454 GrShaderVar::kAttribute_TypeModifier))) {
436 fMode = mode; 455 fMode = mode;
437 } 456 }
438 457
439 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 458 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
440 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other); 459 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other);
441 return eee.fMode == fMode; 460 return eee.fMode == fMode;
442 } 461 }
443 462
463 const GrShaderVar& fInEllipseOffsets0;
464 const GrShaderVar& fInEllipseOffsets1;
444 Mode fMode; 465 Mode fMode;
445 466
446 GR_DECLARE_EFFECT_TEST; 467 GR_DECLARE_EFFECT_TEST;
447 468
448 typedef GrVertexEffect INHERITED; 469 typedef GrGeometryProcessor INHERITED;
449 }; 470 };
450 471
451 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); 472 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect);
452 473
453 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, 474 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
454 GrContext* context, 475 GrContext* context,
455 const GrDrawTargetCaps&, 476 const GrDrawTargetCaps&,
456 GrTexture* textures[]) { 477 GrTexture* textures[]) {
457 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); 478 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2)));
458 } 479 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 halfWidth = SkScalarHalf(strokeWidth); 566 halfWidth = SkScalarHalf(strokeWidth);
546 } 567 }
547 568
548 outerRadius += halfWidth; 569 outerRadius += halfWidth;
549 if (isStrokeOnly) { 570 if (isStrokeOnly) {
550 innerRadius = radius - halfWidth; 571 innerRadius = radius - halfWidth;
551 } 572 }
552 } 573 }
553 574
554 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0) ; 575 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0) ;
555 static const int kCircleEdgeAttrIndex = 1; 576 drawState->setGeometryProcessor(effect)->unref();
556 drawState->setGeometryProcessor(effect, kCircleEdgeAttrIndex)->unref();
557 577
558 // The radii are outset for two reasons. First, it allows the shader to simp ly perform 578 // 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 579 // 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 580 // verts of the bounding box that is rendered and the outset ensures the box will cover all
561 // pixels partially covered by the circle. 581 // pixels partially covered by the circle.
562 outerRadius += SK_ScalarHalf; 582 outerRadius += SK_ScalarHalf;
563 innerRadius -= SK_ScalarHalf; 583 innerRadius -= SK_ScalarHalf;
564 584
565 SkRect bounds = SkRect::MakeLTRB( 585 SkRect bounds = SkRect::MakeLTRB(
566 center.fX - outerRadius, 586 center.fX - outerRadius,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 if (!geo.succeeded()) { 707 if (!geo.succeeded()) {
688 GrPrintf("Failed to get space for vertices!\n"); 708 GrPrintf("Failed to get space for vertices!\n");
689 return false; 709 return false;
690 } 710 }
691 711
692 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 712 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
693 713
694 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && 714 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly &&
695 innerXRadius > 0 && innerYRadiu s > 0); 715 innerXRadius > 0 && innerYRadiu s > 0);
696 716
697 static const int kEllipseCenterAttrIndex = 1; 717 drawState->setGeometryProcessor(effect)->unref();
698 static const int kEllipseEdgeAttrIndex = 2;
699 drawState->setGeometryProcessor(effect, kEllipseCenterAttrIndex, kEllipseEdg eAttrIndex)->unref();
700 718
701 // Compute the reciprocals of the radii here to save time in the shader 719 // Compute the reciprocals of the radii here to save time in the shader
702 SkScalar xRadRecip = SkScalarInvert(xRadius); 720 SkScalar xRadRecip = SkScalarInvert(xRadius);
703 SkScalar yRadRecip = SkScalarInvert(yRadius); 721 SkScalar yRadRecip = SkScalarInvert(yRadius);
704 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 722 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
705 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 723 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
706 724
707 // We've extended the outer x radius out half a pixel to antialias. 725 // 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. 726 // This will also expand the rect so all the pixels will be captured.
709 // TODO: Consider if we should use sqrt(2)/2 instead 727 // 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); 823 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
806 if (!geo.succeeded()) { 824 if (!geo.succeeded()) {
807 GrPrintf("Failed to get space for vertices!\n"); 825 GrPrintf("Failed to get space for vertices!\n");
808 return false; 826 return false;
809 } 827 }
810 828
811 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); 829 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
812 830
813 GrEffect* effect = DIEllipseEdgeEffect::Create(mode); 831 GrEffect* effect = DIEllipseEdgeEffect::Create(mode);
814 832
815 static const int kEllipseOuterOffsetAttrIndex = 1; 833 drawState->setGeometryProcessor(effect)->unref();
816 static const int kEllipseInnerOffsetAttrIndex = 2;
817 drawState->setGeometryProcessor(effect, kEllipseOuterOffsetAttrIndex,
818 kEllipseInnerOffsetAttrIndex)->unref();
819 834
820 // This expands the outer rect so that after CTM we end up with a half-pixel border 835 // This expands the outer rect so that after CTM we end up with a half-pixel border
821 SkScalar a = vm[SkMatrix::kMScaleX]; 836 SkScalar a = vm[SkMatrix::kMScaleX];
822 SkScalar b = vm[SkMatrix::kMSkewX]; 837 SkScalar b = vm[SkMatrix::kMSkewX];
823 SkScalar c = vm[SkMatrix::kMSkewY]; 838 SkScalar c = vm[SkMatrix::kMSkewY];
824 SkScalar d = vm[SkMatrix::kMScaleY]; 839 SkScalar d = vm[SkMatrix::kMScaleY];
825 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); 840 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
826 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); 841 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
827 // This adjusts the "radius" to include the half-pixel border 842 // This adjusts the "radius" to include the half-pixel border
828 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); 843 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 if (isStrokeOnly) { 1070 if (isStrokeOnly) {
1056 innerRadius = xRadius - halfWidth; 1071 innerRadius = xRadius - halfWidth;
1057 } 1072 }
1058 outerRadius += halfWidth; 1073 outerRadius += halfWidth;
1059 bounds.outset(halfWidth, halfWidth); 1074 bounds.outset(halfWidth, halfWidth);
1060 } 1075 }
1061 1076
1062 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 1077 isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
1063 1078
1064 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); 1079 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly);
1065 static const int kCircleEdgeAttrIndex = 1; 1080 drawState->setGeometryProcessor(effect)->unref();
1066 drawState->setGeometryProcessor(effect, kCircleEdgeAttrIndex)->unref();
1067 1081
1068 // The radii are outset for two reasons. First, it allows the shader to simply perform 1082 // 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 1083 // 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 1084 // verts of the bounding box that is rendered and the outset ensures the box will cover all
1071 // pixels partially covered by the circle. 1085 // pixels partially covered by the circle.
1072 outerRadius += SK_ScalarHalf; 1086 outerRadius += SK_ScalarHalf;
1073 innerRadius -= SK_ScalarHalf; 1087 innerRadius -= SK_ScalarHalf;
1074 1088
1075 // Expand the rect so all the pixels will be captured. 1089 // Expand the rect so all the pixels will be captured.
1076 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1090 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); 1173 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
1160 1174
1161 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); 1175 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
1162 if (!geo.succeeded()) { 1176 if (!geo.succeeded()) {
1163 GrPrintf("Failed to get space for vertices!\n"); 1177 GrPrintf("Failed to get space for vertices!\n");
1164 return false; 1178 return false;
1165 } 1179 }
1166 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 1180 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
1167 1181
1168 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); 1182 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly);
1169 static const int kEllipseOffsetAttrIndex = 1; 1183 drawState->setGeometryProcessor(effect)->unref();
1170 static const int kEllipseRadiiAttrIndex = 2;
1171 drawState->setGeometryProcessor(effect,
1172 kEllipseOffsetAttrIndex,
1173 kEllipseRadiiAttrIndex)->unref();
1174 1184
1175 // Compute the reciprocals of the radii here to save time in the shader 1185 // Compute the reciprocals of the radii here to save time in the shader
1176 SkScalar xRadRecip = SkScalarInvert(xRadius); 1186 SkScalar xRadRecip = SkScalarInvert(xRadius);
1177 SkScalar yRadRecip = SkScalarInvert(yRadius); 1187 SkScalar yRadRecip = SkScalarInvert(yRadius);
1178 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 1188 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
1179 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 1189 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
1180 1190
1181 // Extend the radii out half a pixel to antialias. 1191 // Extend the radii out half a pixel to antialias.
1182 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; 1192 SkScalar xOuterRadius = xRadius + SK_ScalarHalf;
1183 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; 1193 SkScalar yOuterRadius = yRadius + SK_ScalarHalf;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 1236
1227 // drop out the middle quad if we're stroked 1237 // drop out the middle quad if we're stroked
1228 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1238 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1229 SK_ARRAY_COUNT(gRRectIndices); 1239 SK_ARRAY_COUNT(gRRectIndices);
1230 target->setIndexSourceToBuffer(indexBuffer); 1240 target->setIndexSourceToBuffer(indexBuffer);
1231 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); 1241 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds);
1232 } 1242 }
1233 1243
1234 return true; 1244 return true;
1235 } 1245 }
OLDNEW
« no previous file with comments | « src/gpu/GrDrawState.h ('k') | src/gpu/GrRODrawState.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698