diff options
author | wangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-15 21:34:02 +0000 |
---|---|---|
committer | wangxianzhu@chromium.org <wangxianzhu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-15 21:34:02 +0000 |
commit | 5a3c3c8eceb7990440d5cf3aba72410afca55589 (patch) | |
tree | 1fc6a9543a3f387c440ebdaf79f1f62b9bd0dcd1 | |
parent | 92a6c9a772d336fa6cb84a2c0b79fdeccff2e394 (diff) | |
download | chromium_src-5a3c3c8eceb7990440d5cf3aba72410afca55589.zip chromium_src-5a3c3c8eceb7990440d5cf3aba72410afca55589.tar.gz chromium_src-5a3c3c8eceb7990440d5cf3aba72410afca55589.tar.bz2 |
Revert 193762 "Makes tile-creation lazy"
The change caused crbug.com/231360.
> Makes tile-creation lazy
>
> This cl contains quite a few changes. I'll try to enumerate all of them here:
>
> 1) Some cleanup of the PictureLayerTiling definition (moved all members to the bottom and sorted them by lifespan)
> 2) Added painted_rect to Tile. This allows us to determine quickly if a new tileing can use an old tile (if the required painted rect is contained within the old painted rect). This lets us re-use partially painted tiles when the layer-bounds shrinks but nothing else changes.
> 3) Added an interest_rect field to PictureLayerTiling (we should determine if this is redundant with last_interest_rect
> 4) Added a new constructor to PictureLayerTiling for the sake of lazy cloning. This constructor copies another PictureLayerTiling but does *not* copy the tiles or interest_rect. The copy occurs lazily.
> 5) Added a ManageTiles function that creates all of the tiles required for a layer from its interest rect. It's interfact takes both the new and old rects, which isn't really required and could be changed if desired. This function deletes tiles outside of an old interest rect and adds tiles from the new interest rect.
> 6) Changed the definition of CreateTile to lazily pull from where it can. It no longer assumes we don't already have a tile for that I,J location. It first checks to see if this tiling already has a tile that has a big enough paint rect. If it doesn't, it checks its sibling for a tile in that I,J to see if it has a tile with a big enough paint rect, if not it creates a new tile.
> 7) Added two functions to the layer client, one lets a Tiling get its sibling and one gets the layer's invalidation.
> 8) Added a SimpleIterator class to iterate over a rectangular region. This iterator is substantially simpler than the current iterator and only has the functionality requried to iterate over a rectangle. We should probably rename SimpleIterator to RectIterator and Iterator to CoverageIterator because it's really part of the coverage algorithm.
>
> There's probably a few more tweaks here and there and names/APIs are final but I wanted to put this up for review now that it appears to work.
>
> BUG=190816
>
> Review URL: https://chromiumcodereview.appspot.com/12865017
BUG=231360
TBR=whunt@chromium.org
Review URL: https://codereview.chromium.org/14103016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194238 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/layers/picture_image_layer_impl_unittest.cc | 4 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 62 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.h | 8 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 20 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 257 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.h | 54 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_set.cc | 54 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_set.h | 13 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_set_unittest.cc | 11 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_unittest.cc | 53 | ||||
-rw-r--r-- | cc/resources/picture_pile_base.h | 1 | ||||
-rw-r--r-- | cc/test/fake_picture_layer_tiling_client.cc | 10 | ||||
-rw-r--r-- | cc/test/fake_picture_layer_tiling_client.h | 5 |
13 files changed, 281 insertions, 271 deletions
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc index abedc8d..5e8b1d8 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->bounds())); + layer->tilings_.reset(new PictureLayerTilingSet(&tiling_client_)); + layer->tilings_->SetLayerBounds(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 f80243b..aa9b7f7 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -61,7 +61,8 @@ scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( void PictureLayerImpl::CreateTilingSet() { DCHECK(layer_tree_impl()->IsPendingTree()); DCHECK(!tilings_); - tilings_.reset(new PictureLayerTilingSet(this, bounds())); + tilings_.reset(new PictureLayerTilingSet(this)); + tilings_->SetLayerBounds(bounds()); } void PictureLayerImpl::TransferTilingSet( @@ -89,6 +90,7 @@ 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) { const gfx::Rect& rect = visible_content_rect(); @@ -384,25 +386,8 @@ 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(); @@ -491,20 +476,31 @@ void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) { } } - // 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); + tilings_->CloneAll(*other->tilings_, invalidation_, MinimumContentsScale()); + DCHECK(bounds() == tilings_->LayerBounds()); - tilings_->CloneAll(*other->tilings_, MinimumContentsScale()); - DCHECK(bounds() == tilings_->layer_bounds()); + // 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); + } + } } void PictureLayerImpl::SyncTiling( - const PictureLayerTiling* tiling) { + const PictureLayerTiling* tiling, + const Region& pending_layer_invalidation) { if (!DrawsContent() || tiling->contents_scale() < MinimumContentsScale()) return; - tilings_->Clone(tiling); + tilings_->Clone(tiling, pending_layer_invalidation); } void PictureLayerImpl::SetIsMask(bool is_mask) { @@ -604,10 +600,18 @@ 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) - twin->SyncTiling(tiling); + if (!twin) + return tiling; + + if (layer_tree_impl()->IsPendingTree()) + twin->SyncTiling(tiling, invalidation_); + else + twin->SyncTiling(tiling, twin->invalidation_); return tiling; } diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index 068e4d2..a2e5a8d 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); + void SyncTiling( + const PictureLayerTiling* tiling, + const Region& pending_layer_invalidation); 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 9c0f5ab..4f00ed7 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -32,6 +32,14 @@ class TestablePictureLayerImpl : public PictureLayerImpl { PictureLayerTilingSet& tilings() { return *tilings_; } Region& invalidation() { return invalidation_; } + virtual gfx::Size CalculateTileSize( + gfx::Size current_tile_size, + gfx::Size content_bounds) OVERRIDE { + if (current_tile_size.IsEmpty()) + return gfx::Size(100, 100); + return current_tile_size; + } + using PictureLayerImpl::AddTiling; using PictureLayerImpl::CleanUpTilingsOnActiveLayer; @@ -161,12 +169,8 @@ 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( @@ -227,7 +231,6 @@ 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()); @@ -398,13 +401,8 @@ 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() || - active_tiles[0]->content_rect().size() != - pending_tiles[0]->content_rect().size()) { + iter.geometry_rect().bottom() >= active_content_bounds.height()) { EXPECT_EQ(pending_pile, iter->picture_pile()); } else { EXPECT_EQ(active_pile, iter->picture_pile()); diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 9025040..3035033 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -17,43 +17,21 @@ namespace cc { scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( - float contents_scale, - gfx::Size layer_bounds, - PictureLayerTilingClient* client) { - return make_scoped_ptr(new PictureLayerTiling(contents_scale, - layer_bounds, - client)); + float contents_scale) { + return make_scoped_ptr(new PictureLayerTiling(contents_scale)); } -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(); +scoped_ptr<PictureLayerTiling> PictureLayerTiling::Clone() const { + return make_scoped_ptr(new PictureLayerTiling(*this)); } -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), +PictureLayerTiling::PictureLayerTiling(float contents_scale) + : client_(NULL), + contents_scale_(contents_scale), tiling_data_(gfx::Size(), gfx::Size(), true), + resolution_(NON_IDEAL_RESOLUTION), last_source_frame_number_(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); + last_impl_frame_time_(0) { } PictureLayerTiling::~PictureLayerTiling() { @@ -79,29 +57,10 @@ 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; @@ -114,6 +73,89 @@ 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) { @@ -127,6 +169,23 @@ 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), @@ -279,11 +338,6 @@ 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, @@ -301,22 +355,6 @@ void PictureLayerTiling::UpdateTilePriorities( if (ContentRect().IsEmpty()) return; - gfx::Rect viewport_in_content_space = - gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space, - 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 interest_rect = ExpandRectEquallyToAreaBoundedBy( - viewport_in_content_space, - interest_rect_area, - ContentRect()); - DCHECK(ContentRect().Contains(interest_rect)); - - SetLiveTilesRect(interest_rect); - bool first_update_in_new_source_frame = current_source_frame_number != last_source_frame_number_; @@ -333,11 +371,43 @@ void PictureLayerTiling::UpdateTilePriorities( if (!first_update_in_new_impl_frame && !first_update_in_new_source_frame) return; - double time_delta = 0.0; - if (last_impl_frame_time_ != 0.0 && - last_layer_bounds == current_layer_bounds) + double time_delta = 0; + if (last_impl_frame_time_ != 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::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 prioritized_rect = ExpandRectEquallyToAreaBoundedBy( + viewport_in_content_space, + prioritized_rect_area, + ContentRect()); + DCHECK(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_; @@ -352,7 +422,7 @@ void PictureLayerTiling::UpdateTilePriorities( last_screen_transform.matrix().get(0, 3), last_screen_transform.matrix().get(1, 3)); - for (TilingData::Iterator iter(&tiling_data_, interest_rect); + for (TilingData::Iterator iter(&tiling_data_, prioritized_rect); iter; ++iter) { TileMap::iterator find = tiles_.find(iter.index()); if (find == tiles_.end()) @@ -385,7 +455,7 @@ void PictureLayerTiling::UpdateTilePriorities( tile->SetPriority(tree, priority); } } else { - for (TilingData::Iterator iter(&tiling_data_, interest_rect); + for (TilingData::Iterator iter(&tiling_data_, prioritized_rect); iter; ++iter) { TileMap::iterator find = tiles_.find(iter.index()); if (find == tiles_.end()) @@ -433,37 +503,6 @@ void PictureLayerTiling::UpdateTilePriorities( last_impl_frame_time_ = current_frame_time; } -void PictureLayerTiling::SetLiveTilesRect( - gfx::Rect new_live_tiles_rect) { - DCHECK(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); - DCHECK(found != tiles_.end()); - 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 426a76f..5a83e40 100644 --- a/cc/resources/picture_layer_tiling.h +++ b/cc/resources/picture_layer_tiling.h @@ -32,10 +32,8 @@ 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() {} @@ -46,17 +44,17 @@ 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, - gfx::Size layer_bounds, - PictureLayerTilingClient* client); - scoped_ptr<PictureLayerTiling> Clone(gfx::Size layer_bounds, - PictureLayerTilingClient* client) const; + static scoped_ptr<PictureLayerTiling> Create(float contents_scale); + scoped_ptr<PictureLayerTiling> Clone() 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; } @@ -66,10 +64,6 @@ 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(); @@ -78,6 +72,11 @@ 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 @@ -126,7 +125,7 @@ class CC_EXPORT PictureLayerTiling { Region OpaqueRegionInContentRect(const gfx::Rect&) const; - void Reset(); + void Reset() { return tiles_.clear(); } void UpdateTilePriorities( WhichTree tree, @@ -150,34 +149,23 @@ 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; - PictureLayerTiling(float contents_scale, - gfx::Size layer_bounds, - PictureLayerTilingClient* client); - void SetLiveTilesRect(gfx::Rect live_tiles_rect); - void CreateTile(int i, int j); + explicit PictureLayerTiling(float contents_scale); Tile* TileAt(int, int) const; + void CreateTilesFromContentRect(gfx::Rect layer_rect); + void CreateTile(int i, int j); - // Given properties. + PictureLayerTilingClient* client_; float contents_scale_; gfx::Size layer_bounds_; - TileResolution resolution_; - PictureLayerTilingClient* client_; - - // Internal data. + gfx::Rect last_prioritized_rect_; + // It is not legal to have a NULL tile in the tiles_ map. + TileMap tiles_; 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. + TileResolution resolution_; 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 6baac30..1b26e56 100644 --- a/cc/resources/picture_layer_tiling_set.cc +++ b/cc/resources/picture_layer_tiling_set.cc @@ -21,10 +21,8 @@ class LargestToSmallestScaleFunctor { PictureLayerTilingSet::PictureLayerTilingSet( - PictureLayerTilingClient* client, - gfx::Size layer_bounds) - : client_(client), - layer_bounds_(layer_bounds) { + PictureLayerTilingClient * client) + : client_(client) { } PictureLayerTilingSet::~PictureLayerTilingSet() { @@ -38,36 +36,61 @@ 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) { - const PictureLayerTiling* tiling = other.tilings_[i]; - if (tiling->contents_scale() < minimum_contents_scale) + if (other.tilings_[i]->contents_scale() < minimum_contents_scale) continue; - tilings_.push_back(tiling->Clone(layer_bounds_, client_)); + Clone(other.tilings_[i], invalidation); } - tilings_.sort(LargestToSmallestScaleFunctor()); } -void PictureLayerTilingSet::Clone(const PictureLayerTiling* tiling) { +void PictureLayerTilingSet::Clone( + const PictureLayerTiling* tiling, + const Region& invalidation) { + for (size_t i = 0; i < tilings_.size(); ++i) DCHECK_NE(tilings_[i]->contents_scale(), tiling->contents_scale()); - tilings_.push_back(tiling->Clone(layer_bounds_, client_)); + 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_.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, - layer_bounds_, - client_)); + tilings_.push_back(PictureLayerTiling::Create(contents_scale)); PictureLayerTiling* appended = tilings_.back(); + appended->SetClient(client_); + appended->SetLayerBounds(layer_bounds_); tilings_.sort(LargestToSmallestScaleFunctor()); return appended; @@ -90,6 +113,11 @@ 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 c32d45a..f88d1ef1 100644 --- a/cc/resources/picture_layer_tiling_set.h +++ b/cc/resources/picture_layer_tiling_set.h @@ -14,8 +14,7 @@ namespace cc { class CC_EXPORT PictureLayerTilingSet { public: - PictureLayerTilingSet(PictureLayerTilingClient* client, - gfx::Size layer_bounds); + explicit PictureLayerTilingSet(PictureLayerTilingClient* client); ~PictureLayerTilingSet(); void SetClient(PictureLayerTilingClient* client); @@ -23,11 +22,14 @@ 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); + void Clone(const PictureLayerTiling* tiling, const Region& invalidation); - gfx::Size layer_bounds() const { return layer_bounds_; } + void SetLayerBounds(gfx::Size layer_bounds); + gfx::Size LayerBounds() const; + void Invalidate(const Region& layer_invalidation); void InvalidateTilesWithText(); PictureLayerTiling* AddTiling(float contents_scale); @@ -46,6 +48,9 @@ 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 1cc552d..d2af09a 100644 --- a/cc/resources/picture_layer_tiling_set_unittest.cc +++ b/cc/resources/picture_layer_tiling_set_unittest.cc @@ -19,10 +19,12 @@ namespace { TEST(PictureLayerTilingSetTest, NoResources) { FakePictureLayerTilingClient client; - gfx::Size layer_bounds(1000, 800); - PictureLayerTilingSet set(&client, layer_bounds); + PictureLayerTilingSet set(&client); client.SetTileSize(gfx::Size(256, 256)); + gfx::Size layer_bounds(1000, 800); + set.SetLayerBounds(layer_bounds); + set.AddTiling(1.0); set.AddTiling(1.5); set.AddTiling(2.0); @@ -65,13 +67,14 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { FakePictureLayerTilingClient client; client.SetTileSize(gfx::Size(256, 256)); + PictureLayerTilingSet set(&client); + gfx::Size layer_bounds(1000, 800); - PictureLayerTilingSet set(&client, layer_bounds); + set.SetLayerBounds(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 70109bd..5e29b82 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -12,27 +12,6 @@ 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() {} @@ -42,21 +21,9 @@ class PictureLayerTilingIteratorTest : public testing::Test { float contents_scale, gfx::Size layer_bounds) { client_.SetTileSize(tile_size); - tiling_ = TestablePictureLayerTiling::Create(contents_scale, - layer_bounds, - &client_); - tiling_->CreateAllTilesForTesting(); - } - - 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())); - } + tiling_ = PictureLayerTiling::Create(contents_scale); + tiling_->SetClient(&client_); + tiling_->SetLayerBounds(layer_bounds); } void VerifyTilesExactlyCoverRect( @@ -125,21 +92,11 @@ class PictureLayerTilingIteratorTest : public testing::Test { protected: FakePictureLayerTilingClient client_; - scoped_ptr<TestablePictureLayerTiling> tiling_; + scoped_ptr<PictureLayerTiling> 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()); @@ -491,7 +448,7 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) { 2.0, // current frame time false, // store screen space quads on tiles 10000); // max tiles in tile manager - VerifyTiles(1.f, gfx::Rect(), base::Bind(&TileExists, false)); + VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false)); } } // namespace diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h index 98aa056..fd16207 100644 --- a/cc/resources/picture_pile_base.h +++ b/cc/resources/picture_pile_base.h @@ -39,7 +39,6 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> { bool CanRaster(float contents_scale, gfx::Rect content_rect); void SetTileGridSize(const 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 5722b78..0ee0483 100644 --- a/cc/test/fake_picture_layer_tiling_client.cc +++ b/cc/test/fake_picture_layer_tiling_client.cc @@ -53,17 +53,9 @@ 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 9f41348..4cde8cd 100644 --- a/cc/test/fake_picture_layer_tiling_client.h +++ b/cc/test/fake_picture_layer_tiling_client.h @@ -25,16 +25,13 @@ 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_; |