From 3833daaa663db7e655a8077cdab42cca19d3a276 Mon Sep 17 00:00:00 2001 From: robertphillips Date: Mon, 14 Sep 2015 11:18:13 -0700 Subject: [PATCH] Fix GPU-only snapping bug in mask blur rendering The existing mask effect code in Ganesh is subject to snapping issues (when the created mask is redrawn). This artifact can be seen by rendering the original geometry (w/o blurs) and comparing that result to a rendering of the unblurred masks. W/o this patch the results do not match up (they are arbitrarily shifted by a pixel). This patch will require rebaselining and suppressions. Chromium layout tests suppressions are here: https://codereview.chromium.org/1342683003/ (Add layout test suppressions for upcoming Skia roll) Review URL: https://codereview.chromium.org/1338183002 --- src/gpu/GrBlurUtils.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp index 039a12c3c8..a96d92e764 100644 --- a/src/gpu/GrBlurUtils.cpp +++ b/src/gpu/GrBlurUtils.cpp @@ -97,15 +97,20 @@ static bool draw_with_mask_filter(GrDrawContext* drawContext, // Create a mask of 'devPath' and place the result in 'mask'. static GrTexture* create_mask_GPU(GrContext* context, - const SkRect& maskRect, + SkRect* maskRect, const SkPath& devPath, const GrStrokeInfo& strokeInfo, bool doAA, int sampleCnt) { + // This mask will ultimately be drawn as a non-AA rect (see draw_mask). + // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here + // so the mask draws in a reproducible manner. + *maskRect = SkRect::Make(maskRect->roundOut()); + GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; - desc.fWidth = SkScalarCeilToInt(maskRect.width()); - desc.fHeight = SkScalarCeilToInt(maskRect.height()); + desc.fWidth = SkScalarCeilToInt(maskRect->width()); + desc.fHeight = SkScalarCeilToInt(maskRect->height()); desc.fSampleCnt = doAA ? sampleCnt : 0; // We actually only need A8, but it often isn't supported as a // render target so default to RGBA_8888 @@ -120,7 +125,7 @@ static GrTexture* create_mask_GPU(GrContext* context, return nullptr; } - SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); + SkRect clipRect = SkRect::MakeWH(maskRect->width(), maskRect->height()); SkAutoTUnref drawContext(context->drawContext()); if (!drawContext) { @@ -136,9 +141,10 @@ static GrTexture* create_mask_GPU(GrContext* context, // setup new clip GrClip clip(clipRect); - // Draw the mask into maskTexture with the path's top-left at the origin using tempPaint. + // Draw the mask into maskTexture with the path's integerized top-left at + // the origin using tempPaint. SkMatrix translate; - translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); + translate.setTranslate(-maskRect->fLeft, -maskRect->fTop); drawContext->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, devPath, strokeInfo); return mask; } @@ -254,7 +260,7 @@ void GrBlurUtils::drawPathWithMaskFilter(GrContext* context, } SkAutoTUnref mask(create_mask_GPU(context, - maskRect, + &maskRect, *devPathPtr, strokeInfo, grPaint.isAntiAlias(),