From 89f077ced4918ded7e911bc5052b61c90ad57a9a Mon Sep 17 00:00:00 2001 From: "senorblanco@chromium.org" Date: Mon, 24 Feb 2014 15:16:42 +0000 Subject: [PATCH] Fix saveLayer() clipping w/filters, GPU path. Don't modify the clipstack in saveLayer() if the kClipToLayer_SaveFlag is not set. Without this the GPU path will clip the offscreen to the layer's bounds, even if the flag is not set. R=robertphillips@google.com BUG=skia: Review URL: https://codereview.chromium.org/164203002 git-svn-id: http://skia.googlecode.com/svn/trunk@13561 2bbb7eff-a529-9590-31e7-b0007b416f81 --- expectations/gm/ignored-tests.txt | 5 +++++ src/core/SkCanvas.cpp | 12 +++++------ tests/CanvasStateTest.cpp | 34 +++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt index 2ad81f0882..40bcd3a26b 100644 --- a/expectations/gm/ignored-tests.txt +++ b/expectations/gm/ignored-tests.txt @@ -59,3 +59,8 @@ imagefiltersscaled # Added by yunchao.he@intel.com for https://codereview.chromium.org/166023002 inverse_paths + +# Added by senorblanco as part of https://codereview.chromium.org/164203002/ +# This one gets PDF result closer to 8888 than it was before (only one bar +# different from 8888 vs three before). +canvas-layer-state diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index d889174a2a..1e9dda3098 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -780,12 +780,12 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, ir = clipBounds; } - fClipStack.clipDevRect(ir, op); - - // early exit if the clip is now empty - if (bounds_affects_clip(flags) && - !fMCRec->fRasterClip->op(ir, op)) { - return false; + if (bounds_affects_clip(flags)) { + fClipStack.clipDevRect(ir, op); + // early exit if the clip is now empty + if (!fMCRec->fRasterClip->op(ir, op)) { + return false; + } } if (intersection) { diff --git a/tests/CanvasStateTest.cpp b/tests/CanvasStateTest.cpp index 29e67f2e14..3c7552fce3 100644 --- a/tests/CanvasStateTest.cpp +++ b/tests/CanvasStateTest.cpp @@ -228,9 +228,43 @@ static void test_soft_clips(skiatest::Reporter* reporter) { SkClearLastError(); } +static void test_saveLayer_clip(skiatest::Reporter* reporter) { + const int WIDTH = 100; + const int HEIGHT = 100; + const int LAYER_WIDTH = 50; + const int LAYER_HEIGHT = 50; + + SkBitmap bitmap; + bitmap.allocN32Pixels(WIDTH, HEIGHT); + SkCanvas canvas(bitmap); + + SkRect bounds = SkRect::MakeWH(SkIntToScalar(LAYER_WIDTH), SkIntToScalar(LAYER_HEIGHT)); + canvas.clipRect(SkRect::MakeWH(SkIntToScalar(WIDTH), SkIntToScalar(HEIGHT))); + + // Check that saveLayer without the kClipToLayer_SaveFlag leaves the + // clip stack unchanged. + canvas.saveLayer(&bounds, NULL, SkCanvas::kARGB_NoClipLayer_SaveFlag); + SkRect clipStackBounds; + SkClipStack::BoundsType boundsType; + canvas.getClipStack()->getBounds(&clipStackBounds, &boundsType); + REPORTER_ASSERT(reporter, clipStackBounds.width() == WIDTH); + REPORTER_ASSERT(reporter, clipStackBounds.height() == HEIGHT); + canvas.restore(); + + // Check that saveLayer with the kClipToLayer_SaveFlag sets the clip + // stack to the layer bounds. + canvas.saveLayer(&bounds, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); + canvas.getClipStack()->getBounds(&clipStackBounds, &boundsType); + REPORTER_ASSERT(reporter, clipStackBounds.width() == LAYER_WIDTH); + REPORTER_ASSERT(reporter, clipStackBounds.height() == LAYER_HEIGHT); + + canvas.restore(); +} + DEF_TEST(CanvasState, reporter) { test_complex_layers(reporter); test_complex_clips(reporter); test_draw_filters(reporter); test_soft_clips(reporter); + test_saveLayer_clip(reporter); }