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

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

Issue 191613003: Use bitfield rather than distinct enum types for circular corners in RRectEffect. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: change order Created 6 years, 9 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 | no next file » | 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 "GrRRectEffect.h" 8 #include "GrRRectEffect.h"
9 9
10 #include "gl/GrGLEffect.h" 10 #include "gl/GrGLEffect.h"
11 #include "gl/GrGLSL.h" 11 #include "gl/GrGLSL.h"
12 #include "GrTBackendEffectFactory.h" 12 #include "GrTBackendEffectFactory.h"
13 13
14 #include "SkRRect.h" 14 #include "SkRRect.h"
15 15
16 using namespace GrRRectEffect; 16 using namespace GrRRectEffect;
17 17
18 class GLRRectEffect; 18 class GLRRectEffect;
19 19
20 class RRectEffect : public GrEffect { 20 class RRectEffect : public GrEffect {
21 public: 21 public:
22 // This effect only supports circular corner rrects where the radius is >= k RadiusMin. 22 // This effect only supports circular corner rrects where the radius is >= k RadiusMin.
23 static const SkScalar kRadiusMin; 23 static const SkScalar kRadiusMin;
24 24
25 /// The types of circular corner rrects supported 25 enum CornerFlags {
26 enum RRectType { 26 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner),
27 kCircleCorner_RRectType, //<! All four corners have the same circula r radius. 27 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner),
28 kLeftCircleTab_RRectType, //<! The left side has circular corners, th e right is a rect. 28 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner),
29 kTopCircleTab_RRectType, //<! etc 29 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner),
30 kRightCircleTab_RRectType, 30
31 kBottomCircleTab_RRectType, 31 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag,
32 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag,
33 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag,
34 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag,
35
36 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag |
37 kBottomLeft_CornerFlag | kBottomRight_CornerFlag,
38
32 }; 39 };
33 40
34 static GrEffectRef* Create(GrEffectEdgeType, RRectType, const SkRRect&); 41 // The flags are used to indicate which corners are circluar (unflagged corn ers are assumed to
42 // be square).
43 static GrEffectRef* Create(GrEffectEdgeType, uint32_t circularCornerFlags, c onst SkRRect&);
35 44
36 virtual ~RRectEffect() {}; 45 virtual ~RRectEffect() {};
37 static const char* Name() { return "RRect"; } 46 static const char* Name() { return "RRect"; }
38 47
39 const SkRRect& getRRect() const { return fRRect; } 48 const SkRRect& getRRect() const { return fRRect; }
40 49
41 RRectType getType() const { return fRRectType; } 50 uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; }
42 51
43 GrEffectEdgeType getEdgeType() const { return fEdgeType; } 52 GrEffectEdgeType getEdgeType() const { return fEdgeType; }
44 53
45 typedef GLRRectEffect GLEffect; 54 typedef GLRRectEffect GLEffect;
46 55
47 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; 56 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE;
48 57
49 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 58 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
50 59
51 private: 60 private:
52 RRectEffect(GrEffectEdgeType, RRectType, const SkRRect&); 61 RRectEffect(GrEffectEdgeType, uint32_t circularCornerFlags, const SkRRect&);
53 62
54 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; 63 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
55 64
56 SkRRect fRRect; 65 SkRRect fRRect;
57 GrEffectEdgeType fEdgeType; 66 GrEffectEdgeType fEdgeType;
58 RRectType fRRectType; 67 uint32_t fCircularCornerFlags;
59 68
60 GR_DECLARE_EFFECT_TEST; 69 GR_DECLARE_EFFECT_TEST;
61 70
62 typedef GrEffect INHERITED; 71 typedef GrEffect INHERITED;
63 }; 72 };
64 73
65 const SkScalar RRectEffect::kRadiusMin = 0.5f; 74 const SkScalar RRectEffect::kRadiusMin = 0.5f;
66 75
67 GrEffectRef* RRectEffect::Create(GrEffectEdgeType edgeType, 76 GrEffectRef* RRectEffect::Create(GrEffectEdgeType edgeType,
68 RRectType rrType, 77 uint32_t circularCornerFlags,
69 const SkRRect& rrect) { 78 const SkRRect& rrect) {
70 SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdge Type == edgeType); 79 SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdge Type == edgeType);
71 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(RRectEffect, (edgeType, rr Type, rrect)))); 80 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(RRectEffect,
81 (edgeType, circularCornerF lags, rrect))));
72 } 82 }
73 83
74 void RRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlag s) const { 84 void RRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlag s) const {
75 *validFlags = 0; 85 *validFlags = 0;
76 } 86 }
77 87
78 const GrBackendEffectFactory& RRectEffect::getFactory() const { 88 const GrBackendEffectFactory& RRectEffect::getFactory() const {
79 return GrTBackendEffectFactory<RRectEffect>::getInstance(); 89 return GrTBackendEffectFactory<RRectEffect>::getInstance();
80 } 90 }
81 91
82 RRectEffect::RRectEffect(GrEffectEdgeType edgeType, RRectType rrType, const SkRR ect& rrect) 92 RRectEffect::RRectEffect(GrEffectEdgeType edgeType, uint32_t circularCornerFlags ,
93 const SkRRect& rrect)
83 : fRRect(rrect) 94 : fRRect(rrect)
84 , fEdgeType(edgeType) 95 , fEdgeType(edgeType)
85 , fRRectType(rrType) { 96 , fCircularCornerFlags(circularCornerFlags) {
86 this->setWillReadFragmentPosition(); 97 this->setWillReadFragmentPosition();
87 } 98 }
88 99
89 bool RRectEffect::onIsEqual(const GrEffect& other) const { 100 bool RRectEffect::onIsEqual(const GrEffect& other) const {
90 const RRectEffect& rre = CastEffect<RRectEffect>(other); 101 const RRectEffect& rre = CastEffect<RRectEffect>(other);
91 // type is derived from fRRect, so no need to check it. 102 // type is derived from fRRect, so no need to check it.
92 return fEdgeType == rre.fEdgeType && fRRect == rre.fRRect; 103 return fEdgeType == rre.fEdgeType && fRRect == rre.fRRect;
93 } 104 }
94 105
95 ////////////////////////////////////////////////////////////////////////////// 106 //////////////////////////////////////////////////////////////////////////////
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 // fragments near the other three edges will get the correct AA. Fragments i n the interior of 186 // fragments near the other three edges will get the correct AA. Fragments i n the interior of
176 // the rrect will have a (0,0) vector at all four corners. So long as the ra dius > 0.5 they will 187 // the rrect will have a (0,0) vector at all four corners. So long as the ra dius > 0.5 they will
177 // correctly produce an alpha value of 1 at all four corners. We take the mi n of all the alphas. 188 // correctly produce an alpha value of 1 at all four corners. We take the mi n of all the alphas.
178 // The code below is a simplified version of the above that performs maxs on the vector 189 // The code below is a simplified version of the above that performs maxs on the vector
179 // components before computing distances and alpha values so that only one d istance computation 190 // components before computing distances and alpha values so that only one d istance computation
180 // need be computed to determine the min alpha. 191 // need be computed to determine the min alpha.
181 // 192 //
182 // For the cases where one half of the rrect is rectangular we drop one of t he x or y 193 // For the cases where one half of the rrect is rectangular we drop one of t he x or y
183 // computations, compute a separate rect edge alpha for the rect side, and m ul the two computed 194 // computations, compute a separate rect edge alpha for the rect side, and m ul the two computed
184 // alphas together. 195 // alphas together.
185 switch (rre.getType()) { 196 switch (rre.getCircularCornerFlags()) {
186 case RRectEffect::kCircleCorner_RRectType: 197 case RRectEffect::kAll_CornerFlags:
187 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); 198 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
188 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName); 199 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName);
189 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ; 200 builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n") ;
190 builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0. 0, 1.0);\n", 201 builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0. 0, 1.0);\n",
191 radiusPlusHalfName); 202 radiusPlusHalfName);
192 break; 203 break;
193 case RRectEffect::kLeftCircleTab_RRectType: 204 case RRectEffect::kLeft_CornerFlags:
194 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); 205 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
195 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos , rectName); 206 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos , rectName);
196 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d y1)), 0.0);\n"); 207 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d y1)), 0.0);\n");
197 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n", 208 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0. 0, 1.0);\n",
198 rectName, fragmentPos); 209 rectName, fragmentPos);
199 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le ngth(dxy), 0.0, 1.0);\n", 210 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le ngth(dxy), 0.0, 1.0);\n",
200 radiusPlusHalfName); 211 radiusPlusHalfName);
201 break; 212 break;
202 case RRectEffect::kTopCircleTab_RRectType: 213 case RRectEffect::kTop_CornerFlags:
203 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); 214 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
204 builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos , rectName); 215 builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos , rectName);
205 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy 0.y), 0.0);\n"); 216 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy 0.y), 0.0);\n");
206 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n", 217 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0 .0, 1.0);\n",
207 rectName, fragmentPos); 218 rectName, fragmentPos);
208 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - l ength(dxy), 0.0, 1.0);\n", 219 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - l ength(dxy), 0.0, 1.0);\n",
209 radiusPlusHalfName); 220 radiusPlusHalfName);
210 break; 221 break;
211 case RRectEffect::kRightCircleTab_RRectType: 222 case RRectEffect::kRight_CornerFlags:
212 builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, f ragmentPos); 223 builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, f ragmentPos);
213 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName); 224 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName);
214 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1 .y)), 0.0);\n"); 225 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1 .y)), 0.0);\n");
215 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n", 226 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0 , 1.0);\n",
216 fragmentPos, rectName); 227 fragmentPos, rectName);
217 builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - len gth(dxy), 0.0, 1.0);\n", 228 builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - len gth(dxy), 0.0, 1.0);\n",
218 radiusPlusHalfName); 229 radiusPlusHalfName);
219 break; 230 break;
220 case RRectEffect::kBottomCircleTab_RRectType: 231 case RRectEffect::kBottom_CornerFlags:
221 builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f ragmentPos); 232 builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f ragmentPos);
222 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName); 233 builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP os, rectName);
223 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy 1.y), 0.0);\n"); 234 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy 1.y), 0.0);\n");
224 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", 235 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
225 fragmentPos, rectName); 236 fragmentPos, rectName);
226 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng th(dxy), 0.0, 1.0);\n", 237 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng th(dxy), 0.0, 1.0);\n",
227 radiusPlusHalfName); 238 radiusPlusHalfName);
228 break; 239 break;
229 } 240 }
230 241
231 if (kInverseFillAA_GrEffectEdgeType == rre.getEdgeType()) { 242 if (kInverseFillAA_GrEffectEdgeType == rre.getEdgeType()) {
232 builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n"); 243 builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n");
233 } 244 }
234 245
235 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, 246 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor,
236 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); 247 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r());
237 } 248 }
238 249
239 GrGLEffect::EffectKey GLRRectEffect::GenKey(const GrDrawEffect& drawEffect, cons t GrGLCaps&) { 250 GrGLEffect::EffectKey GLRRectEffect::GenKey(const GrDrawEffect& drawEffect, cons t GrGLCaps&) {
240 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); 251 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>();
241 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); 252 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8);
242 return (rre.getType() << 3) | rre.getEdgeType(); 253 return (rre.getCircularCornerFlags() << 3) | rre.getEdgeType();
243 } 254 }
244 255
245 void GLRRectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { 256 void GLRRectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
246 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); 257 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>();
247 const SkRRect& rrect = rre.getRRect(); 258 const SkRRect& rrect = rre.getRRect();
248 if (rrect != fPrevRRect) { 259 if (rrect != fPrevRRect) {
249 SkRect rect = rrect.getBounds(); 260 SkRect rect = rrect.getBounds();
250 SkScalar radius = 0; 261 SkScalar radius = 0;
251 switch (rre.getType()) { 262 switch (rre.getCircularCornerFlags()) {
252 case RRectEffect::kCircleCorner_RRectType: 263 case RRectEffect::kAll_CornerFlags:
253 SkASSERT(rrect.isSimpleCircular()); 264 SkASSERT(rrect.isSimpleCircular());
254 radius = rrect.getSimpleRadii().fX; 265 radius = rrect.getSimpleRadii().fX;
255 SkASSERT(radius >= RRectEffect::kRadiusMin); 266 SkASSERT(radius >= RRectEffect::kRadiusMin);
256 rect.inset(radius, radius); 267 rect.inset(radius, radius);
257 break; 268 break;
258 case RRectEffect::kLeftCircleTab_RRectType: 269 case RRectEffect::kLeft_CornerFlags:
259 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; 270 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
260 rect.fLeft += radius; 271 rect.fLeft += radius;
261 rect.fTop += radius; 272 rect.fTop += radius;
262 rect.fRight += 0.5f; 273 rect.fRight += 0.5f;
263 rect.fBottom -= radius; 274 rect.fBottom -= radius;
264 break; 275 break;
265 case RRectEffect::kTopCircleTab_RRectType: 276 case RRectEffect::kTop_CornerFlags:
266 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; 277 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX;
267 rect.fLeft += radius; 278 rect.fLeft += radius;
268 rect.fTop += radius; 279 rect.fTop += radius;
269 rect.fRight -= radius; 280 rect.fRight -= radius;
270 rect.fBottom += 0.5f; 281 rect.fBottom += 0.5f;
271 break; 282 break;
272 case RRectEffect::kRightCircleTab_RRectType: 283 case RRectEffect::kRight_CornerFlags:
273 radius = rrect.radii(SkRRect::kUpperRight_Corner).fX; 284 radius = rrect.radii(SkRRect::kUpperRight_Corner).fX;
274 rect.fLeft -= 0.5f; 285 rect.fLeft -= 0.5f;
275 rect.fTop += radius; 286 rect.fTop += radius;
276 rect.fRight -= radius; 287 rect.fRight -= radius;
277 rect.fBottom -= radius; 288 rect.fBottom -= radius;
278 break; 289 break;
279 case RRectEffect::kBottomCircleTab_RRectType: 290 case RRectEffect::kBottom_CornerFlags:
280 radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX; 291 radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX;
281 rect.fLeft += radius; 292 rect.fLeft += radius;
282 rect.fTop -= 0.5f; 293 rect.fTop -= 0.5f;
283 rect.fRight -= radius; 294 rect.fRight -= radius;
284 rect.fBottom -= radius; 295 rect.fBottom -= radius;
285 break; 296 break;
297 default:
298 GrCrash("Should have been one of the above cases.");
286 } 299 }
287 uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.f Bottom); 300 uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.f Bottom);
288 uman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); 301 uman.set1f(fRadiusPlusHalfUniform, radius + 0.5f);
289 fPrevRRect = rrect; 302 fPrevRRect = rrect;
290 } 303 }
291 } 304 }
292 305
293 ////////////////////////////////////////////////////////////////////////////// 306 //////////////////////////////////////////////////////////////////////////////
294 307
295 GrEffectRef* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rre ct) { 308 GrEffectRef* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rre ct) {
296 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType != edgeType) { 309 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType != edgeType) {
297 return NULL; 310 return NULL;
298 } 311 }
299 RRectEffect::RRectType rrtype; 312 uint32_t cornerFlags;
300 if (rrect.isSimpleCircular()) { 313 if (rrect.isSimpleCircular()) {
301 if (rrect.getSimpleRadii().fX < RRectEffect::kRadiusMin) { 314 if (rrect.getSimpleRadii().fX < RRectEffect::kRadiusMin) {
302 return NULL; 315 return NULL;
303 } 316 }
304 rrtype = RRectEffect::kCircleCorner_RRectType; 317 cornerFlags = RRectEffect::kAll_CornerFlags;
305 } else if (rrect.isComplex()) { 318 } else if (rrect.isComplex()) {
306 // Check for the "tab" cases - two adjacent circular corners and two squ are corners. 319 // Check for the "tab" cases - two adjacent circular corners and two squ are corners.
307 SkScalar radius = 0; 320 SkScalar radius = 0;
308 int circleCornerBitfield = 0; 321 cornerFlags = 0;
309 for (int c = 0; c < 4; ++c) { 322 for (int c = 0; c < 4; ++c) {
310 const SkVector& r = rrect.radii((SkRRect::Corner)c); 323 const SkVector& r = rrect.radii((SkRRect::Corner)c);
311 SkASSERT((0 == r.fX) == (0 == r.fY)); 324 SkASSERT((0 == r.fX) == (0 == r.fY));
312 if (0 == r.fX) { 325 if (0 == r.fX) {
313 continue; 326 continue;
314 } 327 }
315 if (r.fX != r.fY) { 328 if (r.fX != r.fY) {
316 return NULL; 329 return NULL;
317 } 330 }
318 if (!circleCornerBitfield) { 331 if (!cornerFlags) {
319 radius = r.fX; 332 radius = r.fX;
320 if (radius < RRectEffect::kRadiusMin) { 333 if (radius < RRectEffect::kRadiusMin) {
321 return NULL; 334 return NULL;
322 } 335 }
323 circleCornerBitfield = 1 << c; 336 cornerFlags = 1 << c;
324 } else { 337 } else {
325 if (r.fX != radius) { 338 if (r.fX != radius) {
326 return NULL; 339 return NULL;
327 } 340 }
328 circleCornerBitfield |= 1 << c; 341 cornerFlags |= 1 << c;
329 } 342 }
330 } 343 }
331 344
332 GR_STATIC_ASSERT(SkRRect::kUpperLeft_Corner == 0); 345 switch (cornerFlags) {
333 GR_STATIC_ASSERT(SkRRect::kUpperRight_Corner == 1); 346 case RRectEffect::kLeft_CornerFlags:
334 GR_STATIC_ASSERT(SkRRect::kLowerRight_Corner == 2); 347 case RRectEffect::kTop_CornerFlags:
335 GR_STATIC_ASSERT(SkRRect::kLowerLeft_Corner == 3); 348 case RRectEffect::kRight_CornerFlags:
336 switch (circleCornerBitfield) { 349 case RRectEffect::kBottom_CornerFlags:
337 case 3: 350 case RRectEffect::kAll_CornerFlags:
338 rrtype = RRectEffect::kTopCircleTab_RRectType;
339 break;
340 case 6:
341 rrtype = RRectEffect::kRightCircleTab_RRectType;
342 break;
343 case 9:
344 rrtype = RRectEffect::kLeftCircleTab_RRectType;
345 break;
346 case 12:
347 rrtype = RRectEffect::kBottomCircleTab_RRectType;
348 break; 351 break;
349 default: 352 default:
350 return NULL; 353 return NULL;
351 } 354 }
352 } else { 355 } else {
353 return NULL; 356 return NULL;
354 } 357 }
355 return RRectEffect::Create(edgeType, rrtype, rrect); 358 return RRectEffect::Create(edgeType, cornerFlags, rrect);
356 } 359 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698