author | Matt Woodrow <mwoodrow@mozilla.com> |
Thu, 27 Jun 2013 11:22:09 +1200 | |
changeset 139189 | b3d8eb2515762b43bf2d2e9b42df39ab4a87f474 |
parent 139188 | 2293c4eea18e45c1d8ee9e06e65e2c297acd9ed4 |
child 139190 | ad853510b4d5ad26254efd2faa7a80112d69791b |
push id | 24980 |
push user | ryanvm@gmail.com |
push date | Fri, 19 Jul 2013 17:42:29 +0000 |
treeherder | mozilla-central@0983f1a0961c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | snorp |
bugs | 884888 |
milestone | 25.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/skia/src/gpu/SkGpuDevice.cpp +++ b/gfx/skia/src/gpu/SkGpuDevice.cpp @@ -18,16 +18,17 @@ #include "SkColorFilter.h" #include "SkDeviceImageFilterProxy.h" #include "SkDrawProcs.h" #include "SkGlyphCache.h" #include "SkImageFilter.h" #include "SkPathEffect.h" #include "SkStroke.h" #include "SkUtils.h" +#include "SkRasterizer.h" #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 #if 0 extern bool (*gShouldDrawProc)(); #define CHECK_SHOULD_DRAW(draw, forceI) \ do { \ if (gShouldDrawProc && !gShouldDrawProc()) return; \ @@ -662,18 +663,20 @@ void SkGpuDevice::drawRect(const SkDraw& SkScalar width = paint.getStrokeWidth(); /* We have special code for hairline strokes, miter-strokes, and fills. Anything else we just call our path code. */ bool usePath = doStroke && width > 0 && paint.getStrokeJoin() != SkPaint::kMiter_Join; - // another two reasons we might need to call drawPath... - if (paint.getMaskFilter() || paint.getPathEffect()) { + // another three reasons we might need to call drawPath... + if (paint.getMaskFilter() || + paint.getPathEffect() || + paint.getRasterizer()) { usePath = true; } // until we aa rotated rects... if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) { usePath = true; } // small miter limit means right angles show bevel... if (SkPaint::kMiter_Join == paint.getStrokeJoin() && @@ -744,32 +747,43 @@ inline bool shouldDrawBlurWithCPU(const if (rect.width() <= MIN_GPU_BLUR_SIZE && rect.height() <= MIN_GPU_BLUR_SIZE && radius <= MIN_GPU_BLUR_RADIUS) { return true; } return false; } -bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkStrokeRec& stroke, - SkMaskFilter* filter, const SkRegion& clip, +bool drawWithGPUMaskFilter(GrContext* context, SkPath& path, bool pathIsMutable, + const SkStrokeRec& stroke, SkMaskFilter* filter, + SkRasterizer *rasterizer, const SkRegion& clip, SkBounder* bounder, GrPaint* grp) { + if (rasterizer) { + return false; + } + SkMaskFilter::BlurInfo info; SkMaskFilter::BlurType blurType = filter->asABlur(&info); if (SkMaskFilter::kNone_BlurType == blurType) { return false; } SkScalar radius = info.fIgnoreTransform ? info.fRadius : context->getMatrix().mapRadius(info.fRadius); radius = SkMinScalar(radius, MAX_BLUR_RADIUS); if (radius <= 0) { return false; } - SkRect srcRect = devPath.getBounds(); + SkPath tmpPath; + SkPath* devPathPtr = pathIsMutable ? &path : &tmpPath; + + // transform the path into device space + path.transform(context->getMatrix(), devPathPtr); + + SkRect srcRect = devPathPtr->getBounds(); if (shouldDrawBlurWithCPU(srcRect, radius)) { return false; } float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE; float sigma3 = sigma * 3.0f; SkRect clipRect; @@ -829,17 +843,17 @@ bool drawWithGPUMaskFilter(GrContext* co } GrContext::AutoMatrix am; // Draw hard shadow to pathTexture with path top-left at origin using tempPaint. SkMatrix translate; translate.setTranslate(offset.fX, offset.fY); am.set(context, translate); - context->drawPath(tempPaint, devPath, stroke); + context->drawPath(tempPaint, *devPathPtr, stroke); // If we're doing a normal blur, we can clobber the pathTexture in the // gaussianBlur. Otherwise, we need to save it for later compositing. bool isNormalBlur = blurType == SkMaskFilter::kNormal_BlurType; blurTexture.reset(context->gaussianBlur(pathTexture, isNormalBlur, srcRect, sigma, sigma)); if (NULL == blurTexture) { return false; @@ -885,32 +899,52 @@ bool drawWithGPUMaskFilter(GrContext* co grp->coverageStage(MASK_IDX)->reset(); grp->coverageStage(MASK_IDX)->setEffect( GrSimpleTextureEffect::Create(blurTexture, matrix))->unref(); context->drawRect(*grp, finalRect); return true; } -bool drawWithMaskFilter(GrContext* context, const SkPath& devPath, - SkMaskFilter* filter, const SkRegion& clip, SkBounder* bounder, +bool drawWithMaskFilter(GrContext* context, SkPath& path, bool pathIsMutable, + SkMaskFilter* filter, SkRasterizer* rasterizer, + const SkRegion& clip, SkBounder* bounder, GrPaint* grp, SkPaint::Style style) { SkMask srcM, dstM; - if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM, - SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) { - return false; + if (rasterizer) { + if (!rasterizer->rasterize(path, context->getMatrix(), + &clip.getBounds(), filter, &srcM, + SkMask::kComputeBoundsAndRenderImage_CreateMode)) { + return false; + } + } else { + SkPath tmpPath; + SkPath* devPathPtr = pathIsMutable ? &path : &tmpPath; + + // transform the path into device space + path.transform(context->getMatrix(), devPathPtr); + if (!SkDraw::DrawToMask(*devPathPtr, &clip.getBounds(), filter, &context->getMatrix(), + &srcM, SkMask::kComputeBoundsAndRenderImage_CreateMode, + style)) { + return false; + } } SkAutoMaskFreeImage autoSrc(srcM.fImage); - if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) { + if (filter && !filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) { return false; + } else if (!filter) { + dstM = srcM; } - // this will free-up dstM when we're done (allocated in filterMask()) - SkAutoMaskFreeImage autoDst(dstM.fImage); + + // this will free-up dstM when we're done (allocated in filterMask()). + // If we don't have a filter, then srcM and dstM are the same, so + // don't free it twice. + SkAutoMaskFreeImage autoDst(filter ? dstM.fImage : NULL); if (clip.quickReject(dstM.fBounds)) { return false; } if (bounder && !bounder->doIRect(dstM.fBounds)) { return false; } @@ -1003,34 +1037,32 @@ void SkGpuDevice::drawPath(const SkDraw& cullRect)) { pathPtr = &effectPath; } if (!pathEffect && doHairLine) { stroke.setHairlineStyle(); } - if (paint.getMaskFilter()) { + if (paint.getMaskFilter() || paint.getRasterizer()) { if (!stroke.isHairlineStyle()) { if (stroke.applyToPath(&tmpPath, *pathPtr)) { pathPtr = &tmpPath; stroke.setFillStyle(); } } - // avoid possibly allocating a new path in transform if we can - SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; - - // transform the path into device space - pathPtr->transform(fContext->getMatrix(), devPathPtr); - if (!drawWithGPUMaskFilter(fContext, *devPathPtr, stroke, paint.getMaskFilter(), - *draw.fClip, draw.fBounder, &grPaint)) { + if (!drawWithGPUMaskFilter(fContext, *pathPtr, pathIsMutable, + stroke, paint.getMaskFilter(), + paint.getRasterizer(), *draw.fClip, + draw.fBounder, &grPaint)) { SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : SkPaint::kFill_Style; - drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(), + drawWithMaskFilter(fContext, *pathPtr, pathIsMutable, + paint.getMaskFilter(), paint.getRasterizer(), *draw.fClip, draw.fBounder, &grPaint, style); } return; } fContext->drawPath(grPaint, *pathPtr, stroke); }