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

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 15039016: Fix stroked roundrects on Nexus 10 (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 7 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 2013 Google Inc. 2 * Copyright 2013 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 "GrOvalRenderer.h" 8 #include "GrOvalRenderer.h"
9 9
10 #include "GrEffect.h" 10 #include "GrEffect.h"
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 GrContext* context, 280 GrContext* context,
281 const GrDrawTargetCaps&, 281 const GrDrawTargetCaps&,
282 GrTexture* textures[]) { 282 GrTexture* textures[]) {
283 return EllipseEdgeEffect::Create(random->nextBool()); 283 return EllipseEdgeEffect::Create(random->nextBool());
284 } 284 }
285 285
286 /////////////////////////////////////////////////////////////////////////////// 286 ///////////////////////////////////////////////////////////////////////////////
287 287
288 /** 288 /**
289 * The output of this effect is a modulation of the input color and coverage for an axis-aligned 289 * The output of this effect is a modulation of the input color and coverage for an axis-aligned
290 * ellipse, specified as an offset vector from center and outer and inner radii in both 290 * ellipse, specified as an offset vector from center and reciprocals of outer a nd inner radii in
291 * x and y directions. 291 * both x and y directions.
292 * 292 *
293 * This uses a slightly different algorithm than the EllipseEdgeEffect, above. R ather than 293 * This uses a slightly different algorithm than the EllipseEdgeEffect, above. R ather than
294 * scaling an ellipse to be a circle, it attempts to find the distance from the offset point to the 294 * scaling an ellipse to be a circle, it attempts to find the distance from the offset point to the
295 * ellipse by determining where the line through the origin and offset point wou ld cross the 295 * ellipse by determining where the line through the origin and offset point wou ld cross the
296 * ellipse, and computing the distance to that. This is slower but works better for roundrects 296 * ellipse, and computing the distance to that. This is slower but works better for roundrects
297 * because the straight edges will be more accurate. 297 * because the straight edges will be more accurate.
298 */ 298 */
299 299
300 class AltEllipseEdgeEffect : public GrEffect { 300 class AltEllipseEdgeEffect : public GrEffect {
301 public: 301 public:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_st r()); 350 builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_st r());
351 351
352 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName); 352 builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, & fsRadiiName);
353 const SkString* attr1Name = 353 const SkString* attr1Name =
354 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]); 354 builder->getEffectAttributeName(drawEffect.getVertexAttribIndice s()[1]);
355 builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str ()); 355 builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str ());
356 356
357 builder->fsCodeAppend("\tfloat edgeAlpha;\n"); 357 builder->fsCodeAppend("\tfloat edgeAlpha;\n");
358 // get length of offset 358 // get length of offset
359 builder->fsCodeAppendf("\tfloat len = length(%s.xy);\n", fsOffsetNam e); 359 builder->fsCodeAppendf("\tfloat len = length(%s.xy);\n", fsOffsetNam e);
360 builder->fsCodeAppend("\tvec2 offset;\n");
361 360
362 // for outer curve 361 // for outer curve
363 builder->fsCodeAppendf("\toffset.xy = %s.xy*%s.yx;\n", 362 builder->fsCodeAppendf("\tvec2 offset = %s.xy*%s.xy;\n",
364 fsOffsetName, fsRadiiName); 363 fsOffsetName, fsRadiiName);
365 builder->fsCodeAppendf("\tfloat tOuter = " 364 builder->fsCodeAppendf("\tfloat t = inversesqrt(dot(offset.xy, offse t.xy));\n");
366 "%s.x*%s.y*inversesqrt(dot(offset.xy, offset. xy));\n", 365 builder->fsCodeAppend("\tedgeAlpha = clamp(len*t - len, 0.0, 1.0);\n ");
367 fsRadiiName, fsRadiiName);
368 builder->fsCodeAppend("\tedgeAlpha = clamp(len*tOuter - len, 0.0, 1. 0);\n");
369 366
370 // for inner curve 367 // for inner curve
371 if (rrectEffect.isStroked()) { 368 if (rrectEffect.isStroked()) {
372 builder->fsCodeAppendf("\toffset.xy = %s.xy*%s.wz;\n", 369 builder->fsCodeAppendf("\toffset = %s.xy*%s.zw;\n",
373 fsOffsetName, fsRadiiName); 370 fsOffsetName, fsRadiiName);
374 builder->fsCodeAppendf("\tfloat tInner = " 371 builder->fsCodeAppendf("\tt = inversesqrt(dot(offset.xy, offset. xy));\n");
375 "%s.z*%s.w*inversesqrt(dot(offset.xy, off set.xy));\n", 372 builder->fsCodeAppend("\tedgeAlpha *= clamp(len - len*t, 0.0, 1. 0);\n");
376 fsRadiiName, fsRadiiName);
377 builder->fsCodeAppend("\tedgeAlpha *= clamp(len - len*tInner, 0. 0, 1.0);\n");
378 } 373 }
379 374
380 SkString modulate; 375 SkString modulate;
381 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); 376 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
382 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() ); 377 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str() );
383 } 378 }
384 379
385 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { 380 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
386 const AltEllipseEdgeEffect& rrectEffect = drawEffect.castEffect<AltE llipseEdgeEffect>(); 381 const AltEllipseEdgeEffect& rrectEffect = drawEffect.castEffect<AltE llipseEdgeEffect>();
387 382
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 bounds.fBottom - yOuterRadius, 947 bounds.fBottom - yOuterRadius,
953 bounds.fBottom 948 bounds.fBottom
954 }; 949 };
955 SkScalar yOuterOffsets[4] = { 950 SkScalar yOuterOffsets[4] = {
956 -yOuterRadius, 951 -yOuterRadius,
957 SK_ScalarNearlyZero, // we're using inversesqrt() in the shader, so can't be exactly 0 952 SK_ScalarNearlyZero, // we're using inversesqrt() in the shader, so can't be exactly 0
958 SK_ScalarNearlyZero, 953 SK_ScalarNearlyZero,
959 yOuterRadius 954 yOuterRadius
960 }; 955 };
961 956
957 SkScalar recipOuterX = SK_Scalar1/xOuterRadius;
958 SkScalar recipOuterY = SK_Scalar1/yOuterRadius;
959 SkScalar recipInnerX = SK_Scalar1/xInnerRadius;
960 SkScalar recipInnerY = SK_Scalar1/yInnerRadius;
961
962 for (int i = 0; i < 4; ++i) { 962 for (int i = 0; i < 4; ++i) {
963 verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); 963 verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
964 verts->fOffset = SkPoint::Make(-xOuterRadius, yOuterOffsets[i]); 964 verts->fOffset = SkPoint::Make(-xOuterRadius, yOuterOffsets[i]);
965 verts->fOuterRadii = SkPoint::Make(xOuterRadius, yOuterRadius); 965 verts->fOuterRadii = SkPoint::Make(recipOuterX, recipOuterY);
966 verts->fInnerRadii = SkPoint::Make(xInnerRadius, yInnerRadius); 966 verts->fInnerRadii = SkPoint::Make(recipInnerX, recipInnerY);
967 verts++; 967 verts++;
968 968
969 verts->fPos = SkPoint::Make(bounds.fLeft + xOuterRadius, yCoords[i]) ; 969 verts->fPos = SkPoint::Make(bounds.fLeft + xOuterRadius, yCoords[i]) ;
970 verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i] ); 970 verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i] );
971 verts->fOuterRadii = SkPoint::Make(xOuterRadius, yOuterRadius); 971 verts->fOuterRadii = SkPoint::Make(recipOuterX, recipOuterY);
972 verts->fInnerRadii = SkPoint::Make(xInnerRadius, yInnerRadius); 972 verts->fInnerRadii = SkPoint::Make(recipInnerX, recipInnerY);
973 verts++; 973 verts++;
974 974
975 verts->fPos = SkPoint::Make(bounds.fRight - xOuterRadius, yCoords[i] ); 975 verts->fPos = SkPoint::Make(bounds.fRight - xOuterRadius, yCoords[i] );
976 verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i] ); 976 verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i] );
977 verts->fOuterRadii = SkPoint::Make(xOuterRadius, yOuterRadius); 977 verts->fOuterRadii = SkPoint::Make(recipOuterX, recipOuterY);
978 verts->fInnerRadii = SkPoint::Make(xInnerRadius, yInnerRadius); 978 verts->fInnerRadii = SkPoint::Make(recipInnerX, recipInnerY);
979 verts++; 979 verts++;
980 980
981 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); 981 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]);
982 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); 982 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]);
983 verts->fOuterRadii = SkPoint::Make(xOuterRadius, yOuterRadius); 983 verts->fOuterRadii = SkPoint::Make(recipOuterX, recipOuterY);
984 verts->fInnerRadii = SkPoint::Make(xInnerRadius, yInnerRadius); 984 verts->fInnerRadii = SkPoint::Make(recipInnerX, recipInnerY);
985 verts++; 985 verts++;
986 } 986 }
987 987
988 // drop out the middle quad if we're stroked 988 // drop out the middle quad if we're stroked
989 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO UNT(gRRectIndices); 989 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO UNT(gRRectIndices);
990 target->setIndexSourceToBuffer(indexBuffer); 990 target->setIndexSourceToBuffer(indexBuffer);
991 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds); 991 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou nds);
992 } 992 }
993 993
994 return true; 994 return true;
995 } 995 }
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