| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |