aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--samplecode/SampleAndroidShadows.cpp4
-rw-r--r--src/gpu/GrRenderTargetContext.cpp7
-rw-r--r--src/gpu/effects/GrShadowGeoProc.cpp2
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp75
-rw-r--r--src/gpu/ops/GrShadowRRectOp.h2
-rwxr-xr-xsrc/utils/SkShadowTessellator.cpp2
6 files changed, 52 insertions, 40 deletions
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index a5fb6fcb9f..5d4cd26956 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -206,8 +206,8 @@ protected:
void onDrawContent(SkCanvas* canvas) override {
this->drawBG(canvas);
const SkScalar kLightWidth = 800;
- const SkScalar kAmbientAlpha = 0.039f;
- const SkScalar kSpotAlpha = 0.19f;
+ const SkScalar kAmbientAlpha = 0.1f;
+ const SkScalar kSpotAlpha = 0.25f;
SkPaint paint;
paint.setAntiAlias(true);
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index aae0248ae4..e26ec9018b 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1024,10 +1024,15 @@ bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
// set a large inset to force a fill
devSpaceInsetWidth = ambientRRect.width();
}
+ // the fraction of the blur we want to apply is devSpaceInsetWidth/devSpaceAmbientBlur,
+ // which is just 1/umbraRecipAlpha.
+ SkScalar blurClamp = SkScalarInvert(umbraRecipAlpha);
+
std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(ambientColor, viewMatrix,
ambientRRect,
devSpaceAmbientBlur,
- devSpaceInsetWidth);
+ devSpaceInsetWidth,
+ blurClamp);
SkASSERT(op);
this->addDrawOp(clip, std::move(op));
}
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
index 9f84aa2ae7..7eddaa41d8 100644
--- a/src/gpu/effects/GrShadowGeoProc.cpp
+++ b/src/gpu/effects/GrShadowGeoProc.cpp
@@ -45,7 +45,7 @@ public:
fragBuilder->codeAppend("half d = length(shadowParams.xy);");
fragBuilder->codeAppend("half distance = shadowParams.z * (1.0 - d);");
- fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, 1.0);");
+ fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, shadowParams.w);");
fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
fragBuilder->codeAppendf("%s = half4(factor);",
args.fOutputCoverage);
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index bee4e2d235..ba96941073 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -188,7 +188,8 @@ public:
// An insetWidth > 1/2 rect width or height indicates a simple fill.
ShadowCircularRRectOp(GrColor color, const SkRect& devRect,
- float devRadius, bool isCircle, float blurRadius, float insetWidth)
+ float devRadius, bool isCircle, float blurRadius, float insetWidth,
+ float blurClamp)
: INHERITED(ClassID()) {
SkRect bounds = devRect;
SkASSERT(insetWidth > 0);
@@ -224,7 +225,7 @@ public:
this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
fGeoData.emplace_back(Geometry{color, outerRadius, umbraInset, innerRadius,
- blurRadius, bounds, type, isCircle});
+ blurRadius, blurClamp, bounds, type, isCircle});
if (isCircle) {
fVertCount = circle_type_to_vert_count(kStroke_RRectType == type);
fIndexCount = circle_type_to_index_count(kStroke_RRectType == type);
@@ -265,6 +266,7 @@ private:
SkScalar fUmbraInset;
SkScalar fInnerRadius;
SkScalar fBlurRadius;
+ SkScalar fClampValue;
SkRect fDevBounds;
RRectType fType;
bool fIsCircle;
@@ -275,7 +277,7 @@ private:
GrColor fColor;
SkPoint fOffset;
SkScalar fDistanceCorrection;
- SkScalar fPad; // to be used later
+ SkScalar fClampValue;
};
void fillInCircleVerts(const Geometry& args, bool isStroked, CircleVertex** verts) const {
@@ -285,6 +287,7 @@ private:
SkScalar innerRadius = args.fInnerRadius;
SkScalar blurRadius = args.fBlurRadius;
SkScalar distanceCorrection = outerRadius / blurRadius;
+ SkScalar clampValue = args.fClampValue;
const SkRect& bounds = args.fDevBounds;
@@ -299,56 +302,56 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-octOffset, -1);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, -halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(octOffset, -1);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(halfWidth, -octOffset * halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(1, -octOffset);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(halfWidth, octOffset * halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(1, octOffset);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(octOffset, 1);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(-octOffset * halfWidth, halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-octOffset, 1);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(-halfWidth, octOffset * halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-1, octOffset);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(-halfWidth, -octOffset * halfWidth);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-1, -octOffset);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
if (isStroked) {
@@ -363,56 +366,56 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-s * innerRadius, -c * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(s * r, -c * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(s * innerRadius, -c * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(c * r, -s * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(c * innerRadius, -s * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(c * r, s * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(c * innerRadius, s * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(s * r, c * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(s * innerRadius, c * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(-s * r, c * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-s * innerRadius, c * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(-c * r, s * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-c * innerRadius, s * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = center + SkPoint::Make(-c * r, -s * r);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(-c * innerRadius, -s * innerRadius);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
} else {
// filled
@@ -420,7 +423,7 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
}
}
@@ -463,6 +466,7 @@ private:
outerVec.fX + outerVec.fY);
diagVec *= umbraInset / (2 * umbraInset - outerRadius);
SkScalar distanceCorrection = umbraInset / blurRadius;
+ SkScalar clampValue = args.fClampValue;
// build corner by corner
for (int i = 0; i < 4; ++i) {
@@ -471,7 +475,7 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkVector::Make(0, 0);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
// outer points
@@ -479,35 +483,35 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkVector::Make(0, -1);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = SkPoint::Make(xOuter[i], yMid[i]);
(*verts)->fColor = color;
(*verts)->fOffset = outerVec;
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = SkPoint::Make(xOuter[i], yOuter[i]);
(*verts)->fColor = color;
(*verts)->fOffset = diagVec;
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = SkPoint::Make(xMid[i], yOuter[i]);
(*verts)->fColor = color;
(*verts)->fOffset = outerVec;
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
(*verts)->fPos = SkPoint::Make(xInner[i], yOuter[i]);
(*verts)->fColor = color;
(*verts)->fOffset = SkVector::Make(0, -1);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
}
@@ -525,7 +529,7 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
// TR
@@ -533,7 +537,7 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
// BL
@@ -541,7 +545,7 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
// BR
@@ -549,7 +553,7 @@ private:
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fDistanceCorrection = distanceCorrection;
- (*verts)->fPad = 0;
+ (*verts)->fClampValue = clampValue;
(*verts)++;
}
@@ -644,7 +648,8 @@ std::unique_ptr<GrDrawOp> Make(GrColor color,
const SkMatrix& viewMatrix,
const SkRRect& rrect,
SkScalar blurWidth,
- SkScalar insetWidth) {
+ SkScalar insetWidth,
+ SkScalar blurClamp) {
// Shadow rrect ops only handle simple circular rrects.
SkASSERT(viewMatrix.isSimilarity() && SkRRectPriv::EqualRadii(rrect));
@@ -663,7 +668,8 @@ std::unique_ptr<GrDrawOp> Make(GrColor color,
scaledRadius,
rrect.isOval(),
blurWidth,
- scaledInsetWidth));
+ scaledInsetWidth,
+ blurClamp));
}
}
@@ -683,20 +689,21 @@ GR_DRAW_OP_TEST_DEFINE(ShadowRRectOp) {
viewMatrix.postScale(scale, scale);
SkScalar insetWidth = random->nextSScalar1() * 72.f;
SkScalar blurWidth = random->nextSScalar1() * 72.f;
+ SkScalar blurClamp = random->nextSScalar1();
bool isCircle = random->nextBool();
// This op doesn't use a full GrPaint, just a color.
GrColor color = paint.getColor();
if (isCircle) {
SkRect circle = GrTest::TestSquare(random);
SkRRect rrect = SkRRect::MakeOval(circle);
- return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth);
+ return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth, blurClamp);
} else {
SkRRect rrect;
do {
// This may return a rrect with elliptical corners, which we don't support.
rrect = GrTest::TestRRectSimple(random);
} while (!SkRRectPriv::IsSimpleCircular(rrect));
- return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth);
+ return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth, blurClamp);
}
}
diff --git a/src/gpu/ops/GrShadowRRectOp.h b/src/gpu/ops/GrShadowRRectOp.h
index 5ff084e3c8..3d8e92af00 100644
--- a/src/gpu/ops/GrShadowRRectOp.h
+++ b/src/gpu/ops/GrShadowRRectOp.h
@@ -19,7 +19,7 @@ class SkStrokeRec;
namespace GrShadowRRectOp {
std::unique_ptr<GrDrawOp> Make(GrColor, const SkMatrix& viewMatrix, const SkRRect& rrect,
- SkScalar blurWidth, SkScalar insetWidth);
+ SkScalar blurWidth, SkScalar insetWidth, SkScalar blurClamp = 1);
}
#endif
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index 0bf1adaaa4..98c47a6f2d 100755
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -121,7 +121,7 @@ static void compute_radial_steps(const SkVector& v1, const SkVector& v2, SkScala
SkScalar rSin = v1.cross(v2);
SkScalar theta = SkScalarATan2(rSin, rCos);
- int steps = SkScalarRoundToInt(SkScalarAbs(r*theta*kRecipPixelsPerArcSegment));
+ int steps = SkScalarFloorToInt(r*theta*kRecipPixelsPerArcSegment);
SkScalar dTheta = theta / steps;
*rotSin = SkScalarSinCos(dTheta, rotCos);