summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-01 13:18:30 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-01 13:18:30 +0000
commit8765dcb4accfde35362c34eb32614a17f16b700d (patch)
treeaed584b3e0e46a71840f988e3d7f97b7a33b8a22
parent74719923dedc68db453f366de6bb0acf66d8516b (diff)
downloadchromium_src-8765dcb4accfde35362c34eb32614a17f16b700d.zip
chromium_src-8765dcb4accfde35362c34eb32614a17f16b700d.tar.gz
chromium_src-8765dcb4accfde35362c34eb32614a17f16b700d.tar.bz2
cc: Fix PicturePile clearing for non-origin canvases
When canvases are larger than content, and content is stretched and terminates on a non-integer pixel boundary, then the area underneath that content must be cleared first. The clearing code attempted to clear a 2 pixel wide strip, but was not translating it, so it only worked for canvases located at the origin. R=brianderson@chromium.org BUG=296672 Review URL: https://codereview.chromium.org/51433003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232349 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/resources/picture_pile_impl.cc5
-rw-r--r--cc/resources/picture_pile_impl_unittest.cc79
2 files changed, 55 insertions, 29 deletions
diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc
index 3d0f5ec..3411b7f 100644
--- a/cc/resources/picture_pile_impl.cc
+++ b/cc/resources/picture_pile_impl.cc
@@ -112,18 +112,17 @@ void PicturePileImpl::RasterToBitmap(
gfx::SizeF total_content_size = gfx::ScaleSize(tiling_.total_size(),
contents_scale);
gfx::Rect content_rect(gfx::ToCeiledSize(total_content_size));
- gfx::Rect deflated_content_rect = content_rect;
- content_rect.Intersect(canvas_rect);
// The final texel of content may only be partially covered by a
// rasterization; this rect represents the content rect that is fully
// covered by content.
+ gfx::Rect deflated_content_rect = content_rect;
deflated_content_rect.Inset(0, 0, 1, 1);
- deflated_content_rect.Intersect(canvas_rect);
if (!deflated_content_rect.Contains(canvas_rect)) {
// Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X
// faster than clearing, so special case this.
canvas->save();
+ canvas->translate(-canvas_rect.x(), -canvas_rect.y());
gfx::Rect inflated_content_rect = content_rect;
inflated_content_rect.Inset(0, 0, -1, -1);
canvas->clipRect(gfx::RectToSkRect(inflated_content_rect),
diff --git a/cc/resources/picture_pile_impl_unittest.cc b/cc/resources/picture_pile_impl_unittest.cc
index c68b185..16a875e 100644
--- a/cc/resources/picture_pile_impl_unittest.cc
+++ b/cc/resources/picture_pile_impl_unittest.cc
@@ -635,49 +635,76 @@ TEST(PicturePileImplTest, PixelRefIteratorLazyRefsBaseNonLazy) {
}
}
+// Note: this test will always pass in debug because the canvas is cleared
+// to the NonPaintedFillColor first.
TEST(PicturePileImpl, RasterContentsOpaque) {
gfx::Size tile_size(1000, 1000);
gfx::Size layer_bounds(3, 5);
float contents_scale = 1.5f;
+ float raster_divisions = 2.f;
scoped_refptr<FakePicturePileImpl> pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
// Because the caller sets content opaque, it also promises that it
// has at least filled in layer_bounds opaquely.
- SkPaint red_paint;
- red_paint.setColor(SK_ColorRED);
- pile->add_draw_rect_with_paint(gfx::Rect(layer_bounds), red_paint);
+ SkPaint white_paint;
+ white_paint.setColor(SK_ColorWHITE);
+ pile->add_draw_rect_with_paint(gfx::Rect(layer_bounds), white_paint);
pile->SetMinContentsScale(contents_scale);
- pile->set_background_color(SK_ColorRED);
+ pile->set_background_color(SK_ColorBLACK);
pile->set_contents_opaque(true);
pile->RerecordPile();
gfx::Size content_bounds(
gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
- // Simulate a canvas rect larger than the content bounds. Every pixel
- // up to one pixel outside the content bounds is guaranteed to be opaque.
- // Outside of that is undefined.
- gfx::Rect canvas_rect(content_bounds);
- canvas_rect.Inset(0, 0, -1, -1);
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- canvas_rect.width(),
- canvas_rect.height());
- bitmap.allocPixels();
- SkCanvas canvas(bitmap);
-
- FakeRenderingStatsInstrumentation rendering_stats_instrumentation;
-
- pile->RasterToBitmap(
- &canvas, canvas_rect, contents_scale, &rendering_stats_instrumentation);
-
- SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
- int num_pixels = bitmap.width() * bitmap.height();
- for (int i = 0; i < num_pixels; ++i) {
- EXPECT_EQ(SkColorGetA(pixels[i]), 255u);
+ // Simulate drawing into different tiles at different offsets.
+ int step_x = std::ceil(content_bounds.width() / raster_divisions);
+ int step_y = std::ceil(content_bounds.height() / raster_divisions);
+ for (int offset_x = 0; offset_x < content_bounds.width();
+ offset_x += step_x) {
+ for (int offset_y = 0; offset_y < content_bounds.height();
+ offset_y += step_y) {
+ gfx::Rect content_rect(offset_x, offset_y, step_x, step_y);
+ content_rect.Intersect(gfx::Rect(content_bounds));
+
+ // Simulate a canvas rect larger than the content rect. Every pixel
+ // up to one pixel outside the content rect is guaranteed to be opaque.
+ // Outside of that is undefined.
+ gfx::Rect canvas_rect(content_rect);
+ canvas_rect.Inset(0, 0, -1, -1);
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ canvas_rect.width(),
+ canvas_rect.height());
+ bitmap.allocPixels();
+ SkCanvas canvas(bitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+
+ FakeRenderingStatsInstrumentation rendering_stats_instrumentation;
+
+ pile->RasterToBitmap(&canvas,
+ canvas_rect,
+ contents_scale,
+ &rendering_stats_instrumentation);
+
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ int num_pixels = bitmap.width() * bitmap.height();
+ bool all_white = true;
+ for (int i = 0; i < num_pixels; ++i) {
+ EXPECT_EQ(SkColorGetA(pixels[i]), 255u);
+ all_white &= (SkColorGetR(pixels[i]) == 255);
+ all_white &= (SkColorGetG(pixels[i]) == 255);
+ all_white &= (SkColorGetB(pixels[i]) == 255);
+ }
+
+ // If the canvas doesn't extend past the edge of the content,
+ // it should be entirely white. Otherwise, the edge of the content
+ // will be non-white.
+ EXPECT_EQ(all_white, gfx::Rect(content_bounds).Contains(canvas_rect));
+ }
}
}