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

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: adding test to ignore 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
« no previous file with comments | « src/gpu/GrOptDrawState.cpp ('k') | src/gpu/GrProgramDesc.h » ('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 "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);
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);
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);
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 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex));
573 if (!geo.succeeded()) {
574 SkDebugf("Failed to get space for vertices!\n");
575 return;
576 }
577
578 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
579
579 // The radii are outset for two reasons. First, it allows the shader to simp ly perform 580 // 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 581 // 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 582 // verts of the bounding box that is rendered and the outset ensures the box will cover all
582 // pixels partially covered by the circle. 583 // pixels partially covered by the circle.
583 outerRadius += SK_ScalarHalf; 584 outerRadius += SK_ScalarHalf;
584 innerRadius -= SK_ScalarHalf; 585 innerRadius -= SK_ScalarHalf;
585 586
586 SkRect bounds = SkRect::MakeLTRB( 587 SkRect bounds = SkRect::MakeLTRB(
587 center.fX - outerRadius, 588 center.fX - outerRadius,
588 center.fY - outerRadius, 589 center.fY - outerRadius,
(...skipping 21 matching lines...) Expand all
610 verts[3].fOuterRadius = outerRadius; 611 verts[3].fOuterRadius = outerRadius;
611 verts[3].fInnerRadius = innerRadius; 612 verts[3].fInnerRadius = innerRadius;
612 613
613 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); 614 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
614 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds); 615 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
615 target->resetIndexSource(); 616 target->resetIndexSource();
616 } 617 }
617 618
618 /////////////////////////////////////////////////////////////////////////////// 619 ///////////////////////////////////////////////////////////////////////////////
619 620
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, 621 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
635 GrDrawState* drawState, 622 GrDrawState* drawState,
636 const GrContext* context, 623 const GrContext* context,
637 bool useCoverageAA, 624 bool useCoverageAA,
638 const SkRect& ellipse, 625 const SkRect& ellipse,
639 const SkStrokeRec& stroke) 626 const SkStrokeRec& stroke)
640 { 627 {
641 #ifdef SK_DEBUG 628 #ifdef SK_DEBUG
642 { 629 {
643 // we should have checked for this previously 630 // we should have checked for this previously
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 684
698 xRadius += scaledStroke.fX; 685 xRadius += scaledStroke.fX;
699 yRadius += scaledStroke.fY; 686 yRadius += scaledStroke.fY;
700 } 687 }
701 688
702 GrDrawState::AutoViewMatrixRestore avmr; 689 GrDrawState::AutoViewMatrixRestore avmr;
703 if (!avmr.setIdentity(drawState)) { 690 if (!avmr.setIdentity(drawState)) {
704 return false; 691 return false;
705 } 692 }
706 693
707 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVe rtexAttribs), 694 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
708 sizeof(EllipseVertex)); 695 innerXRadius > 0 && inne rYRadius > 0);
709 696
710 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride( ), 0); 697 drawState->setGeometryProcessor(gp)->unref();
698
699 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
700 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex));
711 if (!geo.succeeded()) { 701 if (!geo.succeeded()) {
712 SkDebugf("Failed to get space for vertices!\n"); 702 SkDebugf("Failed to get space for vertices!\n");
713 return false; 703 return false;
714 } 704 }
715 705
716 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 706 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
717 707
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 708 // Compute the reciprocals of the radii here to save time in the shader
724 SkScalar xRadRecip = SkScalarInvert(xRadius); 709 SkScalar xRadRecip = SkScalarInvert(xRadius);
725 SkScalar yRadRecip = SkScalarInvert(yRadius); 710 SkScalar yRadRecip = SkScalarInvert(yRadius);
726 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 711 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
727 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 712 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
728 713
729 // 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.
730 // 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.
731 // TODO: Consider if we should use sqrt(2)/2 instead 716 // TODO: Consider if we should use sqrt(2)/2 instead
732 xRadius += SK_ScalarHalf; 717 xRadius += SK_ScalarHalf;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 xRadius += strokeWidth; 802 xRadius += strokeWidth;
818 yRadius += strokeWidth; 803 yRadius += strokeWidth;
819 } 804 }
820 if (DIEllipseEdgeEffect::kStroke == mode) { 805 if (DIEllipseEdgeEffect::kStroke == mode) {
821 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke : 806 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke :
822 DIEllipseEdgeEffect::kFi ll; 807 DIEllipseEdgeEffect::kFi ll;
823 } 808 }
824 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); 809 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
825 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); 810 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
826 811
827 drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllip seVertexAttribs), 812 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
828 sizeof(DIEllipseVertex) );
829 813
830 GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride( ), 0); 814 drawState->setGeometryProcessor(gp)->unref();
815
816 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
817 SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex));
831 if (!geo.succeeded()) { 818 if (!geo.succeeded()) {
832 SkDebugf("Failed to get space for vertices!\n"); 819 SkDebugf("Failed to get space for vertices!\n");
833 return false; 820 return false;
834 } 821 }
835 822
836 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); 823 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
837 824
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 825 // This expands the outer rect so that after CTM we end up with a half-pixel border
843 SkScalar a = vm[SkMatrix::kMScaleX]; 826 SkScalar a = vm[SkMatrix::kMScaleX];
844 SkScalar b = vm[SkMatrix::kMSkewX]; 827 SkScalar b = vm[SkMatrix::kMSkewX];
845 SkScalar c = vm[SkMatrix::kMSkewY]; 828 SkScalar c = vm[SkMatrix::kMSkewY];
846 SkScalar d = vm[SkMatrix::kMScaleY]; 829 SkScalar d = vm[SkMatrix::kMScaleY];
847 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); 830 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
848 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); 831 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
849 // This adjusts the "radius" to include the half-pixel border 832 // This adjusts the "radius" to include the half-pixel border
850 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); 833 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius);
851 SkScalar offsetDy = SkScalarDiv(geoDy, yRadius); 834 SkScalar offsetDy = SkScalarDiv(geoDy, yRadius);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 } 1048 }
1066 1049
1067 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->g etGpu()); 1050 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->g etGpu());
1068 if (NULL == indexBuffer) { 1051 if (NULL == indexBuffer) {
1069 SkDebugf("Failed to create index buffer!\n"); 1052 SkDebugf("Failed to create index buffer!\n");
1070 return false; 1053 return false;
1071 } 1054 }
1072 1055
1073 // if the corners are circles, use the circle renderer 1056 // if the corners are circles, use the circle renderer
1074 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) { 1057 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; 1058 SkScalar innerRadius = 0.0f;
1086 SkScalar outerRadius = xRadius; 1059 SkScalar outerRadius = xRadius;
1087 SkScalar halfWidth = 0; 1060 SkScalar halfWidth = 0;
1088 if (hasStroke) { 1061 if (hasStroke) {
1089 if (SkScalarNearlyZero(scaledStroke.fX)) { 1062 if (SkScalarNearlyZero(scaledStroke.fX)) {
1090 halfWidth = SK_ScalarHalf; 1063 halfWidth = SK_ScalarHalf;
1091 } else { 1064 } else {
1092 halfWidth = SkScalarHalf(scaledStroke.fX); 1065 halfWidth = SkScalarHalf(scaledStroke.fX);
1093 } 1066 }
1094 1067
1095 if (isStrokeOnly) { 1068 if (isStrokeOnly) {
1096 innerRadius = xRadius - halfWidth; 1069 innerRadius = xRadius - halfWidth;
1097 } 1070 }
1098 outerRadius += halfWidth; 1071 outerRadius += halfWidth;
1099 bounds.outset(halfWidth, halfWidth); 1072 bounds.outset(halfWidth, halfWidth);
1100 } 1073 }
1101 1074
1102 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 1075 isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
1103 1076
1104 GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly); 1077 GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly);
1105 drawState->setGeometryProcessor(effect)->unref(); 1078 drawState->setGeometryProcessor(effect)->unref();
1106 1079
1080 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0);
1081 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex));
1082 if (!geo.succeeded()) {
1083 SkDebugf("Failed to get space for vertices!\n");
1084 return false;
1085 }
1086 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
1087
1107 // The radii are outset for two reasons. First, it allows the shader to simply perform 1088 // 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 1089 // 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 1090 // verts of the bounding box that is rendered and the outset ensures the box will cover all
1110 // pixels partially covered by the circle. 1091 // pixels partially covered by the circle.
1111 outerRadius += SK_ScalarHalf; 1092 outerRadius += SK_ScalarHalf;
1112 innerRadius -= SK_ScalarHalf; 1093 innerRadius -= SK_ScalarHalf;
1113 1094
1114 // Expand the rect so all the pixels will be captured. 1095 // Expand the rect so all the pixels will be captured.
1115 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1096 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1116 1097
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 1135
1155 // drop out the middle quad if we're stroked 1136 // drop out the middle quad if we're stroked
1156 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1137 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1157 SK_ARRAY_COUNT(gRRectIndices); 1138 SK_ARRAY_COUNT(gRRectIndices);
1158 target->setIndexSourceToBuffer(indexBuffer); 1139 target->setIndexSourceToBuffer(indexBuffer);
1159 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt, 1140 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt,
1160 &bounds); 1141 &bounds);
1161 1142
1162 // otherwise we use the ellipse renderer 1143 // otherwise we use the ellipse renderer
1163 } else { 1144 } else {
1164 drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllip seVertexAttribs),
1165 sizeof(EllipseVertex) );
1166
1167 SkScalar innerXRadius = 0.0f; 1145 SkScalar innerXRadius = 0.0f;
1168 SkScalar innerYRadius = 0.0f; 1146 SkScalar innerYRadius = 0.0f;
1169 if (hasStroke) { 1147 if (hasStroke) {
1170 if (SkScalarNearlyZero(scaledStroke.length())) { 1148 if (SkScalarNearlyZero(scaledStroke.length())) {
1171 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 1149 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
1172 } else { 1150 } else {
1173 scaledStroke.scale(SK_ScalarHalf); 1151 scaledStroke.scale(SK_ScalarHalf);
1174 } 1152 }
1175 1153
1176 // we only handle thick strokes for near-circular ellipses 1154 // we only handle thick strokes for near-circular ellipses
(...skipping 14 matching lines...) Expand all
1191 innerYRadius = yRadius - scaledStroke.fY; 1169 innerYRadius = yRadius - scaledStroke.fY;
1192 } 1170 }
1193 1171
1194 xRadius += scaledStroke.fX; 1172 xRadius += scaledStroke.fX;
1195 yRadius += scaledStroke.fY; 1173 yRadius += scaledStroke.fY;
1196 bounds.outset(scaledStroke.fX, scaledStroke.fY); 1174 bounds.outset(scaledStroke.fX, scaledStroke.fY);
1197 } 1175 }
1198 1176
1199 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); 1177 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
1200 1178
1201 GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexSt ride(), 0); 1179 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
1180 drawState->setGeometryProcessor(effect)->unref();
1181
1182 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid e(), 0);
1183 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex));
1202 if (!geo.succeeded()) { 1184 if (!geo.succeeded()) {
1203 SkDebugf("Failed to get space for vertices!\n"); 1185 SkDebugf("Failed to get space for vertices!\n");
1204 return false; 1186 return false;
1205 } 1187 }
1188
1206 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); 1189 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
1207 1190
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 1191 // Compute the reciprocals of the radii here to save time in the shader
1212 SkScalar xRadRecip = SkScalarInvert(xRadius); 1192 SkScalar xRadRecip = SkScalarInvert(xRadius);
1213 SkScalar yRadRecip = SkScalarInvert(yRadius); 1193 SkScalar yRadRecip = SkScalarInvert(yRadius);
1214 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); 1194 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
1215 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); 1195 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
1216 1196
1217 // Extend the radii out half a pixel to antialias. 1197 // Extend the radii out half a pixel to antialias.
1218 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; 1198 SkScalar xOuterRadius = xRadius + SK_ScalarHalf;
1219 SkScalar yOuterRadius = yRadius + SK_ScalarHalf; 1199 SkScalar yOuterRadius = yRadius + SK_ScalarHalf;
1220 1200
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : 1244 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
1265 SK_ARRAY_COUNT(gRRectIndices); 1245 SK_ARRAY_COUNT(gRRectIndices);
1266 target->setIndexSourceToBuffer(indexBuffer); 1246 target->setIndexSourceToBuffer(indexBuffer);
1267 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt, 1247 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1 6, indexCnt,
1268 &bounds); 1248 &bounds);
1269 } 1249 }
1270 1250
1271 target->resetIndexSource(); 1251 target->resetIndexSource();
1272 return true; 1252 return true;
1273 } 1253 }
OLDNEW
« no previous file with comments | « src/gpu/GrOptDrawState.cpp ('k') | src/gpu/GrProgramDesc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698