diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-10 22:53:20 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-10 22:53:20 +0000 |
commit | 821397018fdabea6b434ecb96f84fb5449c4025f (patch) | |
tree | 7b6a3b536f4be38a6a9ea0691358e612db448f40 /src | |
parent | 45b9de81bce1d5edb72815146d45e688ea3090a0 (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
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkMaskFilter.cpp | 7 | ||||
-rw-r--r-- | src/core/SkRRect.cpp | 7 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 11 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 50 |
4 files changed, 67 insertions, 8 deletions
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; |