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 "GrRRectEffect.h" | 8 #include "GrRRectEffect.h" |
9 | 9 |
10 #include "gl/GrGLEffect.h" | 10 #include "gl/GrGLEffect.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 void GLRRectEffect::emitCode(GrGLShaderBuilder* builder, | 158 void GLRRectEffect::emitCode(GrGLShaderBuilder* builder, |
159 const GrDrawEffect& drawEffect, | 159 const GrDrawEffect& drawEffect, |
160 EffectKey key, | 160 EffectKey key, |
161 const char* outputColor, | 161 const char* outputColor, |
162 const char* inputColor, | 162 const char* inputColor, |
163 const TransformedCoordsArray&, | 163 const TransformedCoordsArray&, |
164 const TextureSamplerArray& samplers) { | 164 const TextureSamplerArray& samplers) { |
165 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); | 165 const RRectEffect& rre = drawEffect.castEffect<RRectEffect>(); |
166 const char *rectName; | 166 const char *rectName; |
167 const char *radiusPlusHalfName; | 167 const char *radiusPlusHalfName; |
168 // The inner rect is the rrect bounds inset by the radius. Its top, left, ri
ght, and bottom | 168 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom |
169 // edges correspond to components x, y, z, and w, respectively. When one sid
e of the rrect has | 169 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has |
170 // rectangular corners, that side's value corresponds to the rect edge's val
ue outset by half a | 170 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by |
171 // pixel. | 171 // half a pixel. |
172 fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil
ity, | 172 fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil
ity, |
173 kVec4f_GrSLType, | 173 kVec4f_GrSLType, |
174 "innerRect", | 174 "innerRect", |
175 &rectName); | 175 &rectName); |
176 fRadiusPlusHalfUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Vi
sibility, | 176 fRadiusPlusHalfUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Vi
sibility, |
177 kFloat_GrSLType, | 177 kFloat_GrSLType, |
178 "radiusPlusHalf", | 178 "radiusPlusHalf", |
179 &radiusPlusHalfName); | 179 &radiusPlusHalfName); |
180 const char* fragmentPos = builder->fragmentPosition(); | 180 const char* fragmentPos = builder->fragmentPosition(); |
181 // At each quarter-circle corner we compute a vector that is the offset of t
he fragment position | 181 // At each quarter-circle corner we compute a vector that is the offset of t
he fragment position |
(...skipping 12 matching lines...) Expand all Loading... |
194 // 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 |
195 // alphas together. | 195 // alphas together. |
196 switch (rre.getCircularCornerFlags()) { | 196 switch (rre.getCircularCornerFlags()) { |
197 case RRectEffect::kAll_CornerFlags: | 197 case RRectEffect::kAll_CornerFlags: |
198 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); |
199 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); |
200 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")
; |
201 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", |
202 radiusPlusHalfName); | 202 radiusPlusHalfName); |
203 break; | 203 break; |
| 204 case RRectEffect::kTopLeft_CornerFlag: |
| 205 builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
rectName, fragmentPos); |
| 206 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.
0, 1.0);\n", |
| 207 rectName, fragmentPos); |
| 208 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0
.0, 1.0);\n", |
| 209 rectName, fragmentPos); |
| 210 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha *
clamp(%s - length(dxy), 0.0, 1.0);\n", |
| 211 radiusPlusHalfName); |
| 212 break; |
| 213 case RRectEffect::kTopRight_CornerFlag: |
| 214 builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y -
%s.y), 0.0);\n", |
| 215 fragmentPos, rectName, rectName, fragmentPos)
; |
| 216 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0
, 1.0);\n", |
| 217 fragmentPos, rectName); |
| 218 builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0
.0, 1.0);\n", |
| 219 rectName, fragmentPos); |
| 220 builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha *
clamp(%s - length(dxy), 0.0, 1.0);\n", |
| 221 radiusPlusHalfName); |
| 222 break; |
| 223 case RRectEffect::kBottomRight_CornerFlag: |
| 224 builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n", |
| 225 fragmentPos, rectName); |
| 226 builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0
, 1.0);\n", |
| 227 fragmentPos, rectName); |
| 228 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", |
| 229 fragmentPos, rectName); |
| 230 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * cla
mp(%s - length(dxy), 0.0, 1.0);\n", |
| 231 radiusPlusHalfName); |
| 232 break; |
| 233 case RRectEffect::kBottomLeft_CornerFlag: |
| 234 builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y -
%s.w), 0.0);\n", |
| 235 rectName, fragmentPos, fragmentPos, rectName)
; |
| 236 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.
0, 1.0);\n", |
| 237 rectName, fragmentPos); |
| 238 builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", |
| 239 fragmentPos, rectName); |
| 240 builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * cl
amp(%s - length(dxy), 0.0, 1.0);\n", |
| 241 radiusPlusHalfName); |
| 242 break; |
204 case RRectEffect::kLeft_CornerFlags: | 243 case RRectEffect::kLeft_CornerFlags: |
205 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); | 244 builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName,
fragmentPos); |
206 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos
, rectName); | 245 builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos
, rectName); |
207 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d
y1)), 0.0);\n"); | 246 builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, d
y1)), 0.0);\n"); |
208 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.
0, 1.0);\n", | 247 builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.
0, 1.0);\n", |
209 rectName, fragmentPos); | 248 rectName, fragmentPos); |
210 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le
ngth(dxy), 0.0, 1.0);\n", | 249 builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - le
ngth(dxy), 0.0, 1.0);\n", |
211 radiusPlusHalfName); | 250 radiusPlusHalfName); |
212 break; | 251 break; |
213 case RRectEffect::kTop_CornerFlags: | 252 case RRectEffect::kTop_CornerFlags: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 if (rrect != fPrevRRect) { | 298 if (rrect != fPrevRRect) { |
260 SkRect rect = rrect.getBounds(); | 299 SkRect rect = rrect.getBounds(); |
261 SkScalar radius = 0; | 300 SkScalar radius = 0; |
262 switch (rre.getCircularCornerFlags()) { | 301 switch (rre.getCircularCornerFlags()) { |
263 case RRectEffect::kAll_CornerFlags: | 302 case RRectEffect::kAll_CornerFlags: |
264 SkASSERT(rrect.isSimpleCircular()); | 303 SkASSERT(rrect.isSimpleCircular()); |
265 radius = rrect.getSimpleRadii().fX; | 304 radius = rrect.getSimpleRadii().fX; |
266 SkASSERT(radius >= RRectEffect::kRadiusMin); | 305 SkASSERT(radius >= RRectEffect::kRadiusMin); |
267 rect.inset(radius, radius); | 306 rect.inset(radius, radius); |
268 break; | 307 break; |
| 308 case RRectEffect::kTopLeft_CornerFlag: |
| 309 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; |
| 310 rect.fLeft += radius; |
| 311 rect.fTop += radius; |
| 312 rect.fRight += 0.5f; |
| 313 rect.fBottom += 0.5f; |
| 314 break; |
| 315 case RRectEffect::kTopRight_CornerFlag: |
| 316 radius = rrect.radii(SkRRect::kUpperRight_Corner).fX; |
| 317 rect.fLeft -= 0.5; |
| 318 rect.fTop += radius; |
| 319 rect.fRight -= radius; |
| 320 rect.fBottom += 0.5f; |
| 321 break; |
| 322 case RRectEffect::kBottomRight_CornerFlag: |
| 323 radius = rrect.radii(SkRRect::kLowerRight_Corner).fX; |
| 324 rect.fLeft -= 0.5; |
| 325 rect.fTop -= 0.5; |
| 326 rect.fRight -= radius; |
| 327 rect.fBottom -= radius; |
| 328 break; |
| 329 case RRectEffect::kBottomLeft_CornerFlag: |
| 330 radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX; |
| 331 rect.fLeft += radius; |
| 332 rect.fTop -= 0.5; |
| 333 rect.fRight += 0.5; |
| 334 rect.fBottom -= radius; |
| 335 break; |
269 case RRectEffect::kLeft_CornerFlags: | 336 case RRectEffect::kLeft_CornerFlags: |
270 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; | 337 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; |
271 rect.fLeft += radius; | 338 rect.fLeft += radius; |
272 rect.fTop += radius; | 339 rect.fTop += radius; |
273 rect.fRight += 0.5f; | 340 rect.fRight += 0.5f; |
274 rect.fBottom -= radius; | 341 rect.fBottom -= radius; |
275 break; | 342 break; |
276 case RRectEffect::kTop_CornerFlags: | 343 case RRectEffect::kTop_CornerFlags: |
277 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; | 344 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; |
278 rect.fLeft += radius; | 345 rect.fLeft += radius; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 cornerFlags = 1 << c; | 403 cornerFlags = 1 << c; |
337 } else { | 404 } else { |
338 if (r.fX != radius) { | 405 if (r.fX != radius) { |
339 return NULL; | 406 return NULL; |
340 } | 407 } |
341 cornerFlags |= 1 << c; | 408 cornerFlags |= 1 << c; |
342 } | 409 } |
343 } | 410 } |
344 | 411 |
345 switch (cornerFlags) { | 412 switch (cornerFlags) { |
| 413 case RRectEffect::kTopLeft_CornerFlag: |
| 414 case RRectEffect::kTopRight_CornerFlag: |
| 415 case RRectEffect::kBottomRight_CornerFlag: |
| 416 case RRectEffect::kBottomLeft_CornerFlag: |
346 case RRectEffect::kLeft_CornerFlags: | 417 case RRectEffect::kLeft_CornerFlags: |
347 case RRectEffect::kTop_CornerFlags: | 418 case RRectEffect::kTop_CornerFlags: |
348 case RRectEffect::kRight_CornerFlags: | 419 case RRectEffect::kRight_CornerFlags: |
349 case RRectEffect::kBottom_CornerFlags: | 420 case RRectEffect::kBottom_CornerFlags: |
350 case RRectEffect::kAll_CornerFlags: | 421 case RRectEffect::kAll_CornerFlags: |
351 break; | 422 break; |
352 default: | 423 default: |
353 return NULL; | 424 return NULL; |
354 } | 425 } |
355 } else { | 426 } else { |
356 return NULL; | 427 return NULL; |
357 } | 428 } |
358 return RRectEffect::Create(edgeType, cornerFlags, rrect); | 429 return RRectEffect::Create(edgeType, cornerFlags, rrect); |
359 } | 430 } |
OLD | NEW |