aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-03-10 22:53:20 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-03-10 22:53:20 +0000
commit821397018fdabea6b434ecb96f84fb5449c4025f (patch)
tree7b6a3b536f4be38a6a9ea0691358e612db448f40
parent45b9de81bce1d5edb72815146d45e688ea3090a0 (diff)
plumbing for GPU fast blur
BUG=skia:2281 R=bsalomon@google.com Author: humper@google.com Review URL: https://codereview.chromium.org/193193002 git-svn-id: http://skia.googlecode.com/svn/trunk@13735 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkMaskFilter.h8
-rw-r--r--include/core/SkRRect.h2
-rw-r--r--src/core/SkMaskFilter.cpp7
-rw-r--r--src/core/SkRRect.cpp7
-rw-r--r--src/effects/SkBlurMaskFilter.cpp11
-rw-r--r--src/gpu/SkGpuDevice.cpp50
6 files changed, 77 insertions, 8 deletions
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index 33e45552e8..ac9b7189b2 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -101,6 +101,14 @@ public:
GrPaint* grp,
const SkStrokeRec& strokeRec,
const SkPath& path) const;
+ /**
+ * Try to directly render a rounded rect mask filter into the target. Returns
+ * true if drawing was successful.
+ */
+ virtual bool directFilterRRectMaskGPU(GrContext* context,
+ GrPaint* grp,
+ const SkStrokeRec& strokeRec,
+ const SkRRect& rrect) const;
/**
* This function is used to implement filters that require an explicit src mask. It should only
diff --git a/include/core/SkRRect.h b/include/core/SkRRect.h
index c996346442..9878b54fdc 100644
--- a/include/core/SkRRect.h
+++ b/include/core/SkRRect.h
@@ -101,6 +101,8 @@ public:
}
inline bool isComplex() const { return kComplex_Type == this->getType(); }
+ bool allCornersCircular() const;
+
SkScalar width() const { return fRect.width(); }
SkScalar height() const { return fRect.height(); }
diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp
index b96743d129..9b023d0d65 100644
--- a/src/core/SkMaskFilter.cpp
+++ b/src/core/SkMaskFilter.cpp
@@ -317,6 +317,13 @@ bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds,
}
+bool SkMaskFilter::directFilterRRectMaskGPU(GrContext* context,
+ GrPaint* grp,
+ const SkStrokeRec& strokeRec,
+ const SkRRect& rrect) const {
+ return false;
+}
+
bool SkMaskFilter::filterMaskGPU(GrTexture* src,
const SkMatrix& ctm,
const SkRect& maskRect,
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index e5296d4e3a..915ed75327 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -172,6 +172,13 @@ bool SkRRect::checkCornerContainment(SkScalar x, SkScalar y) const {
return dist <= SkScalarSquare(SkScalarMul(fRadii[index].fX, fRadii[index].fY));
}
+bool SkRRect::allCornersCircular() const {
+ return fRadii[0].fX == fRadii[0].fY &&
+ fRadii[1].fX == fRadii[1].fY &&
+ fRadii[2].fX == fRadii[2].fY &&
+ fRadii[3].fX == fRadii[3].fY;
+}
+
bool SkRRect::contains(const SkRect& rect) const {
if (!this->getBounds().contains(rect)) {
// If 'rect' isn't contained by the RR's bounds then the
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 2d7ff18fdb..63032dbc29 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -45,6 +45,10 @@ public:
GrPaint* grp,
const SkStrokeRec& strokeRec,
const SkPath& path) const SK_OVERRIDE;
+ virtual bool directFilterRRectMaskGPU(GrContext* context,
+ GrPaint* grp,
+ const SkStrokeRec& strokeRec,
+ const SkRRect& rrect) const SK_OVERRIDE;
virtual bool filterMaskGPU(GrTexture* src,
const SkMatrix& ctm,
@@ -815,6 +819,13 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context,
return true;
}
+bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
+ GrPaint* grp,
+ const SkStrokeRec& strokeRec,
+ const SkRRect& rrect) const {
+ return false;
+}
+
bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds,
const SkIRect& clipBounds,
const SkMatrix& ctm,
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 7cecf25bb2..82862414fc 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -19,11 +19,13 @@
#include "SkGrTexturePixelRef.h"
+#include "SkBounder.h"
#include "SkColorFilter.h"
#include "SkDeviceImageFilterProxy.h"
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
#include "SkImageFilter.h"
+#include "SkMaskFilter.h"
#include "SkPathEffect.h"
#include "SkRRect.h"
#include "SkStroke.h"
@@ -739,6 +741,44 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw, false);
+ GrPaint grPaint;
+ if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
+ return;
+ }
+
+ SkStrokeRec stroke(paint);
+ if (paint.getMaskFilter()) {
+ // try to hit the fast path for drawing filtered round rects
+
+ SkRRect devRRect;
+ if (rect.transform(fContext->getMatrix(), &devRRect)) {
+ if (devRRect.allCornersCircular()) {
+ SkRect maskRect;
+ if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(),
+ draw.fClip->getBounds(),
+ fContext->getMatrix(),
+ &maskRect)) {
+ SkIRect finalIRect;
+ maskRect.roundOut(&finalIRect);
+ if (draw.fClip->quickReject(finalIRect)) {
+ // clipped out
+ return;
+ }
+ if (NULL != draw.fBounder && !draw.fBounder->doIRect(finalIRect)) {
+ // nothing to draw
+ return;
+ }
+ if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, &grPaint,
+ stroke, devRRect)) {
+ return;
+ }
+ }
+
+ }
+ }
+
+ }
+
bool usePath = !rect.isSimple();
// another two reasons we might need to call drawPath...
if (paint.getMaskFilter() || paint.getPathEffect()) {
@@ -756,16 +796,10 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
return;
}
- GrPaint grPaint;
- if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
- return;
- }
-
- SkStrokeRec stroke(paint);
fContext->drawRRect(grPaint, rect, stroke);
}
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
const SkPaint& paint) {
@@ -1011,7 +1045,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
}
if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint,
- SkStrokeRec(paint), *devPathPtr)) {
+ stroke, *devPathPtr)) {
// the mask filter was able to draw itself directly, so there's nothing
// left to do.
return;