aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--samplecode/SampleAndroidShadows.cpp2
-rw-r--r--src/effects/shadows/SkAmbientShadowMaskFilter.cpp14
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp23
-rw-r--r--src/utils/SkShadowUtils.cpp22
4 files changed, 31 insertions, 30 deletions
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index 803ea49f4a..cad8f5012e 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -469,7 +469,7 @@ protected:
canvas->translate(-250, 110);
lightPos.fX -= 250;
lightPos.fY += 110;
- this->drawShadowedPath(canvas, fCirclePath, SkTMax(1.0f, 8+fZDelta), paint, 0,
+ this->drawShadowedPath(canvas, fCirclePath, SkTMax(1.0f, 8+fZDelta), paint, kAmbientAlpha,
lightPos, kLightWidth, 0.5f);
paint.setColor(SK_ColorGREEN);
diff --git a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
index 9db75c5acb..b6f5392cb1 100644
--- a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
+++ b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp
@@ -220,12 +220,12 @@ bool SkAmbientShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
if (fAmbientAlpha > 0.0f) {
SkScalar srcSpaceAmbientRadius = fOccluderHeight * kHeightFactor * kGeomFactor;
const float umbraAlpha = (1.0f + SkTMax(fOccluderHeight * kHeightFactor, 0.0f));
- const SkScalar ambientOffset = srcSpaceAmbientRadius / umbraAlpha;
+ const SkScalar strokeWidth = srcSpaceAmbientRadius * umbraAlpha;
- // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius
- // to get our stroke shape.
- SkScalar ambientPathOutset = SkTMax(ambientOffset - srcSpaceAmbientRadius * 0.5f,
- minRadius);
+ // For the ambient rrect, we outset the offset rect by srcSpaceAmbientRadius
+ // minus half the strokeWidth to get our stroke shape.
+ SkScalar ambientPathOutset = SkTMax(srcSpaceAmbientRadius - strokeWidth * 0.5f,
+ minRadius);
SkRRect ambientRRect;
if (isRect) {
@@ -235,14 +235,14 @@ bool SkAmbientShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
rrect.outset(ambientPathOutset, ambientPathOutset, &ambientRRect);
}
- const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
+ const SkScalar devSpaceAmbientRadius = strokeWidth * scaleFactor;
GrPaint newPaint(paint);
GrColor4f color = newPaint.getColor4f();
color.fRGBA[3] *= fAmbientAlpha;
newPaint.setColor4f(color);
SkStrokeRec ambientStrokeRec(SkStrokeRec::kHairline_InitStyle);
- ambientStrokeRec.setStrokeStyle(srcSpaceAmbientRadius, false);
+ ambientStrokeRec.setStrokeStyle(strokeWidth, false);
rtContext->drawShadowRRect(clip, std::move(newPaint), viewMatrix, ambientRRect,
devSpaceAmbientRadius,
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index 6a848b8332..637c38a67d 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -101,13 +101,6 @@ public:
}
}
- // TODO: still needed?
- // The radii are outset for two reasons. First, it allows the shader to simply perform
- // simpler computation because the computed alpha is zero, rather than 50%, at the radius.
- // Second, the outer radius is used to compute the verts of the bounding box that is
- // rendered and the outset ensures the box will cover all partially covered by the circle.
- outerRadius += SK_ScalarHalf;
- innerRadius -= SK_ScalarHalf;
bool stroked = isStrokeOnly && innerRadius > 0.0f;
std::unique_ptr<ShadowCircleOp> op(new ShadowCircleOp());
op->fViewMatrixIfUsingLocalCoords = viewMatrix;
@@ -533,8 +526,6 @@ public:
}
if (strokeOnly) {
- // Outset stroke by 1/4 pixel
- devStrokeWidth += 0.25f;
// If stroke is greater than width or height, this is still a fill
// Otherwise we compute stroke params
if (devStrokeWidth <= devRect.width() && devStrokeWidth <= devRect.height()) {
@@ -546,19 +537,7 @@ public:
bounds.outset(halfWidth, halfWidth);
}
- // TODO: still needed?
- // The radii are outset for two reasons. First, it allows the shader to simply perform
- // simpler computation because the computed alpha is zero, rather than 50%, at the radius.
- // Second, the outer radius is used to compute the verts of the bounding box that is
- // rendered and the outset ensures the box will cover all partially covered by the rrect
- // corners.
- outerRadius += SK_ScalarHalf;
- innerRadius -= SK_ScalarHalf;
-
- this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
-
- // Expand the rect for aa to generate correct vertices.
- bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
+ this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
fGeoData.emplace_back(Geometry{color, outerRadius, innerRadius, blurRadius, bounds, type});
fVertCount = rrect_type_to_vert_count(type);
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 88ebaf5c8f..94dd113a5f 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -18,6 +18,8 @@
#include "GrShape.h"
#include "effects/GrBlurredEdgeFragmentProcessor.h"
#endif
+#include "../../src/effects/shadows/SkAmbientShadowMaskFilter.h"
+#include "../../src/effects/shadows/SkSpotShadowMaskFilter.h"
/**
* Gaussian color filter -- produces a Gaussian ramp based on the color's B value,
@@ -457,6 +459,26 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
uint32_t flags, SkResourceCache* cache) {
SkAutoCanvasRestore acr(canvas, true);
SkMatrix viewMatrix = canvas->getTotalMatrix();
+
+ // try circular fast path
+ SkRect rect;
+ if (viewMatrix.isSimilarity() &&
+ path.isOval(&rect) && rect.width() == rect.height()) {
+ SkPaint newPaint;
+ newPaint.setColor(color);
+ if (ambientAlpha > 0) {
+ newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderHeight, ambientAlpha,
+ flags));
+ canvas->drawPath(path, newPaint);
+ }
+ if (spotAlpha > 0) {
+ newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderHeight, devLightPos,
+ lightRadius, spotAlpha, flags));
+ canvas->drawPath(path, newPaint);
+ }
+ return;
+ }
+
canvas->resetMatrix();
ShadowedPath shadowedPath(&path, &viewMatrix);