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

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

Issue 193263002: Handle rrects with one circular corner and three square corners in GrRRectEffect. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebase on tot to land 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 | « gm/rrects.cpp ('k') | 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"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
OLDNEW
« no previous file with comments | « gm/rrects.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698