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);
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) {
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,
}
}
- // 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;
}
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()) {
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);
#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,
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);