OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |