Use fast path for circular shadows.
Also cleans up some of the MaskFilter code to make it more correct. BUG=skia:6119 Change-Id: I93016bcdd9c55fcb2d1dc8776428a72eb563d67a Reviewed-on: https://skia-review.googlesource.com/9116 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
e7e5499c78
commit
cf40e307cd
@ -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);
|
||||
|
@ -220,11 +220,11 @@ 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,
|
||||
// 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;
|
||||
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user