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

Side by Side Diff: src/gpu/effects/GrOvalEffect.cpp

Issue 218583013: Add effect for ellipse clipping. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/gpu/effects/GrRRectEffect.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 "GrOvalEffect.h" 8 #include "GrOvalEffect.h"
9 9
10 #include "gl/GrGLEffect.h" 10 #include "gl/GrGLEffect.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 } 66 }
67 67
68 CircleEffect::CircleEffect(GrEffectEdgeType edgeType, const SkPoint& c, SkScalar r) 68 CircleEffect::CircleEffect(GrEffectEdgeType edgeType, const SkPoint& c, SkScalar r)
69 : fCenter(c) 69 : fCenter(c)
70 , fRadius(r) 70 , fRadius(r)
71 , fEdgeType(edgeType) { 71 , fEdgeType(edgeType) {
72 this->setWillReadFragmentPosition(); 72 this->setWillReadFragmentPosition();
73 } 73 }
74 74
75 bool CircleEffect::onIsEqual(const GrEffect& other) const { 75 bool CircleEffect::onIsEqual(const GrEffect& other) const {
76 const CircleEffect& crre = CastEffect<CircleEffect>(other); 76 const CircleEffect& ce = CastEffect<CircleEffect>(other);
77 return fEdgeType == crre.fEdgeType && fCenter == crre.fCenter && fRadius == crre.fRadius; 77 return fEdgeType == ce.fEdgeType && fCenter == ce.fCenter && fRadius == ce.f Radius;
78 } 78 }
79 79
80 ////////////////////////////////////////////////////////////////////////////// 80 //////////////////////////////////////////////////////////////////////////////
81 81
82 GR_DEFINE_EFFECT_TEST(CircleEffect); 82 GR_DEFINE_EFFECT_TEST(CircleEffect);
83 83
84 GrEffectRef* CircleEffect::TestCreate(SkRandom* random, 84 GrEffectRef* CircleEffect::TestCreate(SkRandom* random,
85 GrContext*, 85 GrContext*,
86 const GrDrawTargetCaps& caps, 86 const GrDrawTargetCaps& caps,
87 GrTexture*[]) { 87 GrTexture*[]) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 169 }
170 170
171 void GLCircleEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { 171 void GLCircleEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
172 const CircleEffect& ce = drawEffect.castEffect<CircleEffect>(); 172 const CircleEffect& ce = drawEffect.castEffect<CircleEffect>();
173 if (ce.getRadius() != fPrevRadius || ce.getCenter() != fPrevCenter) { 173 if (ce.getRadius() != fPrevRadius || ce.getCenter() != fPrevCenter) {
174 uman.set3f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, ce.getR adius() + 0.5f); 174 uman.set3f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, ce.getR adius() + 0.5f);
175 fPrevCenter = ce.getCenter(); 175 fPrevCenter = ce.getCenter();
176 fPrevRadius = ce.getRadius(); 176 fPrevRadius = ce.getRadius();
177 } 177 }
178 } 178 }
179
180 //////////////////////////////////////////////////////////////////////////////
181
182 class GLEllipseEffect;
183
184 class EllipseEffect : public GrEffect {
185 public:
186 static GrEffectRef* Create(GrEffectEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
187
188 virtual ~EllipseEffect() {};
189 static const char* Name() { return "Ellipse"; }
190
191 const SkPoint& getCenter() const { return fCenter; }
192 SkVector getRadii() const { return fRadii; }
193
194 GrEffectEdgeType getEdgeType() const { return fEdgeType; }
195
196 typedef GLEllipseEffect GLEffect;
197
198 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE;
199
200 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
201
202 private:
203 EllipseEffect(GrEffectEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
204
205 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
206
207 SkPoint fCenter;
208 SkVector fRadii;
209 GrEffectEdgeType fEdgeType;
210
211 GR_DECLARE_EFFECT_TEST;
212
213 typedef GrEffect INHERITED;
214 };
215
216 GrEffectRef* EllipseEffect::Create(GrEffectEdgeType edgeType,
217 const SkPoint& center,
218 SkScalar rx,
219 SkScalar ry) {
220 SkASSERT(rx >= 0 && ry >= 0);
221 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEffect,
222 (edgeType, center, rx, ry) )));
223 }
224
225 void EllipseEffect::getConstantColorComponents(GrColor* color, uint32_t* validFl ags) const {
226 *validFlags = 0;
227 }
228
229 const GrBackendEffectFactory& EllipseEffect::getFactory() const {
230 return GrTBackendEffectFactory<EllipseEffect>::getInstance();
231 }
232
233 EllipseEffect::EllipseEffect(GrEffectEdgeType edgeType, const SkPoint& c, SkScal ar rx, SkScalar ry)
234 : fCenter(c)
235 , fRadii(SkVector::Make(rx, ry))
236 , fEdgeType(edgeType) {
237 this->setWillReadFragmentPosition();
238 }
239
240 bool EllipseEffect::onIsEqual(const GrEffect& other) const {
241 const EllipseEffect& ee = CastEffect<EllipseEffect>(other);
242 return fEdgeType == ee.fEdgeType && fCenter == ee.fCenter && fRadii == ee.fR adii;
243 }
244
245 //////////////////////////////////////////////////////////////////////////////
246
247 GR_DEFINE_EFFECT_TEST(EllipseEffect);
248
249 GrEffectRef* EllipseEffect::TestCreate(SkRandom* random,
250 GrContext*,
251 const GrDrawTargetCaps& caps,
252 GrTexture*[]) {
253 SkPoint center;
254 center.fX = random->nextRangeScalar(0.f, 1000.f);
255 center.fY = random->nextRangeScalar(0.f, 1000.f);
256 SkScalar rx = random->nextRangeF(0.f, 1000.f);
257 SkScalar ry = random->nextRangeF(0.f, 1000.f);
258 GrEffectEdgeType et;
259 do {
260 et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt);
261 } while (kHairlineAA_GrEffectEdgeType == et);
262 return EllipseEffect::Create(et, center, rx, ry);
263 }
264
265 //////////////////////////////////////////////////////////////////////////////
266
267 class GLEllipseEffect : public GrGLEffect {
268 public:
269 GLEllipseEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
270
271 virtual void emitCode(GrGLShaderBuilder* builder,
272 const GrDrawEffect& drawEffect,
273 EffectKey key,
274 const char* outputColor,
275 const char* inputColor,
276 const TransformedCoordsArray&,
277 const TextureSamplerArray&) SK_OVERRIDE;
278
279 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
280
281 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
282
283 private:
284 GrGLUniformManager::UniformHandle fEllipseUniform;
285 SkPoint fPrevCenter;
286 SkVector fPrevRadii;
287
288 typedef GrGLEffect INHERITED;
289 };
290
291 GLEllipseEffect::GLEllipseEffect(const GrBackendEffectFactory& factory,
292 const GrDrawEffect& drawEffect)
293 : INHERITED (factory) {
294 fPrevRadii.fX = -1.f;
295 }
296
297 void GLEllipseEffect::emitCode(GrGLShaderBuilder* builder,
298 const GrDrawEffect& drawEffect,
299 EffectKey key,
300 const char* outputColor,
301 const char* inputColor,
302 const TransformedCoordsArray&,
303 const TextureSamplerArray& samplers) {
304 const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
305 const char *ellipseName;
306 // The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2)
307 fEllipseUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibilit y,
308 kVec4f_GrSLType,
309 "ellipse",
310 &ellipseName);
311 const char* fragmentPos = builder->fragmentPosition();
312
313 // d is the offset to the ellipse center
314 builder->fsCodeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipse Name);
315 builder->fsCodeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
316 // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
317 builder->fsCodeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
318 // grad_dot is the squared length of the gradient of the implicit.
319 builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
320 if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
321 builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
322 }
323 builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_ dot);\n");
324
325 switch (ee.getEdgeType()) {
326 case kFillAA_GrEffectEdgeType:
327 builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0. 0, 1.0);\n");
328 break;
329 case kInverseFillAA_GrEffectEdgeType:
330 builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0. 0, 1.0);\n");
331 break;
332 case kFillBW_GrEffectEdgeType:
333 builder->fsCodeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1 .0;\n");
334 break;
335 case kInverseFillBW_GrEffectEdgeType:
336 builder->fsCodeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0 .0;\n");
337 break;
338 case kHairlineAA_GrEffectEdgeType:
339 GrCrash("Hairline not expected here.");
340 }
341
342 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
343 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
344 }
345
346 GrGLEffect::EffectKey GLEllipseEffect::GenKey(const GrDrawEffect& drawEffect,
347 const GrGLCaps&) {
348 const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
349 return ee.getEdgeType();
350 }
351
352 void GLEllipseEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect & drawEffect) {
353 const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
354 if (ee.getRadii() != fPrevRadii || ee.getCenter() != fPrevCenter) {
355 SkScalar invRXSqd = 1.f / (ee.getRadii().fX * ee.getRadii().fX);
356 SkScalar invRYSqd = 1.f / (ee.getRadii().fY * ee.getRadii().fY);
357 uman.set4f(fEllipseUniform, ee.getCenter().fX, ee.getCenter().fY, invRXS qd, invRYSqd);
358 fPrevCenter = ee.getCenter();
359 fPrevRadii = ee.getRadii();
360 }
361 }
362
179 ////////////////////////////////////////////////////////////////////////////// 363 //////////////////////////////////////////////////////////////////////////////
180 364
181 GrEffectRef* GrOvalEffect::Create(GrEffectEdgeType edgeType, const SkRect& oval) { 365 GrEffectRef* GrOvalEffect::Create(GrEffectEdgeType edgeType, const SkRect& oval) {
182 if (kHairlineAA_GrEffectEdgeType == edgeType) { 366 if (kHairlineAA_GrEffectEdgeType == edgeType) {
183 return NULL; 367 return NULL;
184 } 368 }
185 SkScalar w = oval.width(); 369 SkScalar w = oval.width();
186 SkScalar h = oval.height(); 370 SkScalar h = oval.height();
187 if (SkScalarNearlyEqual(w, h)) { 371 if (SkScalarNearlyEqual(w, h)) {
188 w /= 2; 372 w /= 2;
189 return CircleEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, oval .fTop + w), w); 373 return CircleEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, oval .fTop + w), w);
374 } else {
375 w /= 2;
376 h /= 2;
377 return EllipseEffect::Create(edgeType, SkPoint::Make(oval.fLeft + w, ova l.fTop + h), w, h);
190 } 378 }
191 379
192 return NULL; 380 return NULL;
193 } 381 }
OLDNEW
« no previous file with comments | « no previous file | src/gpu/effects/GrRRectEffect.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698