From 6930285b73b260f81aa6bd1e30f33e12869c1fe5 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Wed, 16 Feb 2011 18:08:07 +0000 Subject: first steps for supporting maskfilters (disabled right now) git-svn-id: http://skia.googlecode.com/svn/trunk@801 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/SkGpuDevice.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index cc7cb7bb59..b887679621 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -647,9 +647,16 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, /* We have special code for hairline strokes, miter-strokes, and fills. - Anything else we just call our path code. (i.e. non-miter thick stroke) + Anything else we just call our path code. */ - if (doStroke && width > 0 && paint.getStrokeJoin() != SkPaint::kMiter_Join) { + bool usePath = doStroke && width > 0 && + paint.getStrokeJoin() != SkPaint::kMiter_Join; + // another reason we might need to call drawPath... + if (paint.getMaskFilter()) { + usePath = true; + } + + if (usePath) { SkPath path; path.addRect(rect); this->drawPath(draw, path, paint, NULL, true); @@ -664,6 +671,75 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, fContext->drawRect(grPaint, Sk2Gr(rect), doStroke ? width : -1); } +#include "SkMaskFilter.h" +#include "SkBounder.h" + +#ifdef HANDLE_MASKFILTER +// modified from SkMaskFilter::filterPath() +static bool drawWithMaskFilter(GrContext* context, const SkPath& path, + SkMaskFilter* filter, const SkMatrix& matrix, + const SkRegion& clip, SkBounder* bounder, + GrPaint* grp) { + SkMask srcM, dstM; + + if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM, + SkMask::kComputeBoundsAndRenderImage_CreateMode)) { + return false; + } + + SkAutoMaskImage autoSrc(&srcM, false); + + if (!filter->filterMask(&dstM, srcM, matrix, NULL)) { + return false; + } + // this will free-up dstM when we're done (allocated in filterMask()) + SkAutoMaskImage autoDst(&dstM, false); + + if (clip.quickReject(dstM.fBounds)) { + return false; + } + if (bounder && !bounder->doIRect(dstM.fBounds)) { + return false; + } + + // we now have a device-aligned 8bit mask in dstM, ready to be drawn using + // the current clip (and identity matrix) and grpaint settings + + GrAutoMatrix avm(fContext, GrMatrix::I()); + + const GrGpu::TextureDesc desc = { + 0, + GrGpu::kNone_AALevel, + dstM.fBounds.width(), + dstM.fBounds.height(), + GrTexture::kAlpha_8_PixelConfig + }; + + GrTexture* texture = context->createUncachedTexture(desc, dstM.fImage, + dstM.fRowBytes); + if (NULL == texture) { + return false; + } + + grp->setMask(texture)->unref(); + grp->fMaskSampler.setClampNoFilter(); + grp->fMaskMatrix.setIdentity(); + + SkPoint max; + max.set(SkFixedToScalar((texture->contentWidth() << 16) / + texture->allocWidth()), + SkFixedToScalar((texture->contentHeight() << 16) / + texture->allocHeight())); + + fContext->drawRectToRect(*grp, + GrRect(GrIntToScalar(left), GrIntToScalar(top), + GrIntToScalar(left + bitmap.width()), + GrIntToScalar(top + bitmap.height())), + GrRect(0, 0, max.fX, max.fY)); + return true; +} +#endif + void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint& paint, const SkMatrix* prePathMatrix, bool pathIsMutable) { @@ -687,6 +763,14 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& path, } } +#ifdef HANDLE_MASKFILTER + if (paint.getMaskFilter()) { + drawWithMaskFilter(fContext, *pathPtr, paint.getMaskFilter(), + *draw.fMatrix, *draw.fClip, draw.fBounder, &grPaint); + return; + } +#endif + SkPath fillPath; GrContext::PathFills fill = GrContext::kHairLine_PathFill; -- cgit v1.2.3