aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-02-16 18:08:07 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-02-16 18:08:07 +0000
commit6930285b73b260f81aa6bd1e30f33e12869c1fe5 (patch)
tree92cf41badf8cbf26c58a746671c267ce155c3951
parent86afc2ae27fec84c01eb0e81a32766bdaf67dca8 (diff)
first steps for supporting maskfilters (disabled right now)
git-svn-id: http://skia.googlecode.com/svn/trunk@801 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/gpu/SkGpuDevice.cpp88
1 files 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;