Fix saveLayer() clipping w/filters, GPU path.
authorsenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 24 Feb 2014 15:16:42 +0000 (15:16 +0000)
committersenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 24 Feb 2014 15:16:42 +0000 (15:16 +0000)
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
src/core/SkCanvas.cpp
tests/CanvasStateTest.cpp

index 2ad81f0..40bcd3a 100644 (file)
@@ -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
index d889174..1e9dda3 100644 (file)
@@ -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) {
index 29e67f2..3c7552f 100644 (file)
@@ -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);
 }