summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DEPS2
-rw-r--r--cc/picture.cc9
-rw-r--r--cc/picture.h5
-rw-r--r--cc/picture_layer.cc6
-rw-r--r--cc/picture_layer_impl_unittest.cc99
-rw-r--r--cc/picture_pile.cc2
-rw-r--r--cc/picture_pile_base.cc20
-rw-r--r--cc/picture_pile_base.h3
-rw-r--r--cc/test/fake_content_layer_client.cc24
-rw-r--r--cc/test/fake_content_layer_client.h16
10 files changed, 160 insertions, 26 deletions
diff --git a/DEPS b/DEPS
index 9e28409..352d6a92 100644
--- a/DEPS
+++ b/DEPS
@@ -29,7 +29,7 @@ vars = {
"ffmpeg_hash": "bb82a38d45e65c1fba378c15180b98ad76ebe1ca",
"sfntly_revision": "134",
- "skia_revision": "7869",
+ "skia_revision": "7896",
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling Skia
# and V8 without interference from each other.
diff --git a/cc/picture.cc b/cc/picture.cc
index c8fd76f..dbb2b08 100644
--- a/cc/picture.cc
+++ b/cc/picture.cc
@@ -9,7 +9,6 @@
#include "skia/ext/analysis_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkData.h"
-#include "third_party/skia/include/core/SkTileGridPicture.h"
#include "third_party/skia/include/utils/SkPictureUtils.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"
@@ -17,8 +16,6 @@
namespace {
// URI label for a lazily decoded SkPixelRef.
const char labelLazyDecoded[] = "lazy";
-// Tile size in recording coordinates used by SkTileGridPicture
-const int tileGridSize = 256;
}
namespace cc {
@@ -51,14 +48,16 @@ scoped_refptr<Picture> Picture::Clone() const {
}
void Picture::Record(ContentLayerClient* painter,
- RenderingStats* stats) {
+ RenderingStats* stats,
+ const SkTileGridPicture::TileGridInfo& tileGridInfo) {
TRACE_EVENT2("cc", "Picture::Record",
"width", layer_rect_.width(), "height", layer_rect_.height());
// Record() should only be called once.
DCHECK(!picture_);
+ DCHECK(!tileGridInfo.fTileInterval.isEmpty());
picture_ = skia::AdoptRef(new SkTileGridPicture(
- tileGridSize, tileGridSize, layer_rect_.width(), layer_rect_.height()));
+ layer_rect_.width(), layer_rect_.height(), tileGridInfo));
SkCanvas* canvas = picture_->beginRecording(
layer_rect_.width(),
diff --git a/cc/picture.h b/cc/picture.h
index 118bcb3..2d01b26 100644
--- a/cc/picture.h
+++ b/cc/picture.h
@@ -12,8 +12,8 @@
#include "cc/cc_export.h"
#include "skia/ext/lazy_pixel_ref.h"
#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/core/SkTileGridPicture.h"
#include "ui/gfx/rect.h"
namespace cc {
@@ -34,7 +34,8 @@ class CC_EXPORT Picture
// Record a paint operation. To be able to safely use this SkPicture for
// playback on a different thread this can only be called once.
- void Record(ContentLayerClient*, RenderingStats*);
+ void Record(ContentLayerClient*, RenderingStats*,
+ const SkTileGridPicture::TileGridInfo& tileGridInfo);
// Has Record() been called yet?
bool HasRecording() const { return picture_.get() != NULL; }
diff --git a/cc/picture_layer.cc b/cc/picture_layer.cc
index 8c5bc91..348d952 100644
--- a/cc/picture_layer.cc
+++ b/cc/picture_layer.cc
@@ -48,8 +48,10 @@ void PictureLayer::pushPropertiesTo(LayerImpl* base_layer) {
void PictureLayer::setLayerTreeHost(LayerTreeHost* host) {
Layer::setLayerTreeHost(host);
- if (host)
- pile_->SetMinContentsScale(host->settings().minimumContentsScale);
+ if (host) {
+ pile_->SetMinContentsScale(host->settings().minimumContentsScale);
+ pile_->SetTileGridSize(host->settings().defaultTileSize);
+ }
}
void PictureLayer::setNeedsDisplayRect(const gfx::RectF& layer_rect) {
diff --git a/cc/picture_layer_impl_unittest.cc b/cc/picture_layer_impl_unittest.cc
index b4b9f4c..02b59da 100644
--- a/cc/picture_layer_impl_unittest.cc
+++ b/cc/picture_layer_impl_unittest.cc
@@ -5,6 +5,7 @@
#include "cc/picture_layer_impl.h"
#include "cc/layer_tree_impl.h"
+#include "cc/picture_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
@@ -51,6 +52,13 @@ class TestablePictureLayerImpl : public PictureLayerImpl {
}
};
+class ImplSidePaintingSettings : public LayerTreeSettings {
+ public:
+ ImplSidePaintingSettings() {
+ implSidePainting = true;
+ }
+};
+
class TestablePicturePileImpl : public PicturePileImpl {
public:
static scoped_refptr<TestablePicturePileImpl> CreateFilledPile(
@@ -59,6 +67,7 @@ class TestablePicturePileImpl : public PicturePileImpl {
scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl());
pile->tiling().SetTotalSize(layer_bounds);
pile->tiling().SetMaxTextureSize(tile_size);
+ pile->SetTileGridSize(ImplSidePaintingSettings().defaultTileSize);
for (int x = 0; x < pile->tiling().num_tiles_x(); ++x) {
for (int y = 0; y < pile->tiling().num_tiles_y(); ++y)
pile->AddRecordingAt(x, y);
@@ -73,6 +82,7 @@ class TestablePicturePileImpl : public PicturePileImpl {
scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl());
pile->tiling().SetTotalSize(layer_bounds);
pile->tiling().SetMaxTextureSize(tile_size);
+ pile->SetTileGridSize(ImplSidePaintingSettings().defaultTileSize);
pile->UpdateRecordedRegion();
return pile;
}
@@ -89,8 +99,7 @@ class TestablePicturePileImpl : public PicturePileImpl {
return;
gfx::Rect bounds(tiling().TileBounds(x, y));
scoped_refptr<Picture> picture(Picture::Create(bounds));
- FakeContentLayerClient client;
- picture->Record(&client, NULL);
+ picture->Record(&client_, NULL, tile_grid_info_);
picture_list_map_[std::pair<int, int>(x, y)].push_back(picture);
EXPECT_TRUE(HasRecordingAt(x, y));
@@ -111,16 +120,27 @@ class TestablePicturePileImpl : public PicturePileImpl {
UpdateRecordedRegion();
}
+ void addDrawRect(const gfx::Rect& rect) {
+ client_.addDrawRect(rect);
+ }
+
protected:
virtual ~TestablePicturePileImpl() {
}
+
+ FakeContentLayerClient client_;
};
-class ImplSidePaintingSettings : public LayerTreeSettings {
+class MockCanvas : public SkCanvas {
public:
- ImplSidePaintingSettings() {
- implSidePainting = true;
+ explicit MockCanvas(SkDevice* device) : SkCanvas(device) { }
+
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint) {
+ // Capture calls before SkCanvas quickReject kicks in
+ rects_.push_back(rect);
}
+
+ std::vector<SkRect> rects_;
};
class PictureLayerImplTest : public testing::Test {
@@ -194,6 +214,65 @@ class PictureLayerImplTest : public testing::Test {
}
protected:
+ void TestTileGridAlignmentCommon() {
+ // Layer to span 4 raster tiles in x and in y
+ ImplSidePaintingSettings settings;
+ gfx::Size layer_size(
+ settings.defaultTileSize.width() * 7 / 2,
+ settings.defaultTileSize.height() * 7 / 2);
+
+ scoped_refptr<TestablePicturePileImpl> pending_pile =
+ TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size);
+ scoped_refptr<TestablePicturePileImpl> active_pile =
+ TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size);
+
+ SetupTrees(pending_pile, active_pile);
+
+ host_impl_.activeTree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f);
+ float result_scale_x, result_scale_y;
+ gfx::Size result_bounds;
+ active_layer_->calculateContentsScale(
+ 1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
+
+ // Add 1x1 rects at the centers of each tile, then re-record pile contents
+ std::vector<Tile*> tiles =
+ active_layer_->tilings().tiling_at(0)->AllTilesForTesting();
+ EXPECT_EQ(16, tiles.size());
+ std::vector<SkRect> rects;
+ std::vector<Tile*>::const_iterator tile_iter;
+ for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
+ gfx::Point tile_center = (*tile_iter)->content_rect().CenterPoint();
+ gfx::Rect rect(tile_center.x(), tile_center.y(), 1, 1);
+ active_pile->addDrawRect(rect);
+ rects.push_back(SkRect::MakeXYWH(rect.x(), rect.y(), 1, 1));
+ }
+ // Force re-record with newly injected content
+ active_pile->RemoveRecordingAt(0, 0);
+ active_pile->AddRecordingAt(0, 0);
+
+ SkBitmap store;
+ store.setConfig(SkBitmap::kNo_Config, 1000, 1000);
+ SkDevice device(store);
+ int64 pixelsRasterized;
+
+ std::vector<SkRect>::const_iterator rect_iter = rects.begin();
+ for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
+ MockCanvas mock_canvas(&device);
+ active_pile->Raster(&mock_canvas, (*tile_iter)->content_rect(),
+ 1.0f, &pixelsRasterized);
+
+ // This test verifies that when drawing the contents of a specific tile
+ // at content scale 1.0, the playback canvas never receives content from
+ // neighboring tiles which indicates that the tile grid embedded in
+ // SkPicture is perfectly aligned with the compositor's tiles.
+ // Note: There are two rects: the initial clear and the explicitly
+ // recorded rect. We only care about the second one.
+ EXPECT_EQ(2, mock_canvas.rects_.size());
+ EXPECT_EQ(*rect_iter, mock_canvas.rects_[1]);
+ rect_iter++;
+ }
+ }
+
FakeImplProxy proxy_;
FakeLayerTreeHostImpl host_impl_;
int id_;
@@ -203,6 +282,16 @@ class PictureLayerImplTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest);
};
+TEST_F(PictureLayerImplTest, tileGridAlignment) {
+ host_impl_.setDeviceScaleFactor(1.f);
+ TestTileGridAlignmentCommon();
+}
+
+TEST_F(PictureLayerImplTest, tileGridAlignmentHiDPI) {
+ host_impl_.setDeviceScaleFactor(2.f);
+ TestTileGridAlignmentCommon();
+}
+
TEST_F(PictureLayerImplTest, cloneNoInvalidation) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
diff --git a/cc/picture_pile.cc b/cc/picture_pile.cc
index 1db3f4b..d94835a 100644
--- a/cc/picture_pile.cc
+++ b/cc/picture_pile.cc
@@ -91,7 +91,7 @@ void PicturePile::Update(
for (PictureList::iterator pic = pic_list.begin();
pic != pic_list.end(); ++pic) {
if (!(*pic)->HasRecording())
- (*pic)->Record(painter, stats);
+ (*pic)->Record(painter, stats, tile_grid_info_);
}
}
diff --git a/cc/picture_pile_base.cc b/cc/picture_pile_base.cc
index 72e09d8..c855167 100644
--- a/cc/picture_pile_base.cc
+++ b/cc/picture_pile_base.cc
@@ -11,6 +11,7 @@ namespace {
// Dimensions of the tiles in this picture pile as well as the dimensions of
// the base picture in each tile.
const int kBasePictureSize = 3000;
+const int kTileGridBorderPixels = 1;
}
namespace cc {
@@ -18,6 +19,9 @@ namespace cc {
PicturePileBase::PicturePileBase()
: min_contents_scale_(0) {
tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize));
+ tile_grid_info_.fTileInterval.setEmpty();
+ tile_grid_info_.fMargin.setEmpty();
+ tile_grid_info_.fOffset.setZero();
}
PicturePileBase::~PicturePileBase() {
@@ -68,6 +72,21 @@ void PicturePileBase::SetMinContentsScale(float min_contents_scale) {
min_contents_scale_ = min_contents_scale;
}
+void PicturePileBase::SetTileGridSize(const gfx::Size& tile_grid_size) {
+ tile_grid_info_.fTileInterval.set(
+ tile_grid_size.width() - 2 * kTileGridBorderPixels,
+ tile_grid_size.height() - 2 * kTileGridBorderPixels);
+ DCHECK_GT(tile_grid_info_.fTileInterval.width(), 0);
+ DCHECK_GT(tile_grid_info_.fTileInterval.height(), 0);
+ tile_grid_info_.fMargin.set(kTileGridBorderPixels,
+ kTileGridBorderPixels);
+ // Offset the tile grid coordinate space to take into account the fact
+ // that the top-most and left-most tiles do not have top and left borders
+ // respectively.
+ tile_grid_info_.fOffset.set(-kTileGridBorderPixels,
+ -kTileGridBorderPixels);
+}
+
void PicturePileBase::SetBufferPixels(int new_buffer_pixels) {
if (new_buffer_pixels == buffer_pixels())
return;
@@ -85,6 +104,7 @@ void PicturePileBase::PushPropertiesTo(PicturePileBase* other) {
other->tiling_ = tiling_;
other->recorded_region_ = recorded_region_;
other->min_contents_scale_ = min_contents_scale_;
+ other->tile_grid_info_ = tile_grid_info_;
}
void PicturePileBase::UpdateRecordedRegion() {
diff --git a/cc/picture_pile_base.h b/cc/picture_pile_base.h
index ea8745c..aea9477 100644
--- a/cc/picture_pile_base.h
+++ b/cc/picture_pile_base.h
@@ -37,6 +37,8 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> {
bool HasRecordingAt(int x, int y);
bool CanRaster(float contents_scale, gfx::Rect content_rect);
+ void SetTileGridSize(const gfx::Size& tile_grid_size);
+
protected:
virtual ~PicturePileBase();
@@ -53,6 +55,7 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> {
TilingData tiling_;
Region recorded_region_;
float min_contents_scale_;
+ SkTileGridPicture::TileGridInfo tile_grid_info_;
private:
void SetBufferPixels(int buffer_pixels);
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc
index 113ac5a..efbd4c3 100644
--- a/cc/test/fake_content_layer_client.cc
+++ b/cc/test/fake_content_layer_client.cc
@@ -4,19 +4,29 @@
#include "cc/test/fake_content_layer_client.h"
-#include "ui/gfx/rect.h"
+#include "third_party/skia/include/core/SkCanvas.h"
namespace cc {
FakeContentLayerClient::FakeContentLayerClient()
- : m_paintAllOpaque(false)
-{
+ : paint_all_opaque_(false) {
}
-void FakeContentLayerClient::paintContents(SkCanvas*, const gfx::Rect& rect, gfx::RectF& opaqueRect)
-{
- if (m_paintAllOpaque)
- opaqueRect = rect;
+FakeContentLayerClient::~FakeContentLayerClient() {
+}
+
+void FakeContentLayerClient::paintContents(SkCanvas* canvas,
+ const gfx::Rect& rect, gfx::RectF& opaque_rect) {
+ if (paint_all_opaque_)
+ opaque_rect = rect;
+
+ SkPaint paint;
+ for (RectVector::const_iterator rect_it = draw_rects_.begin();
+ rect_it < draw_rects_.end(); rect_it++) {
+ SkRect draw_rect = SkRect::MakeXYWH(rect_it->x(), rect_it->y(),
+ rect_it->width(), rect_it->height());
+ canvas->drawRect(draw_rect, paint);
+ }
}
} // namespace cc
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h
index 85ab26e..c39683d 100644
--- a/cc/test/fake_content_layer_client.h
+++ b/cc/test/fake_content_layer_client.h
@@ -5,21 +5,31 @@
#ifndef CC_TEST_FAKE_CONTENT_LAYER_CLIENT_H_
#define CC_TEST_FAKE_CONTENT_LAYER_CLIENT_H_
+#include <vector>
+
#include "base/compiler_specific.h"
#include "cc/content_layer_client.h"
+#include "ui/gfx/rect.h"
namespace cc {
class FakeContentLayerClient : public cc::ContentLayerClient {
public:
FakeContentLayerClient();
+ virtual ~FakeContentLayerClient();
+
+ virtual void paintContents(SkCanvas*, const gfx::Rect& rect,
+ gfx::RectF& opaque_rect) OVERRIDE;
- virtual void paintContents(SkCanvas*, const gfx::Rect& rect, gfx::RectF& opaqueRect) OVERRIDE;
+ void setPaintAllOpaque(bool opaque) { paint_all_opaque_ = opaque; }
- void setPaintAllOpaque(bool opaque) { m_paintAllOpaque = opaque; }
+ void addDrawRect(const gfx::Rect& rect) { draw_rects_.push_back(rect); }
private:
- bool m_paintAllOpaque;
+ typedef std::vector<gfx::Rect> RectVector;
+
+ bool paint_all_opaque_;
+ RectVector draw_rects_;
};
} // namespace cc