Change drawPathWithMaskFilter to drawShapeWithMaskFilter
The caching portion of this (enabled by using GrShapes) is still in:
https://skia-review.googlesource.com/c/skia/+/146767 (Add GPU-side caching of mask-filtered path masks)
I would like to land them separately to assess the perf impact of dropping the path (im)mutability hint.
Change-Id: I584765177f2bb250a449d506d38f21f879fecdc6
Reviewed-on: https://skia-review.googlesource.com/147963
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp
index 4d4e250..65a2f33 100644
--- a/src/core/SkBlurMF.cpp
+++ b/src/core/SkBlurMF.cpp
@@ -26,6 +26,7 @@
#include "GrRenderTargetContext.h"
#include "GrResourceProvider.h"
#include "GrShaderCaps.h"
+#include "GrShape.h"
#include "GrStyle.h"
#include "GrTextureProxy.h"
#include "effects/GrCircleBlurFragmentProcessor.h"
@@ -49,7 +50,8 @@
SkIPoint* margin) const override;
#if SK_SUPPORT_GPU
- bool canFilterMaskGPU(const SkRRect& devRRect,
+ bool canFilterMaskGPU(const GrShape& shape,
+ const SkRect& devSpaceShapeBounds,
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const override;
@@ -58,8 +60,7 @@
GrPaint&&,
const GrClip&,
const SkMatrix& viewMatrix,
- const SkStrokeRec& strokeRec,
- const SkPath& path) const override;
+ const GrShape& shape) const override;
bool directFilterRRectMaskGPU(GrContext*,
GrRenderTargetContext* renderTargetContext,
GrPaint&&,
@@ -733,16 +734,19 @@
GrPaint&& paint,
const GrClip& clip,
const SkMatrix& viewMatrix,
- const SkStrokeRec& strokeRec,
- const SkPath& path) const {
+ const GrShape& shape) const {
SkASSERT(renderTargetContext);
if (fBlurStyle != kNormal_SkBlurStyle) {
return false;
}
+ if (!viewMatrix.rectStaysRect()) {
+ return false;
+ }
+
// TODO: we could handle blurred stroked circles
- if (!strokeRec.isFillStyle()) {
+ if (!shape.style().isSimpleFill()) {
return false;
}
@@ -751,19 +755,27 @@
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
std::unique_ptr<GrFragmentProcessor> fp;
+ SkRRect rrect;
SkRect rect;
- if (path.isRect(&rect)) {
- SkScalar pad = 3.0f * xformedSigma;
- rect.outset(pad, pad);
+ bool inverted;
+ if (shape.asRRect(&rrect, nullptr, nullptr, &inverted) && !inverted) {
+ rect = rrect.rect();
+ SkAssertResult(viewMatrix.mapRect(&rect));
+ if (rrect.isRect()) {
+ SkScalar pad = 3.0f * xformedSigma;
+ rect.outset(pad, pad);
- fp = GrRectBlurEffect::Make(proxyProvider, *context->contextPriv().caps()->shaderCaps(),
- rect, xformedSigma);
- } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height())) {
- fp = GrCircleBlurFragmentProcessor::Make(proxyProvider, rect, xformedSigma);
+ fp = GrRectBlurEffect::Make(proxyProvider, *context->contextPriv().caps()->shaderCaps(),
+ rect, xformedSigma);
+ } else if (SkRRectPriv::IsCircle(rrect)) {
+ fp = GrCircleBlurFragmentProcessor::Make(proxyProvider, rect, xformedSigma);
- // expand the rect for the coverage geometry
- int pad = SkScalarCeilToInt(6*xformedSigma)/2;
- rect.outset(SkIntToScalar(pad), SkIntToScalar(pad));
+ // expand the rect for the coverage geometry
+ int pad = SkScalarCeilToInt(6*xformedSigma)/2;
+ rect.outset(SkIntToScalar(pad), SkIntToScalar(pad));
+ } else {
+ return false;
+ }
} else {
return false;
}
@@ -878,7 +890,8 @@
return true;
}
-bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
+bool SkBlurMaskFilterImpl::canFilterMaskGPU(const GrShape& shape,
+ const SkRect& devSpaceShapeBounds,
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const {
@@ -887,13 +900,13 @@
return false;
}
- // We prefer to blur small rects with small radii on the CPU.
- if (devRRect.isRect()) {
+ // We prefer to blur paths with small blur radii on the CPU.
+ if (ctm.rectStaysRect()) {
static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64);
static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32);
- if (devRRect.width() <= kMIN_GPU_BLUR_SIZE &&
- devRRect.height() <= kMIN_GPU_BLUR_SIZE &&
+ if (devSpaceShapeBounds.width() <= kMIN_GPU_BLUR_SIZE &&
+ devSpaceShapeBounds.height() <= kMIN_GPU_BLUR_SIZE &&
xformedSigma <= kMIN_GPU_BLUR_SIGMA) {
return false;
}
@@ -907,7 +920,7 @@
float sigma3 = 3 * SkScalarToFloat(xformedSigma);
SkRect clipRect = SkRect::Make(clipBounds);
- SkRect srcRect(devRRect.rect());
+ SkRect srcRect = devSpaceShapeBounds;
// Outset srcRect and clipRect by 3 * sigma, to compute affected blur area.
srcRect.outset(sigma3, sigma3);
diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp
index e001f58..0c5af3e 100644
--- a/src/core/SkMaskFilter.cpp
+++ b/src/core/SkMaskFilter.cpp
@@ -323,7 +323,8 @@
}
bool SkMaskFilterBase::onHasFragmentProcessor() const { return false; }
-bool SkMaskFilterBase::canFilterMaskGPU(const SkRRect& devRRect,
+bool SkMaskFilterBase::canFilterMaskGPU(const GrShape& shape,
+ const SkRect& devSpaceShapeBounds,
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const {
@@ -335,8 +336,7 @@
GrPaint&&,
const GrClip&,
const SkMatrix& viewMatrix,
- const SkStrokeRec& strokeRec,
- const SkPath& path) const {
+ const GrShape&) const {
return false;
}
diff --git a/src/core/SkMaskFilterBase.h b/src/core/SkMaskFilterBase.h
index 53d5ec9..cd48477 100644
--- a/src/core/SkMaskFilterBase.h
+++ b/src/core/SkMaskFilterBase.h
@@ -24,6 +24,7 @@
class GrRenderTarget;
class GrRenderTargetContext;
class GrResourceProvider;
+class GrShape;
class GrTexture;
class GrTextureProxy;
@@ -89,8 +90,6 @@
* canFilterMaskGPU is called
* if (it returns true)
* the returned mask rect is used for quick rejecting
- * either directFilterMaskGPU or directFilterRRectMaskGPU is then called
- * if (neither of them handle the blur)
* the mask rect is used to generate the mask
* filterMaskGPU is called to filter the mask
*
@@ -99,7 +98,8 @@
* filterMaskGPU(devShape, ...)
* this would hide the RRect special case and the mask generation
*/
- virtual bool canFilterMaskGPU(const SkRRect& devRRect,
+ virtual bool canFilterMaskGPU(const GrShape&,
+ const SkRect& devSpaceShapeBounds,
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const;
@@ -113,8 +113,7 @@
GrPaint&& paint,
const GrClip&,
const SkMatrix& viewMatrix,
- const SkStrokeRec& strokeRec,
- const SkPath& path) const;
+ const GrShape& shape) const;
/**
* Try to directly render a rounded rect mask filter into the target. Returns
* true if drawing was successful. If false is returned then paint is unmodified.
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 1fc7d4b..669292c 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -14,6 +14,8 @@
#include "GrProxyProvider.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
+#include "GrShape.h"
+#include "GrSoftwarePathRenderer.h"
#include "GrStyle.h"
#include "GrTextureProxy.h"
#include "effects/GrSimpleTextureEffect.h"
@@ -60,11 +62,29 @@
GrRenderTargetContext* renderTargetContext,
const GrClip& clipData,
const SkMatrix& viewMatrix,
- const SkPath& devPath,
+ const GrShape& shape,
const SkMaskFilter* filter,
const SkIRect& clipBounds,
- GrPaint&& paint,
- SkStrokeRec::InitStyle fillOrHairline) {
+ GrPaint&& paint) {
+ SkASSERT(filter);
+ SkASSERT(!shape.style().applies());
+
+ auto proxyProvider = context->contextPriv().proxyProvider();
+
+ sk_sp<GrTextureProxy> maskProxy;
+
+ SkStrokeRec::InitStyle fillOrHairline = shape.style().isSimpleHairline()
+ ? SkStrokeRec::kHairline_InitStyle
+ : SkStrokeRec::kFill_InitStyle;
+
+ // TODO: it seems like we could create an SkDraw here and set its fMatrix field rather
+ // than explicitly transforming the path to device space.
+ SkPath devPath;
+
+ shape.asPath(&devPath);
+
+ devPath.transform(viewMatrix);
+
SkMask srcM, dstM;
if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
SkMask::kComputeBoundsAndRenderImage_CreateMode, fillOrHairline)) {
@@ -72,6 +92,8 @@
}
SkAutoMaskFreeImage autoSrc(srcM.fImage);
+ SkASSERT(SkMask::kA8_Format == srcM.fFormat);
+
if (!as_MFB(filter)->filterMask(&dstM, srcM, viewMatrix, nullptr)) {
return false;
}
@@ -96,11 +118,10 @@
return false;
}
- auto proxyProvider = context->contextPriv().proxyProvider();
- sk_sp<GrTextureProxy> maskProxy = proxyProvider->createTextureProxy(std::move(image),
- kNone_GrSurfaceFlags,
- 1, SkBudgeted::kYes,
- SkBackingFit::kApprox);
+ maskProxy = proxyProvider->createTextureProxy(std::move(image),
+ kNone_GrSurfaceFlags,
+ 1, SkBudgeted::kYes,
+ SkBackingFit::kApprox);
if (!maskProxy) {
return false;
}
@@ -109,11 +130,11 @@
dstM.fBounds, std::move(paint), std::move(maskProxy));
}
-// Create a mask of 'devPath' and place the result in 'mask'.
+// Create a mask of 'shape' and place the result in 'mask'.
static sk_sp<GrTextureProxy> create_mask_GPU(GrContext* context,
const SkIRect& maskRect,
- const SkPath& devPath,
- SkStrokeRec::InitStyle fillOrHairline,
+ const SkMatrix& origViewMatrix,
+ const GrShape& shape,
GrAA aa,
int sampleCnt) {
if (GrAA::kNo == aa) {
@@ -140,62 +161,83 @@
// Draw the mask into maskTexture with the path's integerized top-left at
// the origin using maskPaint.
- SkMatrix translate;
- translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
- rtContext->drawPath(clip, std::move(maskPaint), aa, translate, devPath,
- GrStyle(fillOrHairline));
+ SkMatrix viewMatrix = origViewMatrix;
+ viewMatrix.postTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
+ rtContext->drawShape(clip, std::move(maskPaint), aa, viewMatrix, shape);
return rtContext->asTextureProxyRef();
}
-static void draw_path_with_mask_filter(GrContext* context,
- GrRenderTargetContext* renderTargetContext,
- const GrClip& clip,
- GrPaint&& paint,
- GrAA aa,
- const SkMatrix& viewMatrix,
- const SkMaskFilterBase* maskFilter,
- const GrStyle& style,
- const SkPath* path,
- bool pathIsMutable) {
- SkASSERT(maskFilter);
+static bool get_unclipped_shape_dev_bounds(const GrShape& shape, const SkMatrix& matrix,
+ SkIRect* devBounds) {
+ SkRect shapeBounds = shape.styledBounds();
+ if (shapeBounds.isEmpty()) {
+ return false;
+ }
+ SkRect shapeDevBounds;
+ matrix.mapRect(&shapeDevBounds, shapeBounds);
+ // Even though these are "unclipped" bounds we still clip to the int32_t range.
+ // This is the largest int32_t that is representable exactly as a float. The next 63 larger ints
+ // would round down to this value when cast to a float, but who really cares.
+ // INT32_MIN is exactly representable.
+ static constexpr int32_t kMaxInt = 2147483520;
+ if (!shapeDevBounds.intersect(SkRect::MakeLTRB(INT32_MIN, INT32_MIN, kMaxInt, kMaxInt))) {
+ return false;
+ }
+ // Make sure that the resulting SkIRect can have representable width and height
+ if (SkScalarRoundToInt(shapeDevBounds.width()) > kMaxInt ||
+ SkScalarRoundToInt(shapeDevBounds.height()) > kMaxInt) {
+ return false;
+ }
+ shapeDevBounds.roundOut(devBounds);
+ return true;
+}
- SkIRect clipBounds;
+// Gets the shape bounds, the clip bounds, and the intersection (if any). Returns false if there
+// is no intersection.
+static bool get_shape_and_clip_bounds(GrRenderTargetContext* renderTargetContext,
+ const GrClip& clip,
+ const GrShape& shape,
+ const SkMatrix& matrix,
+ SkIRect* unclippedDevShapeBounds,
+ SkIRect* devClipBounds) {
+ // compute bounds as intersection of rt size, clip, and path
clip.getConservativeBounds(renderTargetContext->width(),
renderTargetContext->height(),
- &clipBounds);
- SkTLazy<SkPath> tmpPath;
- SkStrokeRec::InitStyle fillOrHairline;
+ devClipBounds);
- // We just fully apply the style here.
- if (style.applies()) {
- SkScalar scale = GrStyle::MatrixToScaleFactor(viewMatrix);
- if (0 == scale || !style.applyToPath(tmpPath.init(), &fillOrHairline, *path, scale)) {
- return;
- }
- pathIsMutable = true;
- path = tmpPath.get();
- } else if (style.isSimpleHairline()) {
- fillOrHairline = SkStrokeRec::kHairline_InitStyle;
- } else {
- SkASSERT(style.isSimpleFill());
- fillOrHairline = SkStrokeRec::kFill_InitStyle;
+ if (!get_unclipped_shape_dev_bounds(shape, matrix, unclippedDevShapeBounds)) {
+ *unclippedDevShapeBounds = SkIRect::EmptyIRect();
+ return false;
}
- // transform the path into device space
- if (!viewMatrix.isIdentity()) {
- SkPath* result;
- if (pathIsMutable) {
- result = const_cast<SkPath*>(path);
- } else {
- if (!tmpPath.isValid()) {
- tmpPath.init();
- }
- result = tmpPath.get();
+ return true;
+}
+
+static void draw_shape_with_mask_filter(GrContext* context,
+ GrRenderTargetContext* renderTargetContext,
+ const GrClip& clip,
+ GrPaint&& paint,
+ GrAA aa,
+ const SkMatrix& viewMatrix,
+ const SkMaskFilterBase* maskFilter,
+ const GrShape& origShape) {
+ SkASSERT(maskFilter);
+
+ const GrShape* shape = &origShape;
+ SkTLazy<GrShape> tmpShape;
+
+ if (origShape.style().applies()) {
+ SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
+ if (0 == styleScale) {
+ return;
}
- path->transform(viewMatrix, result);
- path = result;
- result->setIsVolatile(true);
- pathIsMutable = true;
+
+ tmpShape.init(origShape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale));
+ if (tmpShape.get()->isEmpty()) {
+ return;
+ }
+
+ shape = tmpShape.get();
}
if (maskFilter->directFilterMaskGPU(context,
@@ -203,16 +245,33 @@
std::move(paint),
clip,
viewMatrix,
- SkStrokeRec(fillOrHairline),
- *path)) {
+ *shape)) {
// the mask filter was able to draw itself directly, so there's nothing
// left to do.
return;
}
+ // If the path is hairline, ignore inverse fill.
+ bool inverseFilled = shape->inverseFilled() &&
+ !GrPathRenderer::IsStrokeHairlineOrEquivalent(shape->style(),
+ viewMatrix, nullptr);
+
+ SkIRect unclippedDevShapeBounds, devClipBounds;
+ if (!get_shape_and_clip_bounds(renderTargetContext,
+ clip, *shape,
+ viewMatrix,
+ &unclippedDevShapeBounds,
+ &devClipBounds)) {
+ // TODO: just cons up an opaque mask here
+ if (!inverseFilled) {
+ return;
+ }
+ }
+
SkRect maskRect;
- if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()),
- clipBounds,
+ if (maskFilter->canFilterMaskGPU(*shape,
+ SkRect::Make(unclippedDevShapeBounds),
+ devClipBounds,
viewMatrix,
&maskRect)) {
// This mask will ultimately be drawn as a non-AA rect (see draw_mask).
@@ -220,7 +279,7 @@
// so the mask draws in a reproducible manner.
SkIRect finalIRect;
maskRect.roundOut(&finalIRect);
- if (clip_bounds_quick_reject(clipBounds, finalIRect)) {
+ if (clip_bounds_quick_reject(devClipBounds, finalIRect)) {
// clipped out
return;
}
@@ -231,8 +290,8 @@
sk_sp<GrTextureProxy> maskProxy(create_mask_GPU(
context,
finalIRect,
- *path,
- fillOrHairline,
+ viewMatrix,
+ *shape,
aa,
renderTargetContext->numColorSamples()));
if (maskProxy) {
@@ -245,59 +304,52 @@
if (filteredMask) {
if (draw_mask(renderTargetContext, clip, viewMatrix,
- finalIRect, std::move(paint), std::move(filteredMask))) {
+ finalIRect, std::move(paint), std::move(filteredMask))) {
// This path is completely drawn
return;
}
}
-
}
- sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *path, maskFilter,
- clipBounds, std::move(paint), fillOrHairline);
+ sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *shape,
+ maskFilter, devClipBounds, std::move(paint));
}
-void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
- GrRenderTargetContext* renderTargetContext,
- const GrClip& clip,
- const SkPath& path,
- GrPaint&& paint,
- GrAA aa,
- const SkMatrix& viewMatrix,
- const SkMaskFilter* mf,
- const GrStyle& style,
- bool pathIsMutable) {
- draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(paint), aa, viewMatrix,
- as_MFB(mf), style, &path, pathIsMutable);
+void GrBlurUtils::drawShapeWithMaskFilter(GrContext* context,
+ GrRenderTargetContext* renderTargetContext,
+ const GrClip& clip,
+ const GrShape& shape,
+ GrPaint&& paint,
+ GrAA aa,
+ const SkMatrix& viewMatrix,
+ const SkMaskFilter* mf) {
+ draw_shape_with_mask_filter(context, renderTargetContext, clip, std::move(paint), aa,
+ viewMatrix, as_MFB(mf), shape);
}
-void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
- GrRenderTargetContext* renderTargetContext,
- const GrClip& clip,
- const SkPath& path,
- const SkPaint& paint,
- const SkMatrix& viewMatrix,
- bool pathIsMutable) {
+void GrBlurUtils::drawShapeWithMaskFilter(GrContext* context,
+ GrRenderTargetContext* renderTargetContext,
+ const GrClip& clip,
+ const SkPaint& paint,
+ const SkMatrix& viewMatrix,
+ const GrShape& shape) {
if (context->abandoned()) {
return;
}
- SkASSERT(!pathIsMutable || path.isVolatile());
-
- GrStyle style(paint);
-
GrPaint grPaint;
if (!SkPaintToGrPaint(context, renderTargetContext->colorSpaceInfo(), paint, viewMatrix,
&grPaint)) {
return;
}
+
GrAA aa = GrAA(paint.isAntiAlias());
SkMaskFilterBase* mf = as_MFB(paint.getMaskFilter());
if (mf && !mf->hasFragmentProcessor()) {
// The MaskFilter wasn't already handled in SkPaintToGrPaint
- draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(grPaint), aa,
- viewMatrix, mf, style, &path, pathIsMutable);
+ draw_shape_with_mask_filter(context, renderTargetContext, clip, std::move(grPaint), aa,
+ viewMatrix, mf, shape);
} else {
- renderTargetContext->drawPath(clip, std::move(grPaint), aa, viewMatrix, path, style);
+ renderTargetContext->drawShape(clip, std::move(grPaint), aa, viewMatrix, shape);
}
}
diff --git a/src/gpu/GrBlurUtils.h b/src/gpu/GrBlurUtils.h
index 4fb671b..d8f99f1 100644
--- a/src/gpu/GrBlurUtils.h
+++ b/src/gpu/GrBlurUtils.h
@@ -15,6 +15,7 @@
class GrPaint;
class GrRenderTarget;
class GrRenderTargetContext;
+class GrShape;
class GrStyle;
struct SkIRect;
class SkMaskFilter;
@@ -29,30 +30,27 @@
*/
namespace GrBlurUtils {
/**
- * Draw a path handling the mask filter if present.
+ * Draw a shape handling the mask filter if present.
*/
- void drawPathWithMaskFilter(GrContext*,
- GrRenderTargetContext*,
- const GrClip&,
- const SkPath& origSrcPath,
- const SkPaint&,
- const SkMatrix& viewMatrix,
- bool pathIsMutable);
+ void drawShapeWithMaskFilter(GrContext*,
+ GrRenderTargetContext*,
+ const GrClip&,
+ const SkPaint&,
+ const SkMatrix& viewMatrix,
+ const GrShape&);
/**
- * Draw a path handling the mask filter. The mask filter is not optional.
+ * Draw a shape handling the mask filter. The mask filter is not optional.
* The GrPaint will be modified after return.
*/
- void drawPathWithMaskFilter(GrContext*,
- GrRenderTargetContext*,
- const GrClip&,
- const SkPath& path,
- GrPaint&&,
- GrAA,
- const SkMatrix& viewMatrix,
- const SkMaskFilter*,
- const GrStyle&,
- bool pathIsMutable);
+ void drawShapeWithMaskFilter(GrContext*,
+ GrRenderTargetContext*,
+ const GrClip&,
+ const GrShape&,
+ GrPaint&&,
+ GrAA,
+ const SkMatrix& viewMatrix,
+ const SkMaskFilter*);
};
#endif
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 66bbc53..bc98827 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -70,8 +70,11 @@
void drawPath(const GrClip& clip, const SkPath& path, const SkPaint& paint,
const SkMatrix& viewMatrix, bool pathIsMutable) override {
- GrBlurUtils::drawPathWithMaskFilter(fRenderTargetContext->fContext, fRenderTargetContext,
- clip, path, paint, viewMatrix, pathIsMutable);
+ // TODO: we are losing the mutability of the path here
+ GrShape shape(path, paint);
+
+ GrBlurUtils::drawShapeWithMaskFilter(fRenderTargetContext->fContext, fRenderTargetContext,
+ clip, paint, viewMatrix, shape);
}
void makeGrPaint(GrMaskFormat maskFormat, const SkPaint& skPaint, const SkMatrix& viewMatrix,
@@ -1497,23 +1500,19 @@
SkRect rects[2];
if (style.isSimpleFill() && fills_as_nested_rects(viewMatrix, path, rects)) {
// Concave AA paths are expensive - try to avoid them for special cases
- SkRect rects[2];
-
- if (fills_as_nested_rects(viewMatrix, path, rects)) {
- std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillNestedRects(
- fContext, std::move(paint), viewMatrix, rects);
- if (op) {
- this->addDrawOp(clip, std::move(op));
- }
- // A null return indicates that there is nothing to draw in this case.
- return;
+ std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillNestedRects(
+ fContext, std::move(paint), viewMatrix, rects);
+ if (op) {
+ this->addDrawOp(clip, std::move(op));
}
+ // Returning here indicates that there is nothing to draw in this case.
+ return;
}
}
GrShape shape(path, style);
- return this->drawShape(clip, std::move(paint), aa, viewMatrix, shape);
+ this->drawShape(clip, std::move(paint), aa, viewMatrix, shape);
}
void GrRenderTargetContext::drawShape(const GrClip& clip,
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 81b533a..2070110 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -16,6 +16,7 @@
#include "GrGpu.h"
#include "GrImageTextureMaker.h"
#include "GrRenderTargetContextPriv.h"
+#include "GrShape.h"
#include "GrStyle.h"
#include "GrSurfaceProxyPriv.h"
#include "GrTextureAdjuster.h"
@@ -377,13 +378,15 @@
void SkGpuDevice::drawRect(const SkRect& rect, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRect", fContext.get());
+
+ GrStyle style(paint);
+
// A couple reasons we might need to call drawPath.
if (paint.getMaskFilter() || paint.getPathEffect()) {
- SkPath path;
- path.setIsVolatile(true);
- path.addRect(rect);
- GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
- this->clip(), path, paint, this->ctm(), true);
+ GrShape shape(rect, style);
+
+ GrBlurUtils::drawShapeWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
+ this->clip(), paint, this->ctm(), shape);
return;
}
@@ -393,7 +396,6 @@
return;
}
- GrStyle style(paint);
fRenderTargetContext->drawRect(this->clip(), std::move(grPaint), GrAA(paint.isAntiAlias()),
this->ctm(), rect, &style);
}
@@ -403,6 +405,7 @@
void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext.get());
+
GrPaint grPaint;
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext->colorSpaceInfo(), paint,
this->ctm(), &grPaint)) {
@@ -436,11 +439,11 @@
// The only mask filter the native rrect drawing code could've handle was taken
// care of above.
// A path effect will presumably transform this rrect into something else.
- SkPath path;
- path.setIsVolatile(true);
- path.addRRect(rrect);
- GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
- this->clip(), path, paint, this->ctm(), true);
+ GrShape shape(rrect, style);
+
+ // TODO: this is throwing away to work we did to create the GrPaint
+ GrBlurUtils::drawShapeWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
+ this->clip(), paint, this->ctm(), shape);
return;
}
@@ -482,8 +485,12 @@
path.addRRect(inner);
path.setFillType(SkPath::kEvenOdd_FillType);
- GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(), this->clip(),
- path, paint, this->ctm(), true);
+ // TODO: We are losing the possible mutability of the path here but this should probably be
+ // fixed by upgrading GrShape to handle DRRects.
+ GrShape shape(path, paint);
+
+ GrBlurUtils::drawShapeWithMaskFilter(fContext.get(), fRenderTargetContext.get(), this->clip(),
+ paint, this->ctm(), shape);
}
@@ -630,8 +637,12 @@
this->ctm(), origSrcPath, GrStyle(paint));
return;
}
- GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(), this->clip(),
- origSrcPath, paint, this->ctm(), pathIsMutable);
+
+ // TODO: losing possible mutability of 'origSrcPath' here
+ GrShape shape(origSrcPath, paint);
+
+ GrBlurUtils::drawShapeWithMaskFilter(fContext.get(), fRenderTargetContext.get(), this->clip(),
+ paint, this->ctm(), shape);
}
static const int kBmpSmallTileSize = 1 << 10;
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 9b2641e..49753ce 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -10,6 +10,7 @@
#include "GrCaps.h"
#include "GrColorSpaceXform.h"
#include "GrRenderTargetContext.h"
+#include "GrShape.h"
#include "GrStyle.h"
#include "GrTextureAdjuster.h"
#include "GrTextureMaker.h"
@@ -336,10 +337,8 @@
}
}
- SkPath rectPath;
- rectPath.addRect(clippedDstRect);
- rectPath.setIsVolatile(true);
- GrBlurUtils::drawPathWithMaskFilter(this->context(), fRenderTargetContext.get(), this->clip(),
- rectPath, std::move(grPaint), aa, viewMatrix, mf,
- GrStyle::SimpleFill(), true);
+ GrShape shape(clippedDstRect, GrStyle::SimpleFill());
+
+ GrBlurUtils::drawShapeWithMaskFilter(this->context(), fRenderTargetContext.get(), this->clip(),
+ shape, std::move(grPaint), aa, viewMatrix, mf);
}