| Index: src/gpu/GrSoftwarePathRenderer.cpp
|
| diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
|
| index fd25bbbca27ae3c051094ccac12c758a944f5f22..983bd20cbe8a87743fcbc631cc5349b8b658fddf 100644
|
| --- a/src/gpu/GrSoftwarePathRenderer.cpp
|
| +++ b/src/gpu/GrSoftwarePathRenderer.cpp
|
| @@ -14,7 +14,9 @@
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
|
| - return SkToBool(fTexProvider);
|
| + // Pass on any style that applies. The caller will apply the style if a suitable renderer is
|
| + // not found and try again with the new GrShape.
|
| + return !args.fShape->style().applies() && SkToBool(fTexProvider);
|
| }
|
|
|
| namespace {
|
| @@ -23,33 +25,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 +128,41 @@ 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;
|
| + SkASSERT(!args.fShape->style().applies())
|
| + inverseFilled = args.fShape->inverseFilled();
|
| +
|
| + 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;
|
|
|