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; |