Chromium Code Reviews| 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; |
| } |
|
robertphillips
2016/06/24 12:43:29
stray ';' ?
bsalomon
2016/06/24 16:10:23
Done;
|
| - 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; |
|
robertphillips
2016/06/24 12:43:29
Would it make any sense to resolve non-dashing pat
bsalomon
2016/06/24 16:10:23
Yep. I modified onCanDraw() to reject any shape th
|
| + 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; |