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

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

Issue 761563002: First step to moving vertex attributes to the geometryProcessor (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: more cleanup Created 6 years 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 "GrOvalRenderer.h" 8 #include "GrOvalRenderer.h"
9 9
10 #include "gl/builders/GrGLProgramBuilder.h" 10 #include "gl/builders/GrGLProgramBuilder.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 if (stroke) { 70 if (stroke) {
71 gCircleStrokeEdge->ref(); 71 gCircleStrokeEdge->ref();
72 return gCircleStrokeEdge; 72 return gCircleStrokeEdge;
73 } else { 73 } else {
74 gCircleFillEdge->ref(); 74 gCircleFillEdge->ref();
75 return gCircleFillEdge; 75 return gCircleFillEdge;
76 } 76 }
77 } 77 }
78 78
79 const GrShaderVar& inCircleEdge() const { return fInCircleEdge; } 79 const GrAttribute* inPosition() const { return fInPosition; }
80 const GrAttribute* inCircleEdge() const { return fInCircleEdge; }
80 81
81 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR IDE { 82 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR IDE {
82 return GrTBackendGeometryProcessorFactory<CircleEdgeEffect>::getInstance (); 83 return GrTBackendGeometryProcessorFactory<CircleEdgeEffect>::getInstance ();
83 } 84 }
84 85
85 virtual ~CircleEdgeEffect() {} 86 virtual ~CircleEdgeEffect() {}
86 87
87 static const char* Name() { return "CircleEdge"; } 88 static const char* Name() { return "CircleEdge"; }
88 89
89 inline bool isStroked() const { return fStroke; } 90 inline bool isStroked() const { return fStroke; }
90 91
91 class GLProcessor : public GrGLGeometryProcessor { 92 class GLProcessor : public GrGLGeometryProcessor {
92 public: 93 public:
93 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor& ) 94 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor& )
94 : INHERITED (factory) {} 95 : INHERITED (factory) {}
95 96
96 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { 97 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
97 const CircleEdgeEffect& circleEffect = args.fGP.cast<CircleEdgeEffec t>(); 98 const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>();
99 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
100
98 GrGLVertToFrag v(kVec4f_GrSLType); 101 GrGLVertToFrag v(kVec4f_GrSLType);
99 args.fPB->addVarying("CircleEdge", &v); 102 args.fPB->addVarying("CircleEdge", &v);
103 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fNa me);
100 104
101 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();; 105 // setup coord outputs
102 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleE dge().c_str()); 106 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ce.i nPosition()->fName);
107 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ce.inPo sition()->fName);
jvanverth1 2014/12/01 16:00:03 Do we need localCoords here? It doesn't look like
103 108
104 // setup position varying 109 // setup position varying
105 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPositi on(), 110 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPositi on(),
106 vsBuilder->uViewM(), vsBuilder->inPosition()) ; 111 vsBuilder->uViewM(), ce.inPosition()->fName);
107 112
108 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde r(); 113 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde r();
109 fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn()); 114 fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
110 fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0); ", v.fsIn()); 115 fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0); ", v.fsIn());
111 if (circleEffect.isStroked()) { 116 if (ce.isStroked()) {
112 fsBuilder->codeAppendf("float innerAlpha = clamp(d - %s.w, 0.0, 1.0);", 117 fsBuilder->codeAppendf("float innerAlpha = clamp(d - %s.w, 0.0, 1.0);",
113 v.fsIn()); 118 v.fsIn());
114 fsBuilder->codeAppend("edgeAlpha *= innerAlpha;"); 119 fsBuilder->codeAppend("edgeAlpha *= innerAlpha;");
115 } 120 }
116 121
117 fsBuilder->codeAppendf("%s = %s;\n", args.fOutput, 122 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage );
118 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edge Alpha")).c_str());
119 } 123 }
120 124
121 static void GenKey(const GrProcessor& processor, const GrGLCaps&, 125 static void GenKey(const GrProcessor& processor, const GrGLCaps&,
122 GrProcessorKeyBuilder* b) { 126 GrProcessorKeyBuilder* b) {
123 const CircleEdgeEffect& circleEffect = processor.cast<CircleEdgeEffe ct>(); 127 const CircleEdgeEffect& circleEffect = processor.cast<CircleEdgeEffe ct>();
124 b->add32(circleEffect.isStroked()); 128 b->add32(circleEffect.isStroked());
125 } 129 }
126 130
127 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} 131 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
128 132
129 private: 133 private:
130 typedef GrGLGeometryProcessor INHERITED; 134 typedef GrGLGeometryProcessor INHERITED;
131 }; 135 };
132 136
133 137
134 private: 138 private:
135 CircleEdgeEffect(bool stroke) 139 CircleEdgeEffect(bool stroke) {
136 : fInCircleEdge(this->addVertexAttrib( 140 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType));
137 GrShaderVar("inCircleEdge", 141 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge",
138 kVec4f_GrSLType, 142 kVec4f_GrVertexAttrib Type));
139 GrShaderVar::kAttribute_TypeModifier))) {
140 fStroke = stroke; 143 fStroke = stroke;
141 } 144 }
142 145
143 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { 146 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
144 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); 147 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>();
145 return cee.fStroke == fStroke; 148 return cee.fStroke == fStroke;
146 } 149 }
147 150
148 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE { 151 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE {
149 inout->mulByUnknownAlpha(); 152 inout->mulByUnknownAlpha();
150 } 153 }
151 154
152 const GrShaderVar& fInCircleEdge; 155 const GrAttribute* fInPosition;
156 const GrAttribute* fInCircleEdge;
153 bool fStroke; 157 bool fStroke;
154 158
155 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 159 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
156 160
157 typedef GrGeometryProcessor INHERITED; 161 typedef GrGeometryProcessor INHERITED;
158 }; 162 };
159 163
160 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); 164 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect);
161 165
162 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, 166 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random,
(...skipping 29 matching lines...) Expand all
192 } 196 }
193 197
194 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR IDE { 198 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR IDE {
195 return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstanc e(); 199 return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstanc e();
196 } 200 }
197 201
198 virtual ~EllipseEdgeEffect() {} 202 virtual ~EllipseEdgeEffect() {}
199 203
200 static const char* Name() { return "EllipseEdge"; } 204 static const char* Name() { return "EllipseEdge"; }
201 205
202 const GrShaderVar& inEllipseOffset() const { return fInEllipseOffset; } 206
203 const GrShaderVar& inEllipseRadii() const { return fInEllipseRadii; } 207 const GrAttribute* inPosition() const { return fInPosition; }
208 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; }
209 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; }
204 210
205 inline bool isStroked() const { return fStroke; } 211 inline bool isStroked() const { return fStroke; }
206 212
207 class GLProcessor : public GrGLGeometryProcessor { 213 class GLProcessor : public GrGLGeometryProcessor {
208 public: 214 public:
209 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor& ) 215 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor& )
210 : INHERITED (factory) {} 216 : INHERITED (factory) {}
211 217
212 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { 218 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
213 const EllipseEdgeEffect& ellipseEffect = args.fGP.cast<EllipseEdgeEf fect>(); 219 const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>();
220
221 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
214 222
215 GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType); 223 GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType);
216 args.fPB->addVarying("EllipseOffsets", &ellipseOffsets); 224 args.fPB->addVarying("EllipseOffsets", &ellipseOffsets);
217
218 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
219 vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), 225 vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
220 ellipseEffect.inEllipseOffset().c_str()); 226 ee.inEllipseOffset()->fName);
221 227
222 GrGLVertToFrag ellipseRadii(kVec4f_GrSLType); 228 GrGLVertToFrag ellipseRadii(kVec4f_GrSLType);
223 args.fPB->addVarying("EllipseRadii", &ellipseRadii); 229 args.fPB->addVarying("EllipseRadii", &ellipseRadii);
224 vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), 230 vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
225 ellipseEffect.inEllipseRadii().c_str()); 231 ee.inEllipseRadii()->fName);
232
233 // setup coord outputs
234 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.i nPosition()->fName);
235 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPo sition()->fName);
jvanverth1 2014/12/01 16:00:03 Same here about localCoords.
226 236
227 // setup position varying 237 // setup position varying
228 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPositi on(), 238 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPositi on(),
229 vsBuilder->uViewM(), vsBuilder->inPosition()) ; 239 vsBuilder->uViewM(), ee.inPosition()->fName);
230 240
231 // for outer curve 241 // for outer curve
232 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde r(); 242 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde r();
233 fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffse ts.fsIn(), 243 fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffse ts.fsIn(),
234 ellipseRadii.fsIn()); 244 ellipseRadii.fsIn());
235 fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;"); 245 fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
236 fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellips eRadii.fsIn()); 246 fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellips eRadii.fsIn());
237 fsBuilder->codeAppend("float grad_dot = dot(grad, grad);"); 247 fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
238 248
239 // avoid calling inversesqrt on zero. 249 // avoid calling inversesqrt on zero.
240 fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); 250 fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
241 fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); 251 fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
242 fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); 252 fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
243 253
244 // for inner curve 254 // for inner curve
245 if (ellipseEffect.isStroked()) { 255 if (ee.isStroked()) {
246 fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;", 256 fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
247 ellipseOffsets.fsIn(), ellipseRadii.fsIn( )); 257 ellipseOffsets.fsIn(), ellipseRadii.fsIn( ));
248 fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); 258 fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
249 fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;", 259 fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
250 ellipseRadii.fsIn()); 260 ellipseRadii.fsIn());
251 fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); 261 fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
252 fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); 262 fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
253 } 263 }
254 264
255 fsBuilder->codeAppendf("%s = %s;", args.fOutput, 265 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage );
256 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edge Alpha")).c_str());
257 } 266 }
258 267
259 static void GenKey(const GrProcessor& processor, const GrGLCaps&, 268 static void GenKey(const GrProcessor& processor, const GrGLCaps&,
260 GrProcessorKeyBuilder* b) { 269 GrProcessorKeyBuilder* b) {
261 const EllipseEdgeEffect& ellipseEffect = processor.cast<EllipseEdgeE ffect>(); 270 const EllipseEdgeEffect& ellipseEffect = processor.cast<EllipseEdgeE ffect>();
262 b->add32(ellipseEffect.isStroked()); 271 b->add32(ellipseEffect.isStroked());
263 } 272 }
264 273
265 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE { 274 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {
266 } 275 }
267 276
268 private: 277 private:
269 typedef GrGLGeometryProcessor INHERITED; 278 typedef GrGLGeometryProcessor INHERITED;
270 }; 279 };
271 280
272 private: 281 private:
273 EllipseEdgeEffect(bool stroke) 282 EllipseEdgeEffect(bool stroke) {
274 : fInEllipseOffset(this->addVertexAttrib( 283 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType));
275 GrShaderVar("inEllipseOffset", 284 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset",
276 kVec2f_GrSLType, 285 kVec2f_GrVertexAtt ribType));
277 GrShaderVar::kAttribute_TypeModifier))) 286 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii",
278 , fInEllipseRadii(this->addVertexAttrib( 287 kVec4f_GrVertexAttr ibType));
279 GrShaderVar("inEllipseRadii",
280 kVec4f_GrSLType,
281 GrShaderVar::kAttribute_TypeModifier))) {
282 fStroke = stroke; 288 fStroke = stroke;
283 } 289 }
284 290
285 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { 291 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
286 const EllipseEdgeEffect& eee = other.cast<EllipseEdgeEffect>(); 292 const EllipseEdgeEffect& eee = other.cast<EllipseEdgeEffect>();
287 return eee.fStroke == fStroke; 293 return eee.fStroke == fStroke;
288 } 294 }
289 295
290 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE { 296 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE {
291 inout->mulByUnknownAlpha(); 297 inout->mulByUnknownAlpha();
292 } 298 }
293 299
294 const GrShaderVar& fInEllipseOffset; 300 const GrAttribute* fInPosition;
295 const GrShaderVar& fInEllipseRadii; 301 const GrAttribute* fInEllipseOffset;
302 const GrAttribute* fInEllipseRadii;
296 bool fStroke; 303 bool fStroke;
297 304
298 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 305 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
299 306
300 typedef GrGeometryProcessor INHERITED; 307 typedef GrGeometryProcessor INHERITED;
301 }; 308 };
302 309
303 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); 310 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect);
304 311
305 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, 312 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } 349 }
343 350
344 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR IDE { 351 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR IDE {
345 return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInsta nce(); 352 return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInsta nce();
346 } 353 }
347 354
348 virtual ~DIEllipseEdgeEffect() {} 355 virtual ~DIEllipseEdgeEffect() {}
349 356
350 static const char* Name() { return "DIEllipseEdge"; } 357 static const char* Name() { return "DIEllipseEdge"; }
351 358
352 const GrShaderVar& inEllipseOffsets0() const { return fInEllipseOffsets0; } 359 const GrAttribute* inPosition() const { return fInPosition; }
353 const GrShaderVar& inEllipseOffsets1() const { return fInEllipseOffsets1; } 360 const GrAttribute* inEllipseOffsets0() const { return fInEllipseOffsets0; }
361 const GrAttribute* inEllipseOffsets1() const { return fInEllipseOffsets1; }
354 362
355 inline Mode getMode() const { return fMode; } 363 inline Mode getMode() const { return fMode; }
356 364
357 class GLProcessor : public GrGLGeometryProcessor { 365 class GLProcessor : public GrGLGeometryProcessor {
358 public: 366 public:
359 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor& ) 367 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor& )
360 : INHERITED (factory) {} 368 : INHERITED (factory) {}
361 369
362 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { 370 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
363 const DIEllipseEdgeEffect& ellipseEffect = args.fGP.cast<DIEllipseEd geEffect>(); 371 const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>() ;
372
373 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
364 374
365 GrGLVertToFrag offsets0(kVec2f_GrSLType); 375 GrGLVertToFrag offsets0(kVec2f_GrSLType);
366 args.fPB->addVarying("EllipseOffsets0", &offsets0); 376 args.fPB->addVarying("EllipseOffsets0", &offsets0);
367
368 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
369 vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), 377 vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
370 ellipseEffect.inEllipseOffsets0().c_str()); 378 ee.inEllipseOffsets0()->fName);
371 379
372 GrGLVertToFrag offsets1(kVec2f_GrSLType); 380 GrGLVertToFrag offsets1(kVec2f_GrSLType);
373 args.fPB->addVarying("EllipseOffsets1", &offsets1); 381 args.fPB->addVarying("EllipseOffsets1", &offsets1);
374 vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), 382 vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
375 ellipseEffect.inEllipseOffsets1().c_str()); 383 ee.inEllipseOffsets1()->fName);
384
385 // setup coord outputs
386 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), ee.i nPosition()->fName);
387 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), ee.inPo sition()->fName);
jvanverth1 2014/12/01 16:00:03 Ditto.
376 388
377 // setup position varying 389 // setup position varying
378 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPositi on(), 390 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPositi on(),
379 vsBuilder->uViewM(), vsBuilder->inPosition()) ; 391 vsBuilder->uViewM(), ee.inPosition()->fName);
380 392
381 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde r(); 393 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilde r();
382 SkAssertResult(fsBuilder->enableFeature( 394 SkAssertResult(fsBuilder->enableFeature(
383 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature) ); 395 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature) );
384 // for outer curve 396 // for outer curve
385 fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn() ); 397 fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn() );
386 fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;"); 398 fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
387 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn()); 399 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
388 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn()); 400 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
389 fsBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y *duvdx.y," 401 fsBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y *duvdx.y,"
390 " 2.0*%s.x*duvdy.x + 2.0*%s.y *duvdy.y);", 402 " 2.0*%s.x*duvdy.x + 2.0*%s.y *duvdy.y);",
391 offsets0.fsIn(), offsets0.fsIn(), offsets0.fs In(), offsets0.fsIn()); 403 offsets0.fsIn(), offsets0.fsIn(), offsets0.fs In(), offsets0.fsIn());
392 404
393 fsBuilder->codeAppend("float grad_dot = dot(grad, grad);"); 405 fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
394 // avoid calling inversesqrt on zero. 406 // avoid calling inversesqrt on zero.
395 fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); 407 fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
396 fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); 408 fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
397 if (kHairline == ellipseEffect.getMode()) { 409 if (kHairline == ee.getMode()) {
398 // can probably do this with one step 410 // can probably do this with one step
399 fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);"); 411 fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
400 fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);"); 412 fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
401 } else { 413 } else {
402 fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); 414 fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
403 } 415 }
404 416
405 // for inner curve 417 // for inner curve
406 if (kStroke == ellipseEffect.getMode()) { 418 if (kStroke == ee.getMode()) {
407 fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn()) ; 419 fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn()) ;
408 fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); 420 fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
409 fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn()); 421 fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
410 fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn()); 422 fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
411 fsBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y* duvdx.y," 423 fsBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y* duvdx.y,"
412 " 2.0*%s.x*duvdy.x + 2.0*%s.y* duvdy.y);", 424 " 2.0*%s.x*duvdy.x + 2.0*%s.y* duvdy.y);",
413 offsets1.fsIn(), offsets1.fsIn(), offsets 1.fsIn(), 425 offsets1.fsIn(), offsets1.fsIn(), offsets 1.fsIn(),
414 offsets1.fsIn()); 426 offsets1.fsIn());
415 fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); 427 fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
416 fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); 428 fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
417 } 429 }
418 430
419 fsBuilder->codeAppendf("%s = %s;", args.fOutput, 431 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage );
420 (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edge Alpha")).c_str());
421 } 432 }
422 433
423 static void GenKey(const GrProcessor& processor, const GrGLCaps&, 434 static void GenKey(const GrProcessor& processor, const GrGLCaps&,
424 GrProcessorKeyBuilder* b) { 435 GrProcessorKeyBuilder* b) {
425 const DIEllipseEdgeEffect& ellipseEffect = processor.cast<DIEllipseE dgeEffect>(); 436 const DIEllipseEdgeEffect& ellipseEffect = processor.cast<DIEllipseE dgeEffect>();
426 437
427 b->add32(ellipseEffect.getMode()); 438 b->add32(ellipseEffect.getMode());
428 } 439 }
429 440
430 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE { 441 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {
431 } 442 }
432 443
433 private: 444 private:
434 typedef GrGLGeometryProcessor INHERITED; 445 typedef GrGLGeometryProcessor INHERITED;
435 }; 446 };
436 447
437 private: 448 private:
438 DIEllipseEdgeEffect(Mode mode) 449 DIEllipseEdgeEffect(Mode mode) {
439 : fInEllipseOffsets0(this->addVertexAttrib( 450 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr VertexAttribType));
440 GrShaderVar("inEllipseOffsets0", 451 fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffset s0",
441 kVec2f_GrSLType, 452 kVec2f_GrVertexA ttribType));
442 GrShaderVar::kAttribute_TypeModifier))) 453 fInEllipseOffsets1 = &this->addVertexAttrib(GrAttribute("inEllipseOffset s1",
443 , fInEllipseOffsets1(this->addVertexAttrib( 454 kVec2f_GrVertexA ttribType));
444 GrShaderVar("inEllipseOffsets1",
445 kVec2f_GrSLType,
446 GrShaderVar::kAttribute_TypeModifier))) {
447 fMode = mode; 455 fMode = mode;
448 } 456 }
449 457
450 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { 458 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
451 const DIEllipseEdgeEffect& eee = other.cast<DIEllipseEdgeEffect>(); 459 const DIEllipseEdgeEffect& eee = other.cast<DIEllipseEdgeEffect>();
452 return eee.fMode == fMode; 460 return eee.fMode == fMode;
453 } 461 }
454 462
455 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE { 463 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE {
456 inout->mulByUnknownAlpha(); 464 inout->mulByUnknownAlpha();
457 } 465 }
458 466
459 const GrShaderVar& fInEllipseOffsets0; 467 const GrAttribute* fInPosition;
460 const GrShaderVar& fInEllipseOffsets1; 468 const GrAttribute* fInEllipseOffsets0;
469 const GrAttribute* fInEllipseOffsets1;
461 Mode fMode; 470 Mode fMode;
462 471
463 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 472 GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
464 473
465 typedef GrGeometryProcessor INHERITED; 474 typedef GrGeometryProcessor INHERITED;
466 }; 475 };
467 476
468 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); 477 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect);
469 478
470 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, 479 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 return this->drawEllipse(target, drawState, context, useCoverageAA, oval , stroke); 519 return this->drawEllipse(target, drawState, context, useCoverageAA, oval , stroke);
511 } else { 520 } else {
512 return false; 521 return false;
513 } 522 }
514 523
515 return true; 524 return true;
516 } 525 }
517 526
518 /////////////////////////////////////////////////////////////////////////////// 527 ///////////////////////////////////////////////////////////////////////////////
519 528
520 // position + edge
521 extern const GrVertexAttrib gCircleVertexAttribs[] = {
522 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
523 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttr ibBinding}
524 };
525
526 void GrOvalRenderer::drawCircle(GrDrawTarget* target, 529 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
527 GrDrawState* drawState, 530 GrDrawState* drawState,
528 const GrContext* context, 531 const GrContext* context,
529 bool useCoverageAA, 532 bool useCoverageAA,
530 const SkRect& circle, 533 const SkRect& circle,
531 const SkStrokeRec& stroke) 534 const SkStrokeRec& stroke)
532 { 535 {
533 const SkMatrix& vm = drawState->getViewMatrix(); 536 const SkMatrix& vm = drawState->getViewMatrix();
534 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); 537 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY());
535 vm.mapPoints(&center, 1); 538 vm.mapPoints(&center, 1);
536 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); 539 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width()));
537 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); 540 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth());
538 541
539 GrDrawState::AutoViewMatrixRestore avmr; 542 GrDrawState::AutoViewMatrixRestore avmr;
540 if (!avmr.setIdentity(drawState)) { 543 if (!avmr.setIdentity(drawState)) {
541 return; 544 return;
542 } 545 }
543 546
544 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVert exAttribs),
545 sizeof(CircleVertex));
546
547 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride( ), 0);
548 if (!geo.succeeded()) {
549 SkDebugf("Failed to get space for vertices!\n");
550 return;
551 }
552
553 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
554
555 SkStrokeRec::Style style = stroke.getStyle(); 547 SkStrokeRec::Style style = stroke.getStyle();
556 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 548 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
557 SkStrokeRec::kHairline_Style == style; 549 SkStrokeRec::kHairline_Style == style;
558 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 550 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
559 551
560 SkScalar innerRadius = 0.0f; 552 SkScalar innerRadius = 0.0f;
561 SkScalar outerRadius = radius; 553 SkScalar outerRadius = radius;
562 SkScalar halfWidth = 0; 554 SkScalar halfWidth = 0;
563 if (hasStroke) { 555 if (hasStroke) {
564 if (SkScalarNearlyZero(strokeWidth)) { 556 if (SkScalarNearlyZero(strokeWidth)) {
565 halfWidth = SK_ScalarHalf; 557 halfWidth = SK_ScalarHalf;
566 } else { 558 } else {
567 halfWidth = SkScalarHalf(strokeWidth); 559 halfWidth = SkScalarHalf(strokeWidth);
568 } 560 }
569 561
570 outerRadius += halfWidth; 562 outerRadius += halfWidth;
571 if (isStrokeOnly) { 563 if (isStrokeOnly) {
572 innerRadius = radius - halfWidth; 564 innerRadius = radius - halfWidth;
573 } 565 }
574 } 566 }
575 567
576 GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadi us > 0); 568 GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadi us > 0);
577 drawState->setGeometryProcessor(gp)->unref(); 569 drawState->setGeometryProcessor(gp)->unref();
578 570
571 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
572 if (!geo.succeeded()) {
573 SkDebugf("Failed to get space for vertices!\n");
574 return;
575 }
576
577 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
578
579 // The radii are outset for two reasons. First, it allows the shader to simp ly perform 579 // The radii are outset for two reasons. First, it allows the shader to simp ly perform
580 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use d to compute the 580 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use d to compute the
581 // verts of the bounding box that is rendered and the outset ensures the box will cover all 581 // verts of the bounding box that is rendered and the outset ensures the box will cover all
582 // pixels partially covered by the circle. 582 // pixels partially covered by the circle.
583 outerRadius += SK_ScalarHalf; 583 outerRadius += SK_ScalarHalf;
584 innerRadius -= SK_ScalarHalf; 584 innerRadius -= SK_ScalarHalf;
585 585
586 SkRect bounds = SkRect::MakeLTRB( 586 SkRect bounds = SkRect::MakeLTRB(
587 center.fX - outerRadius, 587 center.fX - outerRadius,
588 center.fY - outerRadius, 588 center.fY - outerRadius,
(...skipping 21 matching lines...) Expand all
610 verts[3].fOuterRadius = outerRadius; 610 verts[3].fOuterRadius = outerRadius;
611 verts[3].fInnerRadius = innerRadius; 611 verts[3].fInnerRadius = innerRadius;
612 612
613 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); 613 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
614 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds); 614 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
615 target->resetIndexSource(); 615 target->resetIndexSource();
616 } 616 }
617 617
618 /////////////////////////////////////////////////////////////////////////////// 618 ///////////////////////////////////////////////////////////////////////////////
619 619
620 // position + offset + 1/radii
621 extern const GrVertexAttrib gEllipseVertexAttribs[] = {
622 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi ng},
623 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt tribBinding},
624 {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt tribBinding}
625 };
626
627 // position + offsets
628 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = {
629 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi ng},
630 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt tribBinding},
631 {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt tribBinding},
632 };
633
634 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, 620 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
635 GrDrawState* drawState, 621 GrDrawState* drawState,
636 const GrContext* context, 622 const GrContext* context,
637 bool useCoverageAA, 623 bool useCoverageAA,
638 const SkRect& ellipse, 624 const SkRect& ellipse,
639 const SkStrokeRec& stroke) 625 const SkStrokeRec& stroke)
640 { 626 {
641 #ifdef SK_DEBUG 627 #ifdef SK_DEBUG
642 { 628 {
643 // we should have checked for this previously 629 // we should have checked for this previously
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 683
698 xRadius += scaledStroke.fX; 684 xRadius += scaledStroke.fX;
699 yRadius += scaledStroke.fY; 685 yRadius += scaledStroke.fY;
700 } 686 }
701 687
702 GrDrawState::AutoViewMatrixRestore avmr; 688 GrDrawState::AutoViewMatrixRestore avmr;
703 if (!avmr.setIdentity(drawState)) { 689 if (!avmr.setIdentity(drawState)) {
704 return false; 690 return false;
705 } 691 }
706 692
707 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVe rtexAttribs), 693 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
708 sizeof(EllipseVertex)); 694 innerXRadius > 0 && inne rYRadius > 0);
709 695
710 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride( ), 0); 696 drawState->setGeometryProcessor(gp)->unref();
697
698 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
711 if (!geo.succeeded()) { 699 if (!geo.succeeded()) {
712 SkDebugf("Failed to get space for vertices!\n"); 700 SkDebugf("Failed to get space for vertices!\n");
713 return false; 701 return false;
714 } 702 }
715 703
716 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 704 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
717 705
718 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
719 innerXRadius > 0 && inne rYRadius > 0);
720
721 drawState->setGeometryProcessor(gp)->unref();
722
723 // Compute the reciprocals of the radii here to save time in the shader 706 // Compute the reciprocals of the radii here to save time in the shader
724 SkScalar xRadRecip = SkScalarInvert(xRadius); 707 SkScalar xRadRecip = SkScalarInvert(xRadius);
725 SkScalar yRadRecip = SkScalarInvert(yRadius); 708 SkScalar yRadRecip = SkScalarInvert(yRadius);
726 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 709 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
727 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 710 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
728 711
729 // We've extended the outer x radius out half a pixel to antialias. 712 // We've extended the outer x radius out half a pixel to antialias.
730 // This will also expand the rect so all the pixels will be captured. 713 // This will also expand the rect so all the pixels will be captured.
731 // TODO: Consider if we should use sqrt(2)/2 instead 714 // TODO: Consider if we should use sqrt(2)/2 instead
732 xRadius += SK_ScalarHalf; 715 xRadius += SK_ScalarHalf;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 xRadius += strokeWidth; 800 xRadius += strokeWidth;
818 yRadius += strokeWidth; 801 yRadius += strokeWidth;
819 } 802 }
820 if (DIEllipseEdgeEffect::kStroke == mode) { 803 if (DIEllipseEdgeEffect::kStroke == mode) {
821 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke : 804 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke :
822 DIEllipseEdgeEffect::kFi ll; 805 DIEllipseEdgeEffect::kFi ll;
823 } 806 }
824 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); 807 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
825 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); 808 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
826 809
827 drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllip seVertexAttribs), 810 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
828 sizeof(DIEllipseVertex) );
829 811
830 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride( ), 0); 812 drawState->setGeometryProcessor(gp)->unref();
813
814 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
831 if (!geo.succeeded()) { 815 if (!geo.succeeded()) {
832 SkDebugf("Failed to get space for vertices!\n"); 816 SkDebugf("Failed to get space for vertices!\n");
833 return false; 817 return false;
834 } 818 }
835 819
836 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); 820 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
837 821
838 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
839
840 drawState->setGeometryProcessor(gp)->unref();
841
842 // This expands the outer rect so that after CTM we end up with a half-pixel border 822 // This expands the outer rect so that after CTM we end up with a half-pixel border
843 SkScalar a = vm[SkMatrix::kMScaleX]; 823 SkScalar a = vm[SkMatrix::kMScaleX];
844 SkScalar b = vm[SkMatrix::kMSkewX]; 824 SkScalar b = vm[SkMatrix::kMSkewX];
845 SkScalar c = vm[SkMatrix::kMSkewY]; 825 SkScalar c = vm[SkMatrix::kMSkewY];
846 SkScalar d = vm[SkMatrix::kMScaleY]; 826 SkScalar d = vm[SkMatrix::kMScaleY];
847 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); 827 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
848 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); 828 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
849 // This adjusts the "radius" to include the half-pixel border 829 // This adjusts the "radius" to include the half-pixel border
850 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); 830 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius);
851 SkScalar offsetDy = SkScalarDiv(geoDy, yRadius); 831 SkScalar offsetDy = SkScalarDiv(geoDy, yRadius);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 } 1045 }
1066 1046
1067 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->g etGpu()); 1047 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->g etGpu());
1068 if (NULL == indexBuffer) { 1048 if (NULL == indexBuffer) {
1069 SkDebugf("Failed to create index buffer!\n"); 1049 SkDebugf("Failed to create index buffer!\n");
1070 return false; 1050 return false;
1071 } 1051 }
1072 1052
1073 // if the corners are circles, use the circle renderer 1053 // if the corners are circles, use the circle renderer
1074 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) { 1054 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) {
1075 drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircle VertexAttribs),
1076 sizeof(CircleVertex));
1077
1078 GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexSt ride(), 0);
1079 if (!geo.succeeded()) {
1080 SkDebugf("Failed to get space for vertices!\n");
1081 return false;
1082 }
1083 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
1084
1085 SkScalar innerRadius = 0.0f; 1055 SkScalar innerRadius = 0.0f;
1086 SkScalar outerRadius = xRadius; 1056 SkScalar outerRadius = xRadius;
1087 SkScalar halfWidth = 0; 1057 SkScalar halfWidth = 0;
1088 if (hasStroke) { 1058 if (hasStroke) {
1089 if (SkScalarNearlyZero(scaledStroke.fX)) { 1059 if (SkScalarNearlyZero(scaledStroke.fX)) {
1090 halfWidth = SK_ScalarHalf; 1060 halfWidth = SK_ScalarHalf;
1091 } else { 1061 } else {
1092 halfWidth = SkScalarHalf(scaledStroke.fX); 1062 halfWidth = SkScalarHalf(scaledStroke.fX);
1093 } 1063 }
1094 1064
1095 if (isStrokeOnly) { 1065 if (isStrokeOnly) {
1096 innerRadius = xRadius - halfWidth; 1066 innerRadius = xRadius - halfWidth;
1097 } 1067 }
1098 outerRadius += halfWidth; 1068 outerRadius += halfWidth;
1099 bounds.outset(halfWidth, halfWidth); 1069 bounds.outset(halfWidth, halfWidth);
1100 } 1070 }
1101 1071
1102 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 1072 isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
1103 1073
1104 GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly); 1074 GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly);
1105 drawState->setGeometryProcessor(effect)->unref(); 1075 drawState->setGeometryProcessor(effect)->unref();
1106 1076
1077 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0);
1078 if (!geo.succeeded()) {
1079 SkDebugf("Failed to get space for vertices!\n");
1080 return false;
1081 }
1082 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
1083
1107 // The radii are outset for two reasons. First, it allows the shader to simply perform 1084 // The radii are outset for two reasons. First, it allows the shader to simply perform
1108 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the 1085 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
1109 // verts of the bounding box that is rendered and the outset ensures the box will cover all 1086 // verts of the bounding box that is rendered and the outset ensures the box will cover all
1110 // pixels partially covered by the circle. 1087 // pixels partially covered by the circle.
1111 outerRadius += SK_ScalarHalf; 1088 outerRadius += SK_ScalarHalf;
1112 innerRadius -= SK_ScalarHalf; 1089 innerRadius -= SK_ScalarHalf;
1113 1090
1114 // Expand the rect so all the pixels will be captured. 1091 // Expand the rect so all the pixels will be captured.
1115 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1092 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1116 1093
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 1131
1155 // drop out the middle quad if we're stroked 1132 // drop out the middle quad if we're stroked
1156 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1133 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1157 SK_ARRAY_COUNT(gRRectIndices); 1134 SK_ARRAY_COUNT(gRRectIndices);
1158 target->setIndexSourceToBuffer(indexBuffer); 1135 target->setIndexSourceToBuffer(indexBuffer);
1159 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt, 1136 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt,
1160 &bounds); 1137 &bounds);
1161 1138
1162 // otherwise we use the ellipse renderer 1139 // otherwise we use the ellipse renderer
1163 } else { 1140 } else {
1164 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllip seVertexAttribs),
1165 sizeof(EllipseVertex) );
1166
1167 SkScalar innerXRadius = 0.0f; 1141 SkScalar innerXRadius = 0.0f;
1168 SkScalar innerYRadius = 0.0f; 1142 SkScalar innerYRadius = 0.0f;
1169 if (hasStroke) { 1143 if (hasStroke) {
1170 if (SkScalarNearlyZero(scaledStroke.length())) { 1144 if (SkScalarNearlyZero(scaledStroke.length())) {
1171 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 1145 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
1172 } else { 1146 } else {
1173 scaledStroke.scale(SK_ScalarHalf); 1147 scaledStroke.scale(SK_ScalarHalf);
1174 } 1148 }
1175 1149
1176 // we only handle thick strokes for near-circular ellipses 1150 // we only handle thick strokes for near-circular ellipses
(...skipping 14 matching lines...) Expand all
1191 innerYRadius = yRadius - scaledStroke.fY; 1165 innerYRadius = yRadius - scaledStroke.fY;
1192 } 1166 }
1193 1167
1194 xRadius += scaledStroke.fX; 1168 xRadius += scaledStroke.fX;
1195 yRadius += scaledStroke.fY; 1169 yRadius += scaledStroke.fY;
1196 bounds.outset(scaledStroke.fX, scaledStroke.fY); 1170 bounds.outset(scaledStroke.fX, scaledStroke.fY);
1197 } 1171 }
1198 1172
1199 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); 1173 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
1200 1174
1201 GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexSt ride(), 0); 1175 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
1176 drawState->setGeometryProcessor(effect)->unref();
1177
1178 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0);
1202 if (!geo.succeeded()) { 1179 if (!geo.succeeded()) {
1203 SkDebugf("Failed to get space for vertices!\n"); 1180 SkDebugf("Failed to get space for vertices!\n");
1204 return false; 1181 return false;
1205 } 1182 }
1183
1206 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 1184 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
1207 1185
1208 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
1209 drawState->setGeometryProcessor(effect)->unref();
1210
1211 // Compute the reciprocals of the radii here to save time in the shader 1186 // Compute the reciprocals of the radii here to save time in the shader
1212 SkScalar xRadRecip = SkScalarInvert(xRadius); 1187 SkScalar xRadRecip = SkScalarInvert(xRadius);
1213 SkScalar yRadRecip = SkScalarInvert(yRadius); 1188 SkScalar yRadRecip = SkScalarInvert(yRadius);
1214 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 1189 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
1215 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 1190 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
1216 1191
1217 // Extend the radii out half a pixel to antialias. 1192 // Extend the radii out half a pixel to antialias.
1218 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; 1193 SkScalar xOuterRadius = xRadius + SK_ScalarHalf;
1219 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; 1194 SkScalar yOuterRadius = yRadius + SK_ScalarHalf;
1220 1195
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1239 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1265 SK_ARRAY_COUNT(gRRectIndices); 1240 SK_ARRAY_COUNT(gRRectIndices);
1266 target->setIndexSourceToBuffer(indexBuffer); 1241 target->setIndexSourceToBuffer(indexBuffer);
1267 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt, 1242 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt,
1268 &bounds); 1243 &bounds);
1269 } 1244 }
1270 1245
1271 target->resetIndexSource(); 1246 target->resetIndexSource();
1272 return true; 1247 return true;
1273 } 1248 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698