OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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(¢er, 1); | 538 vm.mapPoints(¢er, 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |