Minor shadow fixes.
Fix inset value for analytic shadows to get full inset (and hence
proper falloff).
Fix compute_radial_values in tessellator to return only positive values
and produce cleaner arcs.
Adjust shadow params in Android sample to match Android.
Fix corner calculation for analytic shadow.
Bug: skia:7486
Change-Id: Ib393b5d577f5a5eb89d3388aa4726ea4dae37055
Reviewed-on: https://skia-review.googlesource.com/123220
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index 5d4cd26..a5fb6fc 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -206,8 +206,8 @@
void onDrawContent(SkCanvas* canvas) override {
this->drawBG(canvas);
const SkScalar kLightWidth = 800;
- const SkScalar kAmbientAlpha = 0.1f;
- const SkScalar kSpotAlpha = 0.25f;
+ const SkScalar kAmbientAlpha = 0.039f;
+ const SkScalar kSpotAlpha = 0.19f;
SkPaint paint;
paint.setAntiAlias(true);
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index e26ec90..bb54122 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1110,7 +1110,7 @@
maxOffset = SkScalarSqrt(SkTMax(SkPointPriv::LengthSqd(upperLeftOffset),
SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
}
- insetWidth += maxOffset;
+ insetWidth += SkTMax(blurOutset, maxOffset);
}
// Outset the shadow rrect to the border of the penumbra
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index ba96941..8d60946 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -460,11 +460,19 @@
// we also skew the vectors we send to the shader that help define the circle.
// By doing so, we end up with a quarter circle in the corner rather than the
// elliptical curve.
- SkVector outerVec = SkVector::Make(0.5f*(outerRadius - umbraInset), -umbraInset);
+
+ // This is a bit magical, but it gives us the correct results at extrema:
+ // a) umbraInset == outerRadius produces an orthogonal vector
+ // b) outerRadius == 0 produces a diagonal vector
+ // And visually the corner looks correct.
+ SkVector outerVec = SkVector::Make(outerRadius - umbraInset, -outerRadius - umbraInset);
outerVec.normalize();
- SkVector diagVec = SkVector::Make(outerVec.fX + outerVec.fY,
- outerVec.fX + outerVec.fY);
- diagVec *= umbraInset / (2 * umbraInset - outerRadius);
+ // We want the circle edge to fall fractionally along the diagonal at
+ // (sqrt(2)*(umbraInset - outerRadius) + outerRadius)/sqrt(2)*umbraInset
+ //
+ // Setting the components of the diagonal offset to the following value will give us that.
+ SkScalar diagVal = umbraInset / (SK_ScalarSqrt2*(outerRadius - umbraInset) - outerRadius);
+ SkVector diagVec = SkVector::Make(diagVal, diagVal);
SkScalar distanceCorrection = umbraInset / blurRadius;
SkScalar clampValue = args.fClampValue;
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index 98c47a6..0bf1ada 100755
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -121,7 +121,7 @@
SkScalar rSin = v1.cross(v2);
SkScalar theta = SkScalarATan2(rSin, rCos);
- int steps = SkScalarFloorToInt(r*theta*kRecipPixelsPerArcSegment);
+ int steps = SkScalarRoundToInt(SkScalarAbs(r*theta*kRecipPixelsPerArcSegment));
SkScalar dTheta = theta / steps;
*rotSin = SkScalarSinCos(dTheta, rotCos);