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) ; | |
jvanverth1
2014/03/11 14:53:23
I suppose it doesn't matter because you're taking
bsalomon
2014/03/11 15:11:04
Yup, it's a bit weird. It's done that way so that
| |
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 |