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/GrGLFullProgramBuilder.h" | 10 #include "gl/builders/GrGLFullProgramBuilder.h" |
11 #include "gl/GrGLEffect.h" | 11 #include "gl/GrGLProcessor.h" |
12 #include "gl/GrGLSL.h" | 12 #include "gl/GrGLSL.h" |
13 #include "gl/GrGLGeometryProcessor.h" | 13 #include "gl/GrGLGeometryProcessor.h" |
14 #include "GrEffect.h" | 14 #include "GrProcessor.h" |
15 #include "GrTBackendEffectFactory.h" | 15 #include "GrTBackendProcessorFactory.h" |
16 | 16 |
17 #include "GrDrawState.h" | 17 #include "GrDrawState.h" |
18 #include "GrDrawTarget.h" | 18 #include "GrDrawTarget.h" |
19 #include "GrGpu.h" | 19 #include "GrGpu.h" |
20 | 20 |
21 #include "SkRRect.h" | 21 #include "SkRRect.h" |
22 #include "SkStrokeRec.h" | 22 #include "SkStrokeRec.h" |
23 #include "SkTLazy.h" | 23 #include "SkTLazy.h" |
24 | 24 |
25 #include "effects/GrGeometryProcessor.h" | 25 #include "GrGeometryProcessor.h" |
26 #include "effects/GrRRectEffect.h" | 26 #include "effects/GrRRectEffect.h" |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 struct CircleVertex { | 30 struct CircleVertex { |
31 SkPoint fPos; | 31 SkPoint fPos; |
32 SkPoint fOffset; | 32 SkPoint fOffset; |
33 SkScalar fOuterRadius; | 33 SkScalar fOuterRadius; |
34 SkScalar fInnerRadius; | 34 SkScalar fInnerRadius; |
35 }; | 35 }; |
(...skipping 19 matching lines...) Expand all Loading... |
55 | 55 |
56 /////////////////////////////////////////////////////////////////////////////// | 56 /////////////////////////////////////////////////////////////////////////////// |
57 | 57 |
58 /** | 58 /** |
59 * The output of this effect is a modulation of the input color and coverage for
a circle, | 59 * The output of this effect is a modulation of the input color and coverage for
a circle, |
60 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. | 60 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. |
61 */ | 61 */ |
62 | 62 |
63 class CircleEdgeEffect : public GrGeometryProcessor { | 63 class CircleEdgeEffect : public GrGeometryProcessor { |
64 public: | 64 public: |
65 static GrEffect* Create(bool stroke) { | 65 static GrGeometryProcessor* Create(bool stroke) { |
66 GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); | 66 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCircleStrokeEdge, CircleEdgeEffect,
(true)); |
67 GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); | 67 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCircleFillEdge, CircleEdgeEffect, (
false)); |
68 | 68 |
69 if (stroke) { | 69 if (stroke) { |
70 gCircleStrokeEdge->ref(); | 70 gCircleStrokeEdge->ref(); |
71 return gCircleStrokeEdge; | 71 return gCircleStrokeEdge; |
72 } else { | 72 } else { |
73 gCircleFillEdge->ref(); | 73 gCircleFillEdge->ref(); |
74 return gCircleFillEdge; | 74 return gCircleFillEdge; |
75 } | 75 } |
76 } | 76 } |
77 | 77 |
78 virtual void getConstantColorComponents(GrColor* color, | 78 virtual void getConstantColorComponents(GrColor* color, |
79 uint32_t* validFlags) const SK_OVERR
IDE { | 79 uint32_t* validFlags) const SK_OVERR
IDE { |
80 *validFlags = 0; | 80 *validFlags = 0; |
81 } | 81 } |
82 | 82 |
83 const GrShaderVar& inCircleEdge() const { return fInCircleEdge; } | 83 const GrShaderVar& inCircleEdge() const { return fInCircleEdge; } |
84 | 84 |
85 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 85 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE { |
86 return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance(); | 86 return GrTBackendGeometryProcessorFactory<CircleEdgeEffect>::getInstance
(); |
87 } | 87 } |
88 | 88 |
89 virtual ~CircleEdgeEffect() {} | 89 virtual ~CircleEdgeEffect() {} |
90 | 90 |
91 static const char* Name() { return "CircleEdge"; } | 91 static const char* Name() { return "CircleEdge"; } |
92 | 92 |
93 inline bool isStroked() const { return fStroke; } | 93 inline bool isStroked() const { return fStroke; } |
94 | 94 |
95 class GLEffect : public GrGLGeometryProcessor { | 95 class GLProcessor : public GrGLGeometryProcessor { |
96 public: | 96 public: |
97 GLEffect(const GrBackendEffectFactory& factory, const GrEffect&) | 97 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) |
98 : INHERITED (factory) {} | 98 : INHERITED (factory) {} |
99 | 99 |
100 virtual void emitCode(GrGLFullProgramBuilder* builder, | 100 virtual void emitCode(GrGLFullProgramBuilder* builder, |
101 const GrEffect& effect, | 101 const GrGeometryProcessor& geometryProcessor, |
102 const GrEffectKey& key, | 102 const GrProcessorKey& key, |
103 const char* outputColor, | 103 const char* outputColor, |
104 const char* inputColor, | 104 const char* inputColor, |
105 const TransformedCoordsArray&, | 105 const TransformedCoordsArray&, |
106 const TextureSamplerArray& samplers) SK_OVERRIDE { | 106 const TextureSamplerArray& samplers) SK_OVERRIDE { |
107 const CircleEdgeEffect& circleEffect = effect.cast<CircleEdgeEffect>
(); | 107 const CircleEdgeEffect& circleEffect = geometryProcessor.cast<Circle
EdgeEffect>(); |
108 const char *vsName, *fsName; | 108 const char *vsName, *fsName; |
109 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName)
; | 109 builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName)
; |
110 | 110 |
111 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
();; | 111 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
();; |
112 vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.inCircle
Edge().c_str()); | 112 vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.inCircle
Edge().c_str()); |
113 | 113 |
114 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 114 GrGLBaseFragmentShaderBuilder* fsBuilder = builder->getFragmentShade
rBuilder(); |
115 fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName); | 115 fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName); |
116 fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0
);\n", fsName); | 116 fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0
);\n", fsName); |
117 if (circleEffect.isStroked()) { | 117 if (circleEffect.isStroked()) { |
118 fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0
, 1.0);\n", fsName); | 118 fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0
, 1.0);\n", fsName); |
119 fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n"); | 119 fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n"); |
120 } | 120 } |
121 | 121 |
122 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, | 122 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
123 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); | 123 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); |
124 } | 124 } |
125 | 125 |
126 static void GenKey(const GrEffect& effect, const GrGLCaps&, | 126 static void GenKey(const GrProcessor& processor, const GrGLCaps&, |
127 GrEffectKeyBuilder* b) { | 127 GrProcessorKeyBuilder* b) { |
128 const CircleEdgeEffect& circleEffect = effect.cast<CircleEdgeEffect>
(); | 128 const CircleEdgeEffect& circleEffect = processor.cast<CircleEdgeEffe
ct>(); |
129 b->add32(circleEffect.isStroked()); | 129 b->add32(circleEffect.isStroked()); |
130 } | 130 } |
131 | 131 |
132 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_
OVERRIDE {} | 132 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&)
SK_OVERRIDE {} |
133 | 133 |
134 private: | 134 private: |
135 typedef GrGLGeometryProcessor INHERITED; | 135 typedef GrGLGeometryProcessor INHERITED; |
136 }; | 136 }; |
137 | 137 |
138 | 138 |
139 private: | 139 private: |
140 CircleEdgeEffect(bool stroke) | 140 CircleEdgeEffect(bool stroke) |
141 : fInCircleEdge(this->addVertexAttrib( | 141 : fInCircleEdge(this->addVertexAttrib( |
142 GrShaderVar("inCircleEdge", | 142 GrShaderVar("inCircleEdge", |
143 kVec4f_GrSLType, | 143 kVec4f_GrSLType, |
144 GrShaderVar::kAttribute_TypeModifier))) { | 144 GrShaderVar::kAttribute_TypeModifier))) { |
145 fStroke = stroke; | 145 fStroke = stroke; |
146 } | 146 } |
147 | 147 |
148 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 148 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { |
149 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); | 149 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); |
150 return cee.fStroke == fStroke; | 150 return cee.fStroke == fStroke; |
151 } | 151 } |
152 | 152 |
153 const GrShaderVar& fInCircleEdge; | 153 const GrShaderVar& fInCircleEdge; |
154 bool fStroke; | 154 bool fStroke; |
155 | 155 |
156 GR_DECLARE_EFFECT_TEST; | 156 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
157 | 157 |
158 typedef GrGeometryProcessor INHERITED; | 158 typedef GrGeometryProcessor INHERITED; |
159 }; | 159 }; |
160 | 160 |
161 GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); | 161 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); |
162 | 162 |
163 GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, | 163 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, |
164 GrContext* context, | 164 GrContext* context, |
165 const GrDrawTargetCaps&, | 165 const GrDrawTargetCaps&, |
166 GrTexture* textures[]) { | 166 GrTexture* textures[]) { |
167 return CircleEdgeEffect::Create(random->nextBool()); | 167 return CircleEdgeEffect::Create(random->nextBool()); |
168 } | 168 } |
169 | 169 |
170 /////////////////////////////////////////////////////////////////////////////// | 170 /////////////////////////////////////////////////////////////////////////////// |
171 | 171 |
172 /** | 172 /** |
173 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned | 173 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned |
174 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, | 174 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, |
175 * in both x and y directions. | 175 * in both x and y directions. |
176 * | 176 * |
177 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. | 177 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. |
178 */ | 178 */ |
179 | 179 |
180 class EllipseEdgeEffect : public GrGeometryProcessor { | 180 class EllipseEdgeEffect : public GrGeometryProcessor { |
181 public: | 181 public: |
182 static GrEffect* Create(bool stroke) { | 182 static GrGeometryProcessor* Create(bool stroke) { |
183 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); | 183 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseStrokeEdge, EllipseEdgeEffec
t, (true)); |
184 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); | 184 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseFillEdge, EllipseEdgeEffect,
(false)); |
185 | 185 |
186 if (stroke) { | 186 if (stroke) { |
187 gEllipseStrokeEdge->ref(); | 187 gEllipseStrokeEdge->ref(); |
188 return gEllipseStrokeEdge; | 188 return gEllipseStrokeEdge; |
189 } else { | 189 } else { |
190 gEllipseFillEdge->ref(); | 190 gEllipseFillEdge->ref(); |
191 return gEllipseFillEdge; | 191 return gEllipseFillEdge; |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 virtual void getConstantColorComponents(GrColor* color, | 195 virtual void getConstantColorComponents(GrColor* color, |
196 uint32_t* validFlags) const SK_OVERR
IDE { | 196 uint32_t* validFlags) const SK_OVERR
IDE { |
197 *validFlags = 0; | 197 *validFlags = 0; |
198 } | 198 } |
199 | 199 |
200 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 200 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE { |
201 return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); | 201 return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstanc
e(); |
202 } | 202 } |
203 | 203 |
204 virtual ~EllipseEdgeEffect() {} | 204 virtual ~EllipseEdgeEffect() {} |
205 | 205 |
206 static const char* Name() { return "EllipseEdge"; } | 206 static const char* Name() { return "EllipseEdge"; } |
207 | 207 |
208 const GrShaderVar& inEllipseOffset() const { return fInEllipseOffset; } | 208 const GrShaderVar& inEllipseOffset() const { return fInEllipseOffset; } |
209 const GrShaderVar& inEllipseRadii() const { return fInEllipseRadii; } | 209 const GrShaderVar& inEllipseRadii() const { return fInEllipseRadii; } |
210 | 210 |
211 inline bool isStroked() const { return fStroke; } | 211 inline bool isStroked() const { return fStroke; } |
212 | 212 |
213 class GLEffect : public GrGLGeometryProcessor { | 213 class GLProcessor : public GrGLGeometryProcessor { |
214 public: | 214 public: |
215 GLEffect(const GrBackendEffectFactory& factory, const GrEffect&) | 215 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) |
216 : INHERITED (factory) {} | 216 : INHERITED (factory) {} |
217 | 217 |
218 virtual void emitCode(GrGLFullProgramBuilder* builder, | 218 virtual void emitCode(GrGLFullProgramBuilder* builder, |
219 const GrEffect& effect, | 219 const GrGeometryProcessor& geometryProcessor, |
220 const GrEffectKey& key, | 220 const GrProcessorKey& key, |
221 const char* outputColor, | 221 const char* outputColor, |
222 const char* inputColor, | 222 const char* inputColor, |
223 const TransformedCoordsArray&, | 223 const TransformedCoordsArray&, |
224 const TextureSamplerArray& samplers) SK_OVERRIDE { | 224 const TextureSamplerArray& samplers) SK_OVERRIDE { |
225 const EllipseEdgeEffect& ellipseEffect = effect.cast<EllipseEdgeEffe
ct>(); | 225 const EllipseEdgeEffect& ellipseEffect = geometryProcessor.cast<Elli
pseEdgeEffect>(); |
226 | 226 |
227 const char *vsOffsetName, *fsOffsetName; | 227 const char *vsOffsetName, *fsOffsetName; |
228 const char *vsRadiiName, *fsRadiiName; | 228 const char *vsRadiiName, *fsRadiiName; |
229 | 229 |
230 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName
, &fsOffsetName); | 230 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName
, &fsOffsetName); |
231 | 231 |
232 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); | 232 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); |
233 vsBuilder->codeAppendf("%s = %s;", vsOffsetName, | 233 vsBuilder->codeAppendf("%s = %s;", vsOffsetName, |
234 ellipseEffect.inEllipseOffset().c_str()); | 234 ellipseEffect.inEllipseOffset().c_str()); |
235 | 235 |
236 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &
fsRadiiName); | 236 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &
fsRadiiName); |
237 vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inElli
pseRadii().c_str()); | 237 vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inElli
pseRadii().c_str()); |
238 | 238 |
239 // for outer curve | 239 // for outer curve |
240 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 240 GrGLBaseFragmentShaderBuilder* fsBuilder = builder->getFragmentShade
rBuilder(); |
241 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset
Name, fsRadiiName); | 241 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffset
Name, fsRadiiName); |
242 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); | 242 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); |
243 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs
RadiiName); | 243 fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fs
RadiiName); |
244 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); | 244 fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); |
245 // avoid calling inversesqrt on zero. | 245 // avoid calling inversesqrt on zero. |
246 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); | 246 fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); |
247 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); | 247 fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); |
248 fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.
0, 1.0);\n"); | 248 fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.
0, 1.0);\n"); |
249 | 249 |
250 // for inner curve | 250 // for inner curve |
251 if (ellipseEffect.isStroked()) { | 251 if (ellipseEffect.isStroked()) { |
252 fsBuilder->codeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetN
ame, fsRadiiName); | 252 fsBuilder->codeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetN
ame, fsRadiiName); |
253 fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset)
- 1.0;\n"); | 253 fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset)
- 1.0;\n"); |
254 fsBuilder->codeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsR
adiiName); | 254 fsBuilder->codeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsR
adiiName); |
255 fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\
n"); | 255 fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\
n"); |
256 fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0
, 1.0);\n"); | 256 fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0
, 1.0);\n"); |
257 } | 257 } |
258 | 258 |
259 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, | 259 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
260 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); | 260 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); |
261 } | 261 } |
262 | 262 |
263 static void GenKey(const GrEffect& effect, const GrGLCaps&, | 263 static void GenKey(const GrProcessor& processor, const GrGLCaps&, |
264 GrEffectKeyBuilder* b) { | 264 GrProcessorKeyBuilder* b) { |
265 const EllipseEdgeEffect& ellipseEffect = effect.cast<EllipseEdgeEffe
ct>(); | 265 const EllipseEdgeEffect& ellipseEffect = processor.cast<EllipseEdgeE
ffect>(); |
266 b->add32(ellipseEffect.isStroked()); | 266 b->add32(ellipseEffect.isStroked()); |
267 } | 267 } |
268 | 268 |
269 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_
OVERRIDE { | 269 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&)
SK_OVERRIDE { |
270 } | 270 } |
271 | 271 |
272 private: | 272 private: |
273 typedef GrGLGeometryProcessor INHERITED; | 273 typedef GrGLGeometryProcessor INHERITED; |
274 }; | 274 }; |
275 | 275 |
276 private: | 276 private: |
277 EllipseEdgeEffect(bool stroke) | 277 EllipseEdgeEffect(bool stroke) |
278 : fInEllipseOffset(this->addVertexAttrib( | 278 : fInEllipseOffset(this->addVertexAttrib( |
279 GrShaderVar("inEllipseOffset", | 279 GrShaderVar("inEllipseOffset", |
280 kVec2f_GrSLType, | 280 kVec2f_GrSLType, |
281 GrShaderVar::kAttribute_TypeModifier))) | 281 GrShaderVar::kAttribute_TypeModifier))) |
282 , fInEllipseRadii(this->addVertexAttrib( | 282 , fInEllipseRadii(this->addVertexAttrib( |
283 GrShaderVar("inEllipseRadii", | 283 GrShaderVar("inEllipseRadii", |
284 kVec4f_GrSLType, | 284 kVec4f_GrSLType, |
285 GrShaderVar::kAttribute_TypeModifier))) { | 285 GrShaderVar::kAttribute_TypeModifier))) { |
286 fStroke = stroke; | 286 fStroke = stroke; |
287 } | 287 } |
288 | 288 |
289 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 289 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { |
290 const EllipseEdgeEffect& eee = other.cast<EllipseEdgeEffect>(); | 290 const EllipseEdgeEffect& eee = other.cast<EllipseEdgeEffect>(); |
291 return eee.fStroke == fStroke; | 291 return eee.fStroke == fStroke; |
292 } | 292 } |
293 | 293 |
294 const GrShaderVar& fInEllipseOffset; | 294 const GrShaderVar& fInEllipseOffset; |
295 const GrShaderVar& fInEllipseRadii; | 295 const GrShaderVar& fInEllipseRadii; |
296 bool fStroke; | 296 bool fStroke; |
297 | 297 |
298 GR_DECLARE_EFFECT_TEST; | 298 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
299 | 299 |
300 typedef GrGeometryProcessor INHERITED; | 300 typedef GrGeometryProcessor INHERITED; |
301 }; | 301 }; |
302 | 302 |
303 GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); | 303 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); |
304 | 304 |
305 GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, | 305 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, |
306 GrContext* context, | 306 GrContext* context, |
307 const GrDrawTargetCaps&, | 307 const GrDrawTargetCaps&, |
308 GrTexture* textures[]) { | 308 GrTexture* textures[]) { |
309 return EllipseEdgeEffect::Create(random->nextBool()); | 309 return EllipseEdgeEffect::Create(random->nextBool()); |
310 } | 310 } |
311 | 311 |
312 /////////////////////////////////////////////////////////////////////////////// | 312 /////////////////////////////////////////////////////////////////////////////// |
313 | 313 |
314 /** | 314 /** |
315 * The output of this effect is a modulation of the input color and coverage for
an ellipse, | 315 * The output of this effect is a modulation of the input color and coverage for
an ellipse, |
316 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The | 316 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The |
317 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by | 317 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by |
318 * using differentials. | 318 * using differentials. |
319 * | 319 * |
320 * The result is device-independent and can be used with any affine matrix. | 320 * The result is device-independent and can be used with any affine matrix. |
321 */ | 321 */ |
322 | 322 |
323 class DIEllipseEdgeEffect : public GrGeometryProcessor { | 323 class DIEllipseEdgeEffect : public GrGeometryProcessor { |
324 public: | 324 public: |
325 enum Mode { kStroke = 0, kHairline, kFill }; | 325 enum Mode { kStroke = 0, kHairline, kFill }; |
326 | 326 |
327 static GrEffect* Create(Mode mode) { | 327 static GrGeometryProcessor* Create(Mode mode) { |
328 GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStrok
e)); | 328 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseStrokeEdge, DIEllipseEdgeEff
ect, (kStroke)); |
329 GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHai
rline)); | 329 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseHairlineEdge, DIEllipseEdgeE
ffect, (kHairline)); |
330 GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); | 330 GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseFillEdge, DIEllipseEdgeEffec
t, (kFill)); |
331 | 331 |
332 if (kStroke == mode) { | 332 if (kStroke == mode) { |
333 gEllipseStrokeEdge->ref(); | 333 gEllipseStrokeEdge->ref(); |
334 return gEllipseStrokeEdge; | 334 return gEllipseStrokeEdge; |
335 } else if (kHairline == mode) { | 335 } else if (kHairline == mode) { |
336 gEllipseHairlineEdge->ref(); | 336 gEllipseHairlineEdge->ref(); |
337 return gEllipseHairlineEdge; | 337 return gEllipseHairlineEdge; |
338 } else { | 338 } else { |
339 gEllipseFillEdge->ref(); | 339 gEllipseFillEdge->ref(); |
340 return gEllipseFillEdge; | 340 return gEllipseFillEdge; |
341 } | 341 } |
342 } | 342 } |
343 | 343 |
344 virtual void getConstantColorComponents(GrColor* color, | 344 virtual void getConstantColorComponents(GrColor* color, |
345 uint32_t* validFlags) const SK_OVERR
IDE { | 345 uint32_t* validFlags) const SK_OVERR
IDE { |
346 *validFlags = 0; | 346 *validFlags = 0; |
347 } | 347 } |
348 | 348 |
349 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 349 virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERR
IDE { |
350 return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance(); | 350 return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInsta
nce(); |
351 } | 351 } |
352 | 352 |
353 virtual ~DIEllipseEdgeEffect() {} | 353 virtual ~DIEllipseEdgeEffect() {} |
354 | 354 |
355 static const char* Name() { return "DIEllipseEdge"; } | 355 static const char* Name() { return "DIEllipseEdge"; } |
356 | 356 |
357 const GrShaderVar& inEllipseOffsets0() const { return fInEllipseOffsets0; } | 357 const GrShaderVar& inEllipseOffsets0() const { return fInEllipseOffsets0; } |
358 const GrShaderVar& inEllipseOffsets1() const { return fInEllipseOffsets1; } | 358 const GrShaderVar& inEllipseOffsets1() const { return fInEllipseOffsets1; } |
359 | 359 |
360 inline Mode getMode() const { return fMode; } | 360 inline Mode getMode() const { return fMode; } |
361 | 361 |
362 class GLEffect : public GrGLGeometryProcessor { | 362 class GLProcessor : public GrGLGeometryProcessor { |
363 public: | 363 public: |
364 GLEffect(const GrBackendEffectFactory& factory, const GrEffect&) | 364 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) |
365 : INHERITED (factory) {} | 365 : INHERITED (factory) {} |
366 | 366 |
367 virtual void emitCode(GrGLFullProgramBuilder* builder, | 367 virtual void emitCode(GrGLFullProgramBuilder* builder, |
368 const GrEffect& effect, | 368 const GrGeometryProcessor& geometryProcessor, |
369 const GrEffectKey& key, | 369 const GrProcessorKey& key, |
370 const char* outputColor, | 370 const char* outputColor, |
371 const char* inputColor, | 371 const char* inputColor, |
372 const TransformedCoordsArray&, | 372 const TransformedCoordsArray&, |
373 const TextureSamplerArray& samplers) SK_OVERRIDE { | 373 const TextureSamplerArray& samplers) SK_OVERRIDE { |
374 const DIEllipseEdgeEffect& ellipseEffect = effect.cast<DIEllipseEdge
Effect>(); | 374 const DIEllipseEdgeEffect& ellipseEffect = |
| 375 geometryProcessor.cast<DIEllipseEdgeEffect>(); |
375 | 376 |
376 const char *vsOffsetName0, *fsOffsetName0; | 377 const char *vsOffsetName0, *fsOffsetName0; |
377 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", | 378 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", |
378 &vsOffsetName0, &fsOffsetName0); | 379 &vsOffsetName0, &fsOffsetName0); |
379 | 380 |
380 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); | 381 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder
(); |
381 vsBuilder->codeAppendf("%s = %s;", vsOffsetName0, | 382 vsBuilder->codeAppendf("%s = %s;", vsOffsetName0, |
382 ellipseEffect.inEllipseOffsets0().c_str()); | 383 ellipseEffect.inEllipseOffsets0().c_str()); |
383 const char *vsOffsetName1, *fsOffsetName1; | 384 const char *vsOffsetName1, *fsOffsetName1; |
384 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", | 385 builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", |
385 &vsOffsetName1, &fsOffsetName1); | 386 &vsOffsetName1, &fsOffsetName1); |
386 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, | 387 vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, |
387 ellipseEffect.inEllipseOffsets1().c_str()); | 388 ellipseEffect.inEllipseOffsets1().c_str()); |
388 | 389 |
389 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 390 GrGLBaseFragmentShaderBuilder* fsBuilder = builder->getFragmentShade
rBuilder(); |
390 SkAssertResult(fsBuilder->enableFeature( | 391 SkAssertResult(fsBuilder->enableFeature( |
391 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)
); | 392 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)
); |
392 // for outer curve | 393 // for outer curve |
393 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam
e0); | 394 fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam
e0); |
394 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); | 395 fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); |
395 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); | 396 fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); |
396 fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); | 397 fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); |
397 fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s
.y*duvdx.y,\n" | 398 fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s
.y*duvdx.y,\n" |
398 "\t 2.0*%s.x*duvdy.x + 2.0*%s
.y*duvdy.y);\n", | 399 "\t 2.0*%s.x*duvdy.x + 2.0*%s
.y*duvdy.y);\n", |
399 fsOffsetName0, fsOffsetName0, fsOffsetName0,
fsOffsetName0); | 400 fsOffsetName0, fsOffsetName0, fsOffsetName0,
fsOffsetName0); |
(...skipping 20 matching lines...) Expand all Loading... |
420 "\t 2.0*%s.x*duvdy.x + 2.0*%s.
y*duvdy.y);\n", | 421 "\t 2.0*%s.x*duvdy.x + 2.0*%s.
y*duvdy.y);\n", |
421 fsOffsetName1, fsOffsetName1, fsOffsetNam
e1, fsOffsetName1); | 422 fsOffsetName1, fsOffsetName1, fsOffsetNam
e1, fsOffsetName1); |
422 fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\
n"); | 423 fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\
n"); |
423 fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0
, 1.0);\n"); | 424 fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0
, 1.0);\n"); |
424 } | 425 } |
425 | 426 |
426 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, | 427 fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
427 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); | 428 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeA
lpha")).c_str()); |
428 } | 429 } |
429 | 430 |
430 static void GenKey(const GrEffect& effect, const GrGLCaps&, | 431 static void GenKey(const GrProcessor& processor, const GrGLCaps&, |
431 GrEffectKeyBuilder* b) { | 432 GrProcessorKeyBuilder* b) { |
432 const DIEllipseEdgeEffect& ellipseEffect = effect.cast<DIEllipseEdge
Effect>(); | 433 const DIEllipseEdgeEffect& ellipseEffect = processor.cast<DIEllipseE
dgeEffect>(); |
433 | 434 |
434 b->add32(ellipseEffect.getMode()); | 435 b->add32(ellipseEffect.getMode()); |
435 } | 436 } |
436 | 437 |
437 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_
OVERRIDE { | 438 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&)
SK_OVERRIDE { |
438 } | 439 } |
439 | 440 |
440 private: | 441 private: |
441 typedef GrGLGeometryProcessor INHERITED; | 442 typedef GrGLGeometryProcessor INHERITED; |
442 }; | 443 }; |
443 | 444 |
444 private: | 445 private: |
445 DIEllipseEdgeEffect(Mode mode) | 446 DIEllipseEdgeEffect(Mode mode) |
446 : fInEllipseOffsets0(this->addVertexAttrib( | 447 : fInEllipseOffsets0(this->addVertexAttrib( |
447 GrShaderVar("inEllipseOffsets0", | 448 GrShaderVar("inEllipseOffsets0", |
448 kVec2f_GrSLType, | 449 kVec2f_GrSLType, |
449 GrShaderVar::kAttribute_TypeModifier))) | 450 GrShaderVar::kAttribute_TypeModifier))) |
450 , fInEllipseOffsets1(this->addVertexAttrib( | 451 , fInEllipseOffsets1(this->addVertexAttrib( |
451 GrShaderVar("inEllipseOffsets1", | 452 GrShaderVar("inEllipseOffsets1", |
452 kVec2f_GrSLType, | 453 kVec2f_GrSLType, |
453 GrShaderVar::kAttribute_TypeModifier))) { | 454 GrShaderVar::kAttribute_TypeModifier))) { |
454 fMode = mode; | 455 fMode = mode; |
455 } | 456 } |
456 | 457 |
457 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 458 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { |
458 const DIEllipseEdgeEffect& eee = other.cast<DIEllipseEdgeEffect>(); | 459 const DIEllipseEdgeEffect& eee = other.cast<DIEllipseEdgeEffect>(); |
459 return eee.fMode == fMode; | 460 return eee.fMode == fMode; |
460 } | 461 } |
461 | 462 |
462 const GrShaderVar& fInEllipseOffsets0; | 463 const GrShaderVar& fInEllipseOffsets0; |
463 const GrShaderVar& fInEllipseOffsets1; | 464 const GrShaderVar& fInEllipseOffsets1; |
464 Mode fMode; | 465 Mode fMode; |
465 | 466 |
466 GR_DECLARE_EFFECT_TEST; | 467 GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
467 | 468 |
468 typedef GrGeometryProcessor INHERITED; | 469 typedef GrGeometryProcessor INHERITED; |
469 }; | 470 }; |
470 | 471 |
471 GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); | 472 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); |
472 | 473 |
473 GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, | 474 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, |
474 GrContext* context, | 475 GrContext* context, |
475 const GrDrawTargetCaps&, | 476 const GrDrawTargetCaps&, |
476 GrTexture* textures[]) { | 477 GrTexture* textures[]) { |
477 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); | 478 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); |
478 } | 479 } |
479 | 480 |
480 /////////////////////////////////////////////////////////////////////////////// | 481 /////////////////////////////////////////////////////////////////////////////// |
481 | 482 |
482 void GrOvalRenderer::reset() { | 483 void GrOvalRenderer::reset() { |
483 SkSafeSetNull(fRRectIndexBuffer); | 484 SkSafeSetNull(fRRectIndexBuffer); |
484 } | 485 } |
485 | 486 |
486 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
ol useAA, | 487 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
ol useAA, |
(...skipping 24 matching lines...) Expand all Loading... |
511 } | 512 } |
512 | 513 |
513 return true; | 514 return true; |
514 } | 515 } |
515 | 516 |
516 /////////////////////////////////////////////////////////////////////////////// | 517 /////////////////////////////////////////////////////////////////////////////// |
517 | 518 |
518 // position + edge | 519 // position + edge |
519 extern const GrVertexAttrib gCircleVertexAttribs[] = { | 520 extern const GrVertexAttrib gCircleVertexAttribs[] = { |
520 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, | 521 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, |
521 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding} | 522 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttr
ibBinding} |
522 }; | 523 }; |
523 | 524 |
524 void GrOvalRenderer::drawCircle(GrDrawTarget* target, | 525 void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
525 bool useCoverageAA, | 526 bool useCoverageAA, |
526 const SkRect& circle, | 527 const SkRect& circle, |
527 const SkStrokeRec& stroke) | 528 const SkStrokeRec& stroke) |
528 { | 529 { |
529 GrDrawState* drawState = target->drawState(); | 530 GrDrawState* drawState = target->drawState(); |
530 | 531 |
531 const SkMatrix& vm = drawState->getViewMatrix(); | 532 const SkMatrix& vm = drawState->getViewMatrix(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 } else { | 565 } else { |
565 halfWidth = SkScalarHalf(strokeWidth); | 566 halfWidth = SkScalarHalf(strokeWidth); |
566 } | 567 } |
567 | 568 |
568 outerRadius += halfWidth; | 569 outerRadius += halfWidth; |
569 if (isStrokeOnly) { | 570 if (isStrokeOnly) { |
570 innerRadius = radius - halfWidth; | 571 innerRadius = radius - halfWidth; |
571 } | 572 } |
572 } | 573 } |
573 | 574 |
574 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0)
; | 575 GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadi
us > 0); |
575 drawState->setGeometryProcessor(effect)->unref(); | 576 drawState->setGeometryProcessor(gp)->unref(); |
576 | 577 |
577 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform | 578 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform |
578 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use
d to compute the | 579 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is use
d to compute the |
579 // verts of the bounding box that is rendered and the outset ensures the box
will cover all | 580 // verts of the bounding box that is rendered and the outset ensures the box
will cover all |
580 // pixels partially covered by the circle. | 581 // pixels partially covered by the circle. |
581 outerRadius += SK_ScalarHalf; | 582 outerRadius += SK_ScalarHalf; |
582 innerRadius -= SK_ScalarHalf; | 583 innerRadius -= SK_ScalarHalf; |
583 | 584 |
584 SkRect bounds = SkRect::MakeLTRB( | 585 SkRect bounds = SkRect::MakeLTRB( |
585 center.fX - outerRadius, | 586 center.fX - outerRadius, |
(...skipping 23 matching lines...) Expand all Loading... |
609 verts[3].fInnerRadius = innerRadius; | 610 verts[3].fInnerRadius = innerRadius; |
610 | 611 |
611 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds); | 612 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds); |
612 } | 613 } |
613 | 614 |
614 /////////////////////////////////////////////////////////////////////////////// | 615 /////////////////////////////////////////////////////////////////////////////// |
615 | 616 |
616 // position + offset + 1/radii | 617 // position + offset + 1/radii |
617 extern const GrVertexAttrib gEllipseVertexAttribs[] = { | 618 extern const GrVertexAttrib gEllipseVertexAttribs[] = { |
618 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, | 619 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, |
619 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding
}, | 620 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, |
620 {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding
} | 621 {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding} |
621 }; | 622 }; |
622 | 623 |
623 // position + offsets | 624 // position + offsets |
624 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { | 625 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { |
625 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, | 626 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, |
626 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding
}, | 627 {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, |
627 {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding
}, | 628 {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAt
tribBinding}, |
628 }; | 629 }; |
629 | 630 |
630 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, | 631 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
631 bool useCoverageAA, | 632 bool useCoverageAA, |
632 const SkRect& ellipse, | 633 const SkRect& ellipse, |
633 const SkStrokeRec& stroke) | 634 const SkStrokeRec& stroke) |
634 { | 635 { |
635 GrDrawState* drawState = target->drawState(); | 636 GrDrawState* drawState = target->drawState(); |
636 #ifdef SK_DEBUG | 637 #ifdef SK_DEBUG |
637 { | 638 { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 sizeof(EllipseVertex)); | 704 sizeof(EllipseVertex)); |
704 | 705 |
705 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 706 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
706 if (!geo.succeeded()) { | 707 if (!geo.succeeded()) { |
707 GrPrintf("Failed to get space for vertices!\n"); | 708 GrPrintf("Failed to get space for vertices!\n"); |
708 return false; | 709 return false; |
709 } | 710 } |
710 | 711 |
711 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 712 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
712 | 713 |
713 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && | 714 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly && |
714 innerXRadius > 0 && innerYRadiu
s > 0); | 715 innerXRadius > 0 && inne
rYRadius > 0); |
715 | 716 |
716 drawState->setGeometryProcessor(effect)->unref(); | 717 drawState->setGeometryProcessor(gp)->unref(); |
717 | 718 |
718 // Compute the reciprocals of the radii here to save time in the shader | 719 // Compute the reciprocals of the radii here to save time in the shader |
719 SkScalar xRadRecip = SkScalarInvert(xRadius); | 720 SkScalar xRadRecip = SkScalarInvert(xRadius); |
720 SkScalar yRadRecip = SkScalarInvert(yRadius); | 721 SkScalar yRadRecip = SkScalarInvert(yRadius); |
721 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 722 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
722 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 723 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
723 | 724 |
724 // We've extended the outer x radius out half a pixel to antialias. | 725 // We've extended the outer x radius out half a pixel to antialias. |
725 // This will also expand the rect so all the pixels will be captured. | 726 // This will also expand the rect so all the pixels will be captured. |
726 // TODO: Consider if we should use sqrt(2)/2 instead | 727 // TODO: Consider if we should use sqrt(2)/2 instead |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 sizeof(DIEllipseVertex)
); | 821 sizeof(DIEllipseVertex)
); |
821 | 822 |
822 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 823 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); |
823 if (!geo.succeeded()) { | 824 if (!geo.succeeded()) { |
824 GrPrintf("Failed to get space for vertices!\n"); | 825 GrPrintf("Failed to get space for vertices!\n"); |
825 return false; | 826 return false; |
826 } | 827 } |
827 | 828 |
828 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); | 829 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); |
829 | 830 |
830 GrEffect* effect = DIEllipseEdgeEffect::Create(mode); | 831 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode); |
831 | 832 |
832 drawState->setGeometryProcessor(effect)->unref(); | 833 drawState->setGeometryProcessor(gp)->unref(); |
833 | 834 |
834 // This expands the outer rect so that after CTM we end up with a half-pixel
border | 835 // This expands the outer rect so that after CTM we end up with a half-pixel
border |
835 SkScalar a = vm[SkMatrix::kMScaleX]; | 836 SkScalar a = vm[SkMatrix::kMScaleX]; |
836 SkScalar b = vm[SkMatrix::kMSkewX]; | 837 SkScalar b = vm[SkMatrix::kMSkewX]; |
837 SkScalar c = vm[SkMatrix::kMSkewY]; | 838 SkScalar c = vm[SkMatrix::kMSkewY]; |
838 SkScalar d = vm[SkMatrix::kMScaleY]; | 839 SkScalar d = vm[SkMatrix::kMScaleY]; |
839 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); | 840 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); |
840 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); | 841 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); |
841 // This adjusts the "radius" to include the half-pixel border | 842 // This adjusts the "radius" to include the half-pixel border |
842 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); | 843 SkScalar offsetDx = SkScalarDiv(geoDx, xRadius); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 !target->getDrawState().getRenderTarget()->isMultisampled() &
& | 914 !target->getDrawState().getRenderTarget()->isMultisampled() &
& |
914 !target->shouldDisableCoverageAAForBlend(); | 915 !target->shouldDisableCoverageAAForBlend(); |
915 GrDrawState::AutoRestoreEffects are; | 916 GrDrawState::AutoRestoreEffects are; |
916 if (!origInner.isEmpty()) { | 917 if (!origInner.isEmpty()) { |
917 SkTCopyOnFirstWrite<SkRRect> inner(origInner); | 918 SkTCopyOnFirstWrite<SkRRect> inner(origInner); |
918 if (!context->getMatrix().isIdentity()) { | 919 if (!context->getMatrix().isIdentity()) { |
919 if (!origInner.transform(context->getMatrix(), inner.writable())) { | 920 if (!origInner.transform(context->getMatrix(), inner.writable())) { |
920 return false; | 921 return false; |
921 } | 922 } |
922 } | 923 } |
923 GrEffectEdgeType edgeType = applyAA ? kInverseFillAA_GrEffectEdgeType : | 924 GrProcessorEdgeType edgeType = applyAA ? |
924 kInverseFillBW_GrEffectEdgeType; | 925 kInverseFillAA_GrProcessorEdgeType : |
925 GrEffect* effect = GrRRectEffect::Create(edgeType, *inner); | 926 kInverseFillBW_GrProcessorEdgeType; |
926 if (NULL == effect) { | 927 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); |
| 928 if (NULL == fp) { |
927 return false; | 929 return false; |
928 } | 930 } |
929 are.set(target->drawState()); | 931 are.set(target->drawState()); |
930 target->drawState()->addCoverageEffect(effect)->unref(); | 932 target->drawState()->addCoverageProcessor(fp)->unref(); |
931 } | 933 } |
932 | 934 |
933 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 935 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
934 if (this->drawRRect(target, context, useAA, origOuter, fillRec)) { | 936 if (this->drawRRect(target, context, useAA, origOuter, fillRec)) { |
935 return true; | 937 return true; |
936 } | 938 } |
937 | 939 |
938 SkASSERT(!origOuter.isEmpty()); | 940 SkASSERT(!origOuter.isEmpty()); |
939 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); | 941 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); |
940 if (!context->getMatrix().isIdentity()) { | 942 if (!context->getMatrix().isIdentity()) { |
941 if (!origOuter.transform(context->getMatrix(), outer.writable())) { | 943 if (!origOuter.transform(context->getMatrix(), outer.writable())) { |
942 return false; | 944 return false; |
943 } | 945 } |
944 } | 946 } |
945 GrEffectEdgeType edgeType = applyAA ? kFillAA_GrEffectEdgeType : | 947 GrProcessorEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : |
946 kFillBW_GrEffectEdgeType; | 948 kFillBW_GrProcessorEdgeType; |
947 GrEffect* effect = GrRRectEffect::Create(edgeType, *outer); | 949 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); |
948 if (NULL == effect) { | 950 if (NULL == effect) { |
949 return false; | 951 return false; |
950 } | 952 } |
951 if (!are.isSet()) { | 953 if (!are.isSet()) { |
952 are.set(target->drawState()); | 954 are.set(target->drawState()); |
953 } | 955 } |
954 GrDrawState::AutoViewMatrixRestore avmr; | 956 GrDrawState::AutoViewMatrixRestore avmr; |
955 if (!avmr.setIdentity(target->drawState())) { | 957 if (!avmr.setIdentity(target->drawState())) { |
956 return false; | 958 return false; |
957 } | 959 } |
958 target->drawState()->addCoverageEffect(effect)->unref(); | 960 target->drawState()->addCoverageProcessor(effect)->unref(); |
959 SkRect bounds = outer->getBounds(); | 961 SkRect bounds = outer->getBounds(); |
960 if (applyAA) { | 962 if (applyAA) { |
961 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 963 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
962 } | 964 } |
963 target->drawRect(bounds, NULL, NULL); | 965 target->drawRect(bounds, NULL, NULL); |
964 return true; | 966 return true; |
965 } | 967 } |
966 | 968 |
967 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us
eAA, | 969 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us
eAA, |
968 const SkRRect& rrect, const SkStrokeRec& stroke)
{ | 970 const SkRRect& rrect, const SkStrokeRec& stroke)
{ |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 | 1070 |
1069 if (isStrokeOnly) { | 1071 if (isStrokeOnly) { |
1070 innerRadius = xRadius - halfWidth; | 1072 innerRadius = xRadius - halfWidth; |
1071 } | 1073 } |
1072 outerRadius += halfWidth; | 1074 outerRadius += halfWidth; |
1073 bounds.outset(halfWidth, halfWidth); | 1075 bounds.outset(halfWidth, halfWidth); |
1074 } | 1076 } |
1075 | 1077 |
1076 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); | 1078 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
1077 | 1079 |
1078 GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); | 1080 GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly); |
1079 drawState->setGeometryProcessor(effect)->unref(); | 1081 drawState->setGeometryProcessor(effect)->unref(); |
1080 | 1082 |
1081 // The radii are outset for two reasons. First, it allows the shader to
simply perform | 1083 // The radii are outset for two reasons. First, it allows the shader to
simply perform |
1082 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the | 1084 // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is
used to compute the |
1083 // verts of the bounding box that is rendered and the outset ensures the
box will cover all | 1085 // verts of the bounding box that is rendered and the outset ensures the
box will cover all |
1084 // pixels partially covered by the circle. | 1086 // pixels partially covered by the circle. |
1085 outerRadius += SK_ScalarHalf; | 1087 outerRadius += SK_ScalarHalf; |
1086 innerRadius -= SK_ScalarHalf; | 1088 innerRadius -= SK_ScalarHalf; |
1087 | 1089 |
1088 // Expand the rect so all the pixels will be captured. | 1090 // Expand the rect so all the pixels will be captured. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 | 1173 |
1172 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 1174 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
1173 | 1175 |
1174 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 1176 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
1175 if (!geo.succeeded()) { | 1177 if (!geo.succeeded()) { |
1176 GrPrintf("Failed to get space for vertices!\n"); | 1178 GrPrintf("Failed to get space for vertices!\n"); |
1177 return false; | 1179 return false; |
1178 } | 1180 } |
1179 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 1181 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
1180 | 1182 |
1181 GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); | 1183 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly); |
1182 drawState->setGeometryProcessor(effect)->unref(); | 1184 drawState->setGeometryProcessor(effect)->unref(); |
1183 | 1185 |
1184 // 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 |
1185 SkScalar xRadRecip = SkScalarInvert(xRadius); | 1187 SkScalar xRadRecip = SkScalarInvert(xRadius); |
1186 SkScalar yRadRecip = SkScalarInvert(yRadius); | 1188 SkScalar yRadRecip = SkScalarInvert(yRadius); |
1187 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); | 1189 SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius); |
1188 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); | 1190 SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius); |
1189 | 1191 |
1190 // Extend the radii out half a pixel to antialias. | 1192 // Extend the radii out half a pixel to antialias. |
1191 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; | 1193 SkScalar xOuterRadius = xRadius + SK_ScalarHalf; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 | 1237 |
1236 // drop out the middle quad if we're stroked | 1238 // drop out the middle quad if we're stroked |
1237 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1239 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
1238 SK_ARRAY_COUNT(gRRectIndices); | 1240 SK_ARRAY_COUNT(gRRectIndices); |
1239 target->setIndexSourceToBuffer(indexBuffer); | 1241 target->setIndexSourceToBuffer(indexBuffer); |
1240 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); | 1242 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); |
1241 } | 1243 } |
1242 | 1244 |
1243 return true; | 1245 return true; |
1244 } | 1246 } |
OLD | NEW |