summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layers/picture_image_layer_impl_unittest.cc4
-rw-r--r--cc/layers/picture_layer_impl.cc62
-rw-r--r--cc/layers/picture_layer_impl.h8
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc28
-rw-r--r--cc/resources/picture_layer_tiling.cc275
-rw-r--r--cc/resources/picture_layer_tiling.h57
-rw-r--r--cc/resources/picture_layer_tiling_set.cc54
-rw-r--r--cc/resources/picture_layer_tiling_set.h13
-rw-r--r--cc/resources/picture_layer_tiling_set_unittest.cc11
-rw-r--r--cc/resources/picture_layer_tiling_unittest.cc84
-rw-r--r--cc/resources/picture_pile_base.h1
-rw-r--r--cc/test/fake_picture_layer_tiling_client.cc10
-rw-r--r--cc/test/fake_picture_layer_tiling_client.h5
13 files changed, 309 insertions, 303 deletions
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc
index 5e8b1d8..abedc8d 100644
--- a/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -35,8 +35,8 @@ class PictureImageLayerImplTest : public testing::Test {
TestablePictureImageLayerImpl* layer =
new TestablePictureImageLayerImpl(host_impl_.pending_tree(), id);
layer->SetBounds(gfx::Size(100, 200));
- layer->tilings_.reset(new PictureLayerTilingSet(&tiling_client_));
- layer->tilings_->SetLayerBounds(layer->bounds());
+ layer->tilings_.reset(new PictureLayerTilingSet(&tiling_client_,
+ layer->bounds()));
layer->pile_ = tiling_client_.pile();
return make_scoped_ptr(layer);
}
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 29d84f2..d830590 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -61,8 +61,7 @@ scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
void PictureLayerImpl::CreateTilingSet() {
DCHECK(layer_tree_impl()->IsPendingTree());
DCHECK(!tilings_);
- tilings_.reset(new PictureLayerTilingSet(this));
- tilings_->SetLayerBounds(bounds());
+ tilings_.reset(new PictureLayerTilingSet(this, bounds()));
}
void PictureLayerImpl::TransferTilingSet(
@@ -90,7 +89,6 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
layer_impl->is_using_lcd_text_ = is_using_lcd_text_;
}
-
void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
AppendQuadsData* append_quads_data) {
gfx::Rect rect(visible_content_rect());
@@ -390,8 +388,25 @@ void PictureLayerImpl::UpdatePile(Tile* tile) {
tile->set_picture_pile(pile_);
}
+const Region* PictureLayerImpl::GetInvalidation() {
+ return &invalidation_;
+}
+
+const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
+ const PictureLayerTiling* tiling) {
+
+ const PictureLayerImpl* other_layer = layer_tree_impl()->IsActiveTree() ?
+ PendingTwin() : ActiveTwin();
+ if (!other_layer)
+ return NULL;
+ for (size_t i = 0; i < other_layer->tilings_->num_tilings(); ++i)
+ if (other_layer->tilings_->tiling_at(i)->contents_scale() ==
+ tiling->contents_scale())
+ return other_layer->tilings_->tiling_at(i);
+ return NULL;
+}
+
gfx::Size PictureLayerImpl::CalculateTileSize(
- gfx::Size current_tile_size,
gfx::Size content_bounds) {
if (is_mask_) {
int max_size = layer_tree_impl()->MaxTextureSize();
@@ -487,31 +502,20 @@ void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
}
}
- tilings_->CloneAll(*other->tilings_, invalidation_, MinimumContentsScale());
- DCHECK(bounds() == tilings_->LayerBounds());
+ // Union in the other newly exposed regions as invalid.
+ Region difference_region = Region(gfx::Rect(bounds()));
+ difference_region.Subtract(gfx::Rect(other->bounds()));
+ invalidation_.Union(difference_region);
- // It's a sad but unfortunate fact that PicturePile tiling edges do not line
- // up with PictureLayerTiling edges. Tiles can only be added if they are
- // entirely covered by recordings (that may come from multiple PicturePile
- // tiles). This check happens in this class's CreateTile() call.
- for (int x = 0; x < pile_->num_tiles_x(); ++x) {
- for (int y = 0; y < pile_->num_tiles_y(); ++y) {
- bool previously_had = other->pile_->HasRecordingAt(x, y);
- bool now_has = pile_->HasRecordingAt(x, y);
- if (!now_has || previously_had)
- continue;
- gfx::Rect layer_rect = pile_->tile_bounds(x, y);
- tilings_->CreateTilesFromLayerRect(layer_rect);
- }
- }
+ tilings_->CloneAll(*other->tilings_, MinimumContentsScale());
+ DCHECK(bounds() == tilings_->layer_bounds());
}
void PictureLayerImpl::SyncTiling(
- const PictureLayerTiling* tiling,
- const Region& pending_layer_invalidation) {
+ const PictureLayerTiling* tiling) {
if (!DrawsContent() || tiling->contents_scale() < MinimumContentsScale())
return;
- tilings_->Clone(tiling, pending_layer_invalidation);
+ tilings_->Clone(tiling);
}
void PictureLayerImpl::SetIsMask(bool is_mask) {
@@ -614,18 +618,10 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
const Region& recorded = pile_->recorded_region();
DCHECK(!recorded.IsEmpty());
- for (Region::Iterator iter(recorded); iter.has_rect(); iter.next())
- tiling->CreateTilesFromLayerRect(iter.rect());
-
PictureLayerImpl* twin =
layer_tree_impl()->IsPendingTree() ? ActiveTwin() : PendingTwin();
- if (!twin)
- return tiling;
-
- if (layer_tree_impl()->IsPendingTree())
- twin->SyncTiling(tiling, invalidation_);
- else
- twin->SyncTiling(tiling, twin->invalidation_);
+ if (twin)
+ twin->SyncTiling(tiling);
return tiling;
}
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index a2e5a8d..068e4d2 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -54,14 +54,14 @@ class CC_EXPORT PictureLayerImpl
gfx::Rect content_rect) OVERRIDE;
virtual void UpdatePile(Tile* tile) OVERRIDE;
virtual gfx::Size CalculateTileSize(
- gfx::Size current_tile_size,
gfx::Size content_bounds) OVERRIDE;
+ virtual const Region* GetInvalidation() OVERRIDE;
+ virtual const PictureLayerTiling* GetTwinTiling(
+ const PictureLayerTiling* tiling) OVERRIDE;
// PushPropertiesTo active tree => pending tree
void SyncFromActiveLayer();
- void SyncTiling(
- const PictureLayerTiling* tiling,
- const Region& pending_layer_invalidation);
+ void SyncTiling(const PictureLayerTiling* tiling);
void CreateTilingSet();
void TransferTilingSet(scoped_ptr<PictureLayerTilingSet> tilings);
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index ee21993..a3f0ae3 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -41,16 +41,12 @@ class TestablePictureLayerImpl : public PictureLayerImpl {
Region& invalidation() { return invalidation_; }
virtual gfx::Size CalculateTileSize(
- gfx::Size current_tile_size,
gfx::Size content_bounds) OVERRIDE {
if (fixed_tile_size_.IsEmpty()) {
- return PictureLayerImpl::CalculateTileSize(current_tile_size,
- content_bounds);
+ return PictureLayerImpl::CalculateTileSize(content_bounds);
}
- if (current_tile_size.IsEmpty())
- return fixed_tile_size_;
- return current_tile_size;
+ return fixed_tile_size_;
}
using PictureLayerImpl::AddTiling;
@@ -116,8 +112,12 @@ class PictureLayerImplTest : public testing::Test {
active_layer_->AddTiling(2.3f);
active_layer_->AddTiling(1.0f);
active_layer_->AddTiling(0.5f);
+ for (size_t i = 0; i < active_layer_->tilings().num_tilings(); ++i)
+ active_layer_->tilings().tiling_at(i)->CreateAllTilesForTesting();
pending_layer_->invalidation() = invalidation;
pending_layer_->SyncFromActiveLayer();
+ for (size_t i = 0; i < pending_layer_->tilings().num_tilings(); ++i)
+ pending_layer_->tilings().tiling_at(i)->CreateAllTilesForTesting();
}
void SetupPendingTree(
@@ -178,6 +178,7 @@ class PictureLayerImplTest : public testing::Test {
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
+ active_layer_->tilings().tiling_at(0)->CreateAllTilesForTesting();
std::vector<Tile*> tiles =
active_layer_->tilings().tiling_at(0)->AllTilesForTesting();
EXPECT_EQ(16u, tiles.size());
@@ -352,8 +353,13 @@ TEST_F(PictureLayerImplTest, NoInvalidationBoundsChange) {
++iter) {
EXPECT_TRUE(*iter);
EXPECT_FALSE(iter.geometry_rect().IsEmpty());
+ std::vector<Tile*> active_tiles =
+ active_layer_->tilings().tiling_at(i)->AllTilesForTesting();
+ std::vector<Tile*> pending_tiles = tiling->AllTilesForTesting();
if (iter.geometry_rect().right() >= active_content_bounds.width() ||
- iter.geometry_rect().bottom() >= active_content_bounds.height()) {
+ iter.geometry_rect().bottom() >= active_content_bounds.height() ||
+ active_tiles[0]->content_rect().size() !=
+ pending_tiles[0]->content_rect().size()) {
EXPECT_EQ(pending_pile, iter->picture_pile());
} else {
EXPECT_EQ(active_pile, iter->picture_pile());
@@ -698,6 +704,8 @@ TEST_F(PictureLayerImplTest, ClampTilesToToMaxTileSize) {
1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
ASSERT_EQ(2u, pending_layer_->tilings().num_tilings());
+ pending_layer_->tilings().tiling_at(0)->CreateAllTilesForTesting();
+
// The default value.
EXPECT_EQ(gfx::Size(256, 256).ToString(),
host_impl_.settings().default_tile_size.ToString());
@@ -719,6 +727,8 @@ TEST_F(PictureLayerImplTest, ClampTilesToToMaxTileSize) {
1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
ASSERT_EQ(2u, pending_layer_->tilings().num_tilings());
+ pending_layer_->tilings().tiling_at(0)->CreateAllTilesForTesting();
+
// Verify the tiles are not larger than the context's max texture size.
tile = pending_layer_->tilings().tiling_at(0)->AllTilesForTesting()[0];
EXPECT_GE(140, tile->content_rect().width());
@@ -745,6 +755,8 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
ASSERT_EQ(2u, pending_layer_->tilings().num_tilings());
+ pending_layer_->tilings().tiling_at(0)->CreateAllTilesForTesting();
+
// The default value. The layer is smaller than this.
EXPECT_EQ(gfx::Size(512, 512).ToString(),
host_impl_.settings().max_untiled_layer_size.ToString());
@@ -766,6 +778,8 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
ASSERT_EQ(2u, pending_layer_->tilings().num_tilings());
+ pending_layer_->tilings().tiling_at(0)->CreateAllTilesForTesting();
+
// There should be more than one tile since the max texture size won't cover
// the layer.
high_res_tiling = pending_layer_->tilings().tiling_at(0);
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 48e5dae..7216152 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -17,21 +17,43 @@
namespace cc {
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
- float contents_scale) {
- return make_scoped_ptr(new PictureLayerTiling(contents_scale));
+ float contents_scale,
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client) {
+ return make_scoped_ptr(new PictureLayerTiling(contents_scale,
+ layer_bounds,
+ client));
}
-scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const {
- return make_scoped_ptr(new PictureLayerTiling(*this));
+scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone(
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client) const {
+ scoped_ptr<PictureLayerTiling> out =
+ make_scoped_ptr(new PictureLayerTiling(contents_scale_,
+ layer_bounds,
+ client));
+ out->resolution_ = resolution_;
+ out->last_source_frame_number_ = last_source_frame_number_;
+ out->last_impl_frame_time_ = last_impl_frame_time_;
+ return out.Pass();
}
-PictureLayerTiling::PictureLayerTiling(float contents_scale)
- : client_(NULL),
- contents_scale_(contents_scale),
- tiling_data_(gfx::Size(), gfx::Size(), true),
+PictureLayerTiling::PictureLayerTiling(float contents_scale,
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client)
+ : contents_scale_(contents_scale),
+ layer_bounds_(layer_bounds),
resolution_(NON_IDEAL_RESOLUTION),
+ client_(client),
+ tiling_data_(gfx::Size(), gfx::Size(), true),
last_source_frame_number_(0),
- last_impl_frame_time_(0) {
+ last_impl_frame_time_(0.0) {
+ gfx::Size content_bounds =
+ gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale));
+ gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
+
+ tiling_data_.SetTotalSize(content_bounds);
+ tiling_data_.SetMaxTextureSize(tile_size);
}
PictureLayerTiling::~PictureLayerTiling() {
@@ -57,10 +79,29 @@ Tile* PictureLayerTiling::TileAt(int i, int j) const {
}
void PictureLayerTiling::CreateTile(int i, int j) {
- gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j);
- tile_rect.set_size(tiling_data_.max_texture_size());
TileMapKey key(i, j);
DCHECK(tiles_.find(key) == tiles_.end());
+
+ gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j);
+ gfx::Rect tile_rect = paint_rect;
+ tile_rect.set_size(tiling_data_.max_texture_size());
+
+ // Check our twin for a valid tile.
+ const PictureLayerTiling* twin = client_->GetTwinTiling(this);
+ if (twin && tiling_data_.max_texture_size() ==
+ twin->tiling_data_.max_texture_size()) {
+ Tile* candidate_tile = twin->TileAt(i, j);
+ if (candidate_tile) {
+ gfx::Rect rect =
+ gfx::ToEnclosingRect(ScaleRect(paint_rect, 1.0f / contents_scale_));
+ if (!client_->GetInvalidation()->Intersects(rect)) {
+ tiles_[key] = candidate_tile;
+ return;
+ }
+ }
+ }
+
+ // Create a new tile because our twin didn't have a valid one.
scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect);
if (tile)
tiles_[key] = tile;
@@ -73,89 +114,6 @@ Region PictureLayerTiling::OpaqueRegionInContentRect(
return opaque_region;
}
-void PictureLayerTiling::SetLayerBounds(gfx::Size layer_bounds) {
- if (layer_bounds_ == layer_bounds)
- return;
-
- gfx::Size old_layer_bounds = layer_bounds_;
- layer_bounds_ = layer_bounds;
- gfx::Size old_content_bounds = tiling_data_.total_size();
- gfx::Size content_bounds =
- gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_));
-
- tiling_data_.SetTotalSize(content_bounds);
- if (layer_bounds_.IsEmpty()) {
- tiles_.clear();
- return;
- }
-
- gfx::Size tile_size = client_->CalculateTileSize(
- tiling_data_.max_texture_size(),
- content_bounds);
- if (tile_size != tiling_data_.max_texture_size()) {
- tiling_data_.SetMaxTextureSize(tile_size);
- tiles_.clear();
- CreateTilesFromLayerRect(gfx::Rect(layer_bounds_));
- return;
- }
-
- // Any tiles outside our new bounds are invalid and should be dropped.
- if (old_content_bounds.width() > content_bounds.width() ||
- old_content_bounds.height() > content_bounds.height()) {
- int right =
- tiling_data_.TileXIndexFromSrcCoord(content_bounds.width() - 1);
- int bottom =
- tiling_data_.TileYIndexFromSrcCoord(content_bounds.height() - 1);
-
- std::vector<TileMapKey> invalid_tile_keys;
- for (TileMap::const_iterator it = tiles_.begin();
- it != tiles_.end(); ++it) {
- if (it->first.first > right || it->first.second > bottom)
- invalid_tile_keys.push_back(it->first);
- }
- for (size_t i = 0; i < invalid_tile_keys.size(); ++i)
- tiles_.erase(invalid_tile_keys[i]);
- }
-
- // Create tiles for newly exposed areas.
- Region layer_region((gfx::Rect(layer_bounds_)));
- layer_region.Subtract(gfx::Rect(old_layer_bounds));
- for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
- Invalidate(iter.rect());
- CreateTilesFromLayerRect(iter.rect());
- }
-}
-
-void PictureLayerTiling::Invalidate(const Region& layer_invalidation) {
- std::vector<TileMapKey> new_tiles;
-
- for (Region::Iterator region_iter(layer_invalidation);
- region_iter.has_rect();
- region_iter.next()) {
- gfx::Rect layer_invalidation = region_iter.rect();
- layer_invalidation.Intersect(gfx::Rect(layer_bounds_));
- gfx::Rect rect =
- gfx::ToEnclosingRect(ScaleRect(layer_invalidation, contents_scale_));
-
- for (PictureLayerTiling::CoverageIterator tile_iter(this,
- contents_scale_,
- rect);
- tile_iter;
- ++tile_iter) {
- TileMapKey key(tile_iter.tile_i_, tile_iter.tile_j_);
- TileMap::iterator found = tiles_.find(key);
- if (found == tiles_.end())
- continue;
-
- tiles_.erase(found);
- new_tiles.push_back(key);
- }
- }
-
- for (size_t i = 0; i < new_tiles.size(); ++i)
- CreateTile(new_tiles[i].first, new_tiles[i].second);
-}
-
void PictureLayerTiling::InvalidateTilesWithText() {
std::vector<TileMapKey> new_tiles;
for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
@@ -169,23 +127,6 @@ void PictureLayerTiling::InvalidateTilesWithText() {
}
}
-void PictureLayerTiling::CreateTilesFromLayerRect(gfx::Rect layer_rect) {
- gfx::Rect content_rect =
- gfx::ToEnclosingRect(ScaleRect(layer_rect, contents_scale_));
- CreateTilesFromContentRect(content_rect);
-}
-
-void PictureLayerTiling::CreateTilesFromContentRect(gfx::Rect content_rect) {
- for (TilingData::Iterator iter(&tiling_data_, content_rect); iter; ++iter) {
- TileMap::iterator found =
- tiles_.find(TileMapKey(iter.index_x(), iter.index_y()));
- // Ignore any tiles that already exist.
- if (found != tiles_.end())
- continue;
- CreateTile(iter.index_x(), iter.index_y());
- }
-}
-
PictureLayerTiling::CoverageIterator::CoverageIterator()
: tiling_(NULL),
current_tile_(NULL),
@@ -338,6 +279,11 @@ gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const {
return tiling_->tiling_data_.max_texture_size();
}
+void PictureLayerTiling::Reset() {
+ live_tiles_rect_ = gfx::Rect();
+ tiles_.clear();
+}
+
void PictureLayerTiling::UpdateTilePriorities(
WhichTree tree,
gfx::Size device_viewport,
@@ -356,6 +302,29 @@ void PictureLayerTiling::UpdateTilePriorities(
if (ContentRect().IsEmpty())
return;
+ gfx::Rect viewport_in_content_space =
+ gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
+ contents_scale_));
+ gfx::Rect visible_content_rect =
+ gfx::ToEnclosingRect(gfx::ScaleRect(visible_layer_rect,
+ contents_scale_));
+
+ gfx::Size tile_size = tiling_data_.max_texture_size();
+ int64 interest_rect_area =
+ max_tiles_for_interest_area * tile_size.width() * tile_size.height();
+
+ gfx::Rect starting_rect = visible_content_rect.IsEmpty()
+ ? viewport_in_content_space
+ : visible_content_rect;
+ gfx::Rect interest_rect = ExpandRectEquallyToAreaBoundedBy(
+ starting_rect,
+ interest_rect_area,
+ ContentRect());
+ DCHECK(interest_rect.IsEmpty() ||
+ ContentRect().Contains(interest_rect));
+
+ SetLiveTilesRect(interest_rect);
+
bool first_update_in_new_source_frame =
current_source_frame_number != last_source_frame_number_;
@@ -372,50 +341,11 @@ void PictureLayerTiling::UpdateTilePriorities(
if (!first_update_in_new_impl_frame && !first_update_in_new_source_frame)
return;
- double time_delta = 0;
- if (last_impl_frame_time_ != 0 && last_layer_bounds == current_layer_bounds)
+ double time_delta = 0.0;
+ if (last_impl_frame_time_ != 0.0 &&
+ last_layer_bounds == current_layer_bounds)
time_delta = current_frame_time - last_impl_frame_time_;
- gfx::Rect viewport_in_content_space =
- gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
- contents_scale_));
- gfx::Rect visible_content_rect =
- gfx::ToEnclosingRect(gfx::ScaleRect(visible_layer_rect,
- contents_scale_));
-
- gfx::Size tile_size = tiling_data_.max_texture_size();
- int64 prioritized_rect_area =
- max_tiles_for_interest_area *
- tile_size.width() * tile_size.height();
-
- gfx::Rect starting_rect = visible_content_rect.IsEmpty()
- ? viewport_in_content_space
- : visible_content_rect;
- gfx::Rect prioritized_rect = ExpandRectEquallyToAreaBoundedBy(
- starting_rect,
- prioritized_rect_area,
- ContentRect());
- DCHECK(prioritized_rect.IsEmpty() ||
- ContentRect().Contains(prioritized_rect));
-
- // Iterate through all of the tiles that were live last frame but will
- // not be live this frame, and mark them as being dead.
- for (TilingData::DifferenceIterator iter(&tiling_data_,
- last_prioritized_rect_,
- prioritized_rect);
- iter;
- ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
- continue;
-
- TilePriority priority;
- DCHECK(!priority.is_live);
- Tile* tile = find->second.get();
- tile->SetPriority(tree, priority);
- }
- last_prioritized_rect_ = prioritized_rect;
-
gfx::Rect view_rect(device_viewport);
float current_scale = current_layer_contents_scale / contents_scale_;
float last_scale = last_layer_contents_scale / contents_scale_;
@@ -430,7 +360,7 @@ void PictureLayerTiling::UpdateTilePriorities(
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
TileMap::iterator find = tiles_.find(iter.index());
if (find == tiles_.end())
@@ -463,7 +393,7 @@ void PictureLayerTiling::UpdateTilePriorities(
tile->SetPriority(tree, priority);
}
} else {
- for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
+ for (TilingData::Iterator iter(&tiling_data_, interest_rect);
iter; ++iter) {
TileMap::iterator find = tiles_.find(iter.index());
if (find == tiles_.end())
@@ -511,6 +441,41 @@ void PictureLayerTiling::UpdateTilePriorities(
last_impl_frame_time_ = current_frame_time;
}
+void PictureLayerTiling::SetLiveTilesRect(
+ gfx::Rect new_live_tiles_rect) {
+ DCHECK(new_live_tiles_rect.IsEmpty() ||
+ ContentRect().Contains(new_live_tiles_rect));
+ if (live_tiles_rect_ == new_live_tiles_rect)
+ return;
+
+ // Iterate to delete all tiles outside of our new live_tiles rect.
+ for (TilingData::DifferenceIterator iter(&tiling_data_,
+ live_tiles_rect_,
+ new_live_tiles_rect);
+ iter;
+ ++iter) {
+ TileMapKey key(iter.index());
+ TileMap::iterator found = tiles_.find(key);
+ // If the tile was outside of the recorded region, it won't exist even
+ // though it was in the live rect.
+ if (found == tiles_.end())
+ continue;
+ tiles_.erase(found);
+ }
+
+ // Iterate to allocate new tiles for all regions with newly exposed area.
+ for (TilingData::DifferenceIterator iter(&tiling_data_,
+ new_live_tiles_rect,
+ live_tiles_rect_);
+ iter;
+ ++iter) {
+ TileMapKey key(iter.index());
+ CreateTile(key.first, key.second);
+ }
+
+ live_tiles_rect_ = new_live_tiles_rect;
+}
+
void PictureLayerTiling::DidBecomeActive() {
for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE));
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 29686d2..6227147 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -32,8 +32,10 @@ class PictureLayerTilingClient {
gfx::Rect content_rect) = 0;
virtual void UpdatePile(Tile* tile) = 0;
virtual gfx::Size CalculateTileSize(
- gfx::Size current_tile_size,
gfx::Size content_bounds) = 0;
+ virtual const Region* GetInvalidation() = 0;
+ virtual const PictureLayerTiling* GetTwinTiling(
+ const PictureLayerTiling* tiling) = 0;
protected:
virtual ~PictureLayerTilingClient() {}
@@ -44,18 +46,15 @@ class CC_EXPORT PictureLayerTiling {
~PictureLayerTiling();
// Create a tiling with no tiles. CreateTiles must be called to add some.
- static scoped_ptr<PictureLayerTiling> Create(float contents_scale);
- scoped_ptr<PictureLayerTiling> Clone() const;
-
+ static scoped_ptr<PictureLayerTiling> Create(
+ float contents_scale,
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client);
+ scoped_ptr<PictureLayerTiling> Clone(gfx::Size layer_bounds,
+ PictureLayerTilingClient* client) const;
gfx::Size layer_bounds() const { return layer_bounds_; }
- void SetLayerBounds(gfx::Size layer_bounds);
- void Invalidate(const Region& layer_invalidation);
void InvalidateTilesWithText();
- // Add any tiles that intersect with |layer_rect|. If any tiles already
- // exist, then this leaves them as-is.
- void CreateTilesFromLayerRect(gfx::Rect layer_rect);
-
void SetClient(PictureLayerTilingClient* client);
void set_resolution(TileResolution resolution) { resolution_ = resolution; }
TileResolution resolution() const { return resolution_; }
@@ -64,6 +63,10 @@ class CC_EXPORT PictureLayerTiling {
gfx::SizeF ContentSizeF() const;
float contents_scale() const { return contents_scale_; }
+ void CreateAllTilesForTesting() {
+ SetLiveTilesRect(gfx::Rect(tiling_data_.total_size()));
+ }
+
std::vector<Tile*> AllTilesForTesting() const {
std::vector<Tile*> all_tiles;
for (TileMap::const_iterator it = tiles_.begin();
@@ -72,11 +75,6 @@ class CC_EXPORT PictureLayerTiling {
return all_tiles;
}
- static gfx::Rect ExpandRectEquallyToAreaBoundedBy(
- gfx::Rect starting_rect,
- int64 target_area,
- gfx::Rect bounding_rect);
-
// Iterate over all tiles to fill content_rect. Even if tiles are invalid
// (i.e. no valid resource) this tiling should still iterate over them.
// The union of all geometry_rect calls for each element iterated over should
@@ -125,7 +123,7 @@ class CC_EXPORT PictureLayerTiling {
Region OpaqueRegionInContentRect(gfx::Rect content_rect) const;
- void Reset() { return tiles_.clear(); }
+ void Reset();
void UpdateTilePriorities(
WhichTree tree,
@@ -150,23 +148,34 @@ class CC_EXPORT PictureLayerTiling {
scoped_ptr<base::Value> AsValue() const;
+ static gfx::Rect ExpandRectEquallyToAreaBoundedBy(
+ gfx::Rect starting_rect,
+ int64 target_area,
+ gfx::Rect bounding_rect);
+
protected:
typedef std::pair<int, int> TileMapKey;
typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap;
- explicit PictureLayerTiling(float contents_scale);
- Tile* TileAt(int, int) const;
- void CreateTilesFromContentRect(gfx::Rect layer_rect);
+ PictureLayerTiling(float contents_scale,
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client);
+ void SetLiveTilesRect(gfx::Rect live_tiles_rect);
void CreateTile(int i, int j);
+ Tile* TileAt(int, int) const;
- PictureLayerTilingClient* client_;
+ // Given properties.
float contents_scale_;
gfx::Size layer_bounds_;
- gfx::Rect last_prioritized_rect_;
- // It is not legal to have a NULL tile in the tiles_ map.
- TileMap tiles_;
- TilingData tiling_data_;
TileResolution resolution_;
+ PictureLayerTilingClient* client_;
+
+ // Internal data.
+ TilingData tiling_data_;
+ TileMap tiles_; // It is not legal to have a NULL tile in the tiles_ map.
+ gfx::Rect live_tiles_rect_;
+
+ // State saved for computing velocities based upon finite differences.
int last_source_frame_number_;
double last_impl_frame_time_;
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index cc15047..65ab01c 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -21,8 +21,10 @@ class LargestToSmallestScaleFunctor {
PictureLayerTilingSet::PictureLayerTilingSet(
- PictureLayerTilingClient * client)
- : client_(client) {
+ PictureLayerTilingClient* client,
+ gfx::Size layer_bounds)
+ : client_(client),
+ layer_bounds_(layer_bounds) {
}
PictureLayerTilingSet::~PictureLayerTilingSet() {
@@ -36,61 +38,36 @@ void PictureLayerTilingSet::SetClient(PictureLayerTilingClient* client) {
void PictureLayerTilingSet::CloneAll(
const PictureLayerTilingSet& other,
- const Region& invalidation,
float minimum_contents_scale) {
tilings_.clear();
tilings_.reserve(other.tilings_.size());
for (size_t i = 0; i < other.tilings_.size(); ++i) {
- if (other.tilings_[i]->contents_scale() < minimum_contents_scale)
+ const PictureLayerTiling* tiling = other.tilings_[i];
+ if (tiling->contents_scale() < minimum_contents_scale)
continue;
- Clone(other.tilings_[i], invalidation);
+ tilings_.push_back(tiling->Clone(layer_bounds_, client_));
}
+ tilings_.sort(LargestToSmallestScaleFunctor());
}
-void PictureLayerTilingSet::Clone(
- const PictureLayerTiling* tiling,
- const Region& invalidation) {
-
+void PictureLayerTilingSet::Clone(const PictureLayerTiling* tiling) {
for (size_t i = 0; i < tilings_.size(); ++i)
DCHECK_NE(tilings_[i]->contents_scale(), tiling->contents_scale());
- tilings_.push_back(tiling->Clone());
- gfx::Size size = tilings_.back()->layer_bounds();
- tilings_.back()->SetClient(client_);
- tilings_.back()->Invalidate(invalidation);
- // Intentionally use this set's layer bounds, as it may have changed.
- tilings_.back()->SetLayerBounds(layer_bounds_);
-
+ tilings_.push_back(tiling->Clone(layer_bounds_, client_));
tilings_.sort(LargestToSmallestScaleFunctor());
}
-void PictureLayerTilingSet::SetLayerBounds(gfx::Size layer_bounds) {
- if (layer_bounds_ == layer_bounds)
- return;
- layer_bounds_ = layer_bounds;
- for (size_t i = 0; i < tilings_.size(); ++i)
- tilings_[i]->SetLayerBounds(layer_bounds);
-}
-
-gfx::Size PictureLayerTilingSet::LayerBounds() const {
- return layer_bounds_;
-}
-
-void PictureLayerTilingSet::Invalidate(const Region& layer_invalidation) {
- for (size_t i = 0; i < tilings_.size(); ++i)
- tilings_[i]->Invalidate(layer_invalidation);
-}
-
void PictureLayerTilingSet::InvalidateTilesWithText() {
for (size_t i = 0; i < tilings_.size(); ++i)
tilings_[i]->InvalidateTilesWithText();
}
PictureLayerTiling* PictureLayerTilingSet::AddTiling(float contents_scale) {
- tilings_.push_back(PictureLayerTiling::Create(contents_scale));
+ tilings_.push_back(PictureLayerTiling::Create(contents_scale,
+ layer_bounds_,
+ client_));
PictureLayerTiling* appended = tilings_.back();
- appended->SetClient(client_);
- appended->SetLayerBounds(layer_bounds_);
tilings_.sort(LargestToSmallestScaleFunctor());
return appended;
@@ -113,11 +90,6 @@ void PictureLayerTilingSet::RemoveAllTiles() {
tilings_[i]->Reset();
}
-void PictureLayerTilingSet::CreateTilesFromLayerRect(gfx::Rect layer_rect) {
- for (size_t i = 0; i < tilings_.size(); ++i)
- tilings_[i]->CreateTilesFromLayerRect(layer_rect);
-}
-
PictureLayerTilingSet::CoverageIterator::CoverageIterator(
const PictureLayerTilingSet* set,
float contents_scale,
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h
index 31f7e93..d263e71 100644
--- a/cc/resources/picture_layer_tiling_set.h
+++ b/cc/resources/picture_layer_tiling_set.h
@@ -14,7 +14,8 @@ namespace cc {
class CC_EXPORT PictureLayerTilingSet {
public:
- explicit PictureLayerTilingSet(PictureLayerTilingClient* client);
+ PictureLayerTilingSet(PictureLayerTilingClient* client,
+ gfx::Size layer_bounds);
~PictureLayerTilingSet();
void SetClient(PictureLayerTilingClient* client);
@@ -22,14 +23,11 @@ class CC_EXPORT PictureLayerTilingSet {
// Shallow copies all data (except client and bounds from other).
void CloneAll(
const PictureLayerTilingSet& other,
- const Region& invalidation,
float minimum_contents_scale);
- void Clone(const PictureLayerTiling* tiling, const Region& invalidation);
+ void Clone(const PictureLayerTiling* tiling);
- void SetLayerBounds(gfx::Size layer_bounds);
- gfx::Size LayerBounds() const;
+ gfx::Size layer_bounds() const { return layer_bounds_; }
- void Invalidate(const Region& layer_invalidation);
void InvalidateTilesWithText();
PictureLayerTiling* AddTiling(float contents_scale);
@@ -48,9 +46,6 @@ class CC_EXPORT PictureLayerTilingSet {
// Remove all tiles; keep all tilings.
void RemoveAllTiles();
- // For all tilings, create any tile that intersects |layer_rect|.
- void CreateTilesFromLayerRect(gfx::Rect layer_rect);
-
void UpdateTilePriorities(
WhichTree tree,
gfx::Size device_viewport,
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 90aa5ed..b79433d 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -19,11 +19,9 @@ namespace {
TEST(PictureLayerTilingSetTest, NoResources) {
FakePictureLayerTilingClient client;
- PictureLayerTilingSet set(&client);
- client.SetTileSize(gfx::Size(256, 256));
-
gfx::Size layer_bounds(1000, 800);
- set.SetLayerBounds(layer_bounds);
+ PictureLayerTilingSet set(&client, layer_bounds);
+ client.SetTileSize(gfx::Size(256, 256));
set.AddTiling(1.0);
set.AddTiling(1.5);
@@ -67,14 +65,13 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
FakePictureLayerTilingClient client;
client.SetTileSize(gfx::Size(256, 256));
- PictureLayerTilingSet set(&client);
-
gfx::Size layer_bounds(1000, 800);
- set.SetLayerBounds(layer_bounds);
+ PictureLayerTilingSet set(&client, layer_bounds);
float scale = min_scale;
for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
PictureLayerTiling* tiling = set.AddTiling(scale);
+ tiling->CreateAllTilesForTesting();
std::vector<Tile*> tiles = tiling->AllTilesForTesting();
for (size_t i = 0; i < tiles.size(); ++i) {
EXPECT_FALSE(tiles[i]->drawing_info().GetResourceForTesting());
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index a17c025..83e0db4 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -12,6 +12,27 @@
namespace cc {
namespace {
+class TestablePictureLayerTiling : public PictureLayerTiling {
+ public:
+ using PictureLayerTiling::SetLiveTilesRect;
+
+ static scoped_ptr<TestablePictureLayerTiling> Create(
+ float contents_scale,
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client) {
+ return make_scoped_ptr(new TestablePictureLayerTiling(
+ contents_scale,
+ layer_bounds,
+ client));
+ }
+
+ protected:
+ TestablePictureLayerTiling(float contents_scale,
+ gfx::Size layer_bounds,
+ PictureLayerTilingClient* client)
+ : PictureLayerTiling(contents_scale, layer_bounds, client) { }
+};
+
class PictureLayerTilingIteratorTest : public testing::Test {
public:
PictureLayerTilingIteratorTest() {}
@@ -21,9 +42,20 @@ class PictureLayerTilingIteratorTest : public testing::Test {
float contents_scale,
gfx::Size layer_bounds) {
client_.SetTileSize(tile_size);
- tiling_ = PictureLayerTiling::Create(contents_scale);
- tiling_->SetClient(&client_);
- tiling_->SetLayerBounds(layer_bounds);
+ tiling_ = TestablePictureLayerTiling::Create(contents_scale,
+ layer_bounds,
+ &client_);
+ }
+
+ void SetLiveRectAndVerifyTiles(gfx::Rect live_tiles_rect) {
+ tiling_->SetLiveTilesRect(live_tiles_rect);
+
+ std::vector<Tile*> tiles = tiling_->AllTilesForTesting();
+ for (std::vector<Tile*>::iterator iter = tiles.begin();
+ iter != tiles.end();
+ ++iter) {
+ EXPECT_TRUE(live_tiles_rect.Intersects((*iter)->content_rect()));
+ }
}
void VerifyTilesExactlyCoverRect(
@@ -68,16 +100,17 @@ class PictureLayerTilingIteratorTest : public testing::Test {
VerifyTilesExactlyCoverRect(rect_scale, rect, rect);
}
- void VerifyTiles(float rect_scale,
- gfx::Rect rect,
- base::Callback<void(Tile* tile)> callback) {
+ void VerifyTiles(
+ float rect_scale,
+ gfx::Rect rect,
+ base::Callback<void(Tile* tile, gfx::Rect geometry_rect)> callback) {
Region remaining = rect;
for (PictureLayerTiling::CoverageIterator iter(
tiling_.get(), rect_scale, rect);
iter;
++iter) {
remaining.Subtract(iter.geometry_rect());
- callback.Run(*iter);
+ callback.Run(*iter, iter.geometry_rect());
}
EXPECT_TRUE(remaining.IsEmpty());
}
@@ -92,11 +125,21 @@ class PictureLayerTilingIteratorTest : public testing::Test {
protected:
FakePictureLayerTilingClient client_;
- scoped_ptr<PictureLayerTiling> tiling_;
+ scoped_ptr<TestablePictureLayerTiling> tiling_;
DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest);
};
+TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) {
+ Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
+ SetLiveRectAndVerifyTiles(gfx::Rect(100, 100));
+ SetLiveRectAndVerifyTiles(gfx::Rect(101, 99));
+ SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
+ SetLiveRectAndVerifyTiles(gfx::Rect(1, 801));
+ SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
+ SetLiveRectAndVerifyTiles(gfx::Rect(201, 800));
+}
+
TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsNoScale) {
Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
VerifyTilesExactlyCoverRect(1, gfx::Rect());
@@ -406,9 +449,9 @@ TEST(PictureLayerTilingTest, EmptyStartingRect) {
EXPECT_TRUE(out.IsEmpty());
}
-static void TileExists(bool live, Tile* tile) {
- ASSERT_TRUE(tile != NULL);
- EXPECT_EQ(live, tile->priority(ACTIVE_TREE).is_live);
+static void TileExists(bool exists, Tile* tile, gfx::Rect geometry_rect) {
+ EXPECT_EQ(exists, tile != NULL && tile->priority(ACTIVE_TREE).is_live) <<
+ geometry_rect.ToString();
}
TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
@@ -526,12 +569,14 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
-static void TilesIntersectingRectExist(gfx::Rect rect, Tile* tile) {
- ASSERT_TRUE(tile != NULL);
- bool expected_live = rect.Intersects(tile->content_rect());
- EXPECT_EQ(expected_live, tile->priority(ACTIVE_TREE).is_live) <<
+static void TilesIntersectingRectExist(gfx::Rect rect,
+ Tile* tile,
+ gfx::Rect geometry_rect) {
+ bool expected_exists = rect.Intersects(geometry_rect);
+ EXPECT_EQ(expected_exists,
+ tile != NULL && tile->priority(ACTIVE_TREE).is_live) <<
"Rects intersecting " << rect.ToString() << " should exist. " <<
- "Current tile rect is " << tile->content_rect().ToString();
+ "Current tile rect is " << geometry_rect.ToString();
}
TEST_F(PictureLayerTilingIteratorTest,
@@ -563,9 +608,10 @@ TEST_F(PictureLayerTilingIteratorTest,
base::Bind(&TilesIntersectingRectExist, visible_rect));
}
-static void CountExistingTiles(int *count, Tile* tile) {
- ASSERT_TRUE(tile != NULL);
- if (tile->priority(ACTIVE_TREE).is_live)
+static void CountExistingTiles(int *count,
+ Tile* tile,
+ gfx::Rect geometry_rect) {
+ if (tile != NULL && tile->priority(ACTIVE_TREE).is_live)
++(*count);
}
diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h
index 5233929..fdfff2b 100644
--- a/cc/resources/picture_pile_base.h
+++ b/cc/resources/picture_pile_base.h
@@ -39,6 +39,7 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> {
bool CanRaster(float contents_scale, gfx::Rect content_rect);
void SetTileGridSize(gfx::Size tile_grid_size);
+ TilingData& tiling() { return tiling_; }
protected:
virtual ~PicturePileBase();
diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc
index 7e35c38..c8c4d29 100644
--- a/cc/test/fake_picture_layer_tiling_client.cc
+++ b/cc/test/fake_picture_layer_tiling_client.cc
@@ -52,9 +52,17 @@ void FakePictureLayerTilingClient::SetTileSize(gfx::Size tile_size) {
}
gfx::Size FakePictureLayerTilingClient::CalculateTileSize(
- gfx::Size /* current_tile_size */,
gfx::Size /* content_bounds */) {
return tile_size_;
}
+const Region* FakePictureLayerTilingClient::GetInvalidation() {
+ return NULL;
+}
+
+const PictureLayerTiling* FakePictureLayerTilingClient::GetTwinTiling(
+ const PictureLayerTiling* tiling) {
+ return NULL;
+}
+
} // namespace cc
diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h
index 4cde8cd..9f41348 100644
--- a/cc/test/fake_picture_layer_tiling_client.h
+++ b/cc/test/fake_picture_layer_tiling_client.h
@@ -25,13 +25,16 @@ class FakePictureLayerTilingClient : public PictureLayerTilingClient {
PictureLayerTiling* tiling, gfx::Rect rect) OVERRIDE;
virtual void UpdatePile(Tile* tile) OVERRIDE {}
virtual gfx::Size CalculateTileSize(
- gfx::Size current_tile_size,
gfx::Size content_bounds) OVERRIDE;
void SetTileSize(gfx::Size tile_size);
gfx::Size TileSize() const { return tile_size_; }
scoped_refptr<PicturePileImpl> pile() { return pile_; }
+ virtual const Region* GetInvalidation() OVERRIDE;
+ virtual const PictureLayerTiling* GetTwinTiling(
+ const PictureLayerTiling* tiling) OVERRIDE;
+
protected:
FakeTileManagerClient tile_manager_client_;
FakeRenderingStatsInstrumentation stats_instrumentation_;