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
This commit is contained in:
senorblanco@chromium.org 2014-02-24 15:16:42 +00:00
parent f54ea1073b
commit 89f077ced4
3 changed files with 45 additions and 6 deletions

View File

@ -59,3 +59,8 @@ imagefiltersscaled
# Added by yunchao.he@intel.com for https://codereview.chromium.org/166023002 # Added by yunchao.he@intel.com for https://codereview.chromium.org/166023002
inverse_paths 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

View File

@ -780,12 +780,12 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
ir = clipBounds; ir = clipBounds;
} }
fClipStack.clipDevRect(ir, op); if (bounds_affects_clip(flags)) {
fClipStack.clipDevRect(ir, op);
// early exit if the clip is now empty // early exit if the clip is now empty
if (bounds_affects_clip(flags) && if (!fMCRec->fRasterClip->op(ir, op)) {
!fMCRec->fRasterClip->op(ir, op)) { return false;
return false; }
} }
if (intersection) { if (intersection) {

View File

@ -228,9 +228,43 @@ static void test_soft_clips(skiatest::Reporter* reporter) {
SkClearLastError(); 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) { DEF_TEST(CanvasState, reporter) {
test_complex_layers(reporter); test_complex_layers(reporter);
test_complex_clips(reporter); test_complex_clips(reporter);
test_draw_filters(reporter); test_draw_filters(reporter);
test_soft_clips(reporter); test_soft_clips(reporter);
test_saveLayer_clip(reporter);
} }