| Index: src/gpu/GrSoftwarePathRenderer.cpp
|
| diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
|
| index fd25bbbca27ae3c051094ccac12c758a944f5f22..6fe3dc1bf5dc612327c03e75be0a43d614767540 100644
|
| --- a/src/gpu/GrSoftwarePathRenderer.cpp
|
| +++ b/src/gpu/GrSoftwarePathRenderer.cpp
|
| @@ -23,33 +23,34 @@ namespace {
|
| // gets device coord bounds of path (not considering the fill) and clip. The
|
| // path bounds will be a subset of the clip bounds. returns false if
|
| // path bounds would be empty.
|
| -bool get_path_and_clip_bounds(int width, int height,
|
| - const GrClip& clip,
|
| - const SkPath& path,
|
| - const SkMatrix& matrix,
|
| - SkIRect* devPathBounds,
|
| - SkIRect* devClipBounds) {
|
| +bool get_shape_and_clip_bounds(int width, int height,
|
| + const GrClip& clip,
|
| + const GrShape& shape,
|
| + const SkMatrix& matrix,
|
| + SkIRect* devShapeBounds,
|
| + SkIRect* devClipBounds) {
|
| // compute bounds as intersection of rt size, clip, and path
|
| clip.getConservativeBounds(width, height, devClipBounds);
|
|
|
| if (devClipBounds->isEmpty()) {
|
| - *devPathBounds = SkIRect::MakeWH(width, height);
|
| + *devShapeBounds = SkIRect::MakeWH(width, height);
|
| return false;
|
| }
|
| -
|
| - if (!path.getBounds().isEmpty()) {
|
| - SkRect pathSBounds;
|
| - matrix.mapRect(&pathSBounds, path.getBounds());
|
| - SkIRect pathIBounds;
|
| - pathSBounds.roundOut(&pathIBounds);
|
| - *devPathBounds = *devClipBounds;
|
| - if (!devPathBounds->intersect(pathIBounds)) {
|
| + SkRect shapeBounds;
|
| + shape.styledBounds(&shapeBounds);
|
| + if (!shapeBounds.isEmpty()) {
|
| + SkRect shapeSBounds;
|
| + matrix.mapRect(&shapeSBounds, shapeBounds);
|
| + SkIRect shapeIBounds;
|
| + shapeSBounds.roundOut(&shapeIBounds);
|
| + *devShapeBounds = *devClipBounds;
|
| + if (!devShapeBounds->intersect(shapeIBounds)) {
|
| // set the correct path bounds, as this would be used later.
|
| - *devPathBounds = pathIBounds;
|
| + *devShapeBounds = shapeIBounds;
|
| return false;
|
| }
|
| } else {
|
| - *devPathBounds = SkIRect::EmptyIRect();
|
| + *devShapeBounds = SkIRect::EmptyIRect();
|
| return false;
|
| }
|
| return true;
|
| @@ -125,35 +126,50 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
|
| return false;
|
| }
|
|
|
| - SkIRect devPathBounds, devClipBounds;
|
| - if (!get_path_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
|
| - *args.fClip, *args.fPath,
|
| - *args.fViewMatrix, &devPathBounds, &devClipBounds)) {
|
| - if (args.fPath->isInverseFillType()) {
|
| + // We really need to know if the shape will be inverse filled or not;
|
| + bool inverseFilled = false;
|
| + SkTLazy<GrShape> tmpShape;
|
| + const GrShape* shape = args.fShape;
|
| + if (shape->mayBeInverseFilledAfterStyling()) {
|
| + // The "may" comes about because of arbitrary path effects. The rubber meets the road here.
|
| + if (shape->style().hasNonDashPathEffect()) {
|
| + tmpShape.init(shape->applyStyle(GrStyle::Apply::kPathEffectOnly, 1.f));
|
| + shape = tmpShape.get();
|
| + inverseFilled = shape->inverseFilled();
|
| + } else {
|
| + inverseFilled = true;
|
| + }
|
| + }
|
| +
|
| + SkIRect devShapeBounds, devClipBounds;
|
| + if (!get_shape_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
|
| + *args.fClip, *args.fShape,
|
| + *args.fViewMatrix, &devShapeBounds, &devClipBounds)) {
|
| + if (inverseFilled) {
|
| DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
|
| *args.fClip, args.fColor,
|
| - *args.fViewMatrix, devClipBounds, devPathBounds);
|
| + *args.fViewMatrix, devClipBounds, devShapeBounds);
|
| +
|
| }
|
| return true;
|
| }
|
|
|
| SkAutoTUnref<GrTexture> texture(
|
| - GrSWMaskHelper::DrawPathMaskToTexture(fTexProvider, *args.fPath, *args.fStyle,
|
| - devPathBounds,
|
| - args.fAntiAlias, args.fViewMatrix));
|
| + GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape, devShapeBounds,
|
| + args.fAntiAlias, args.fViewMatrix));
|
| if (nullptr == texture) {
|
| return false;
|
| }
|
|
|
| - GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fDrawContext, args.fPaint,
|
| - args.fUserStencilSettings,
|
| - *args.fClip, args.fColor, *args.fViewMatrix,
|
| - devPathBounds);
|
| + GrSWMaskHelper::DrawToTargetWithShapeMask(texture, args.fDrawContext, args.fPaint,
|
| + args.fUserStencilSettings,
|
| + *args.fClip, args.fColor, *args.fViewMatrix,
|
| + devShapeBounds);
|
|
|
| - if (args.fPath->isInverseFillType()) {
|
| + if (inverseFilled) {
|
| DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
|
| *args.fClip, args.fColor,
|
| - *args.fViewMatrix, devClipBounds, devPathBounds);
|
| + *args.fViewMatrix, devClipBounds, devShapeBounds);
|
| }
|
|
|
| return true;
|
|
|