diff options
-rw-r--r-- | cc/base/ref_counted_managed.h | 63 | ||||
-rw-r--r-- | cc/cc.gyp | 1 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 6 | ||||
-rw-r--r-- | cc/resources/prioritized_tile_set_unittest.cc | 17 | ||||
-rw-r--r-- | cc/resources/tile.cc | 5 | ||||
-rw-r--r-- | cc/resources/tile.h | 31 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 88 | ||||
-rw-r--r-- | cc/resources/tile_manager.h | 24 | ||||
-rw-r--r-- | cc/resources/tile_manager_perftest.cc | 17 | ||||
-rw-r--r-- | cc/resources/tile_manager_unittest.cc | 18 | ||||
-rw-r--r-- | cc/test/fake_picture_layer_tiling_client.cc | 13 |
11 files changed, 192 insertions, 91 deletions
diff --git a/cc/base/ref_counted_managed.h b/cc/base/ref_counted_managed.h new file mode 100644 index 0000000..7845f32 --- /dev/null +++ b/cc/base/ref_counted_managed.h @@ -0,0 +1,63 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_BASE_REF_COUNTED_MANAGED_H_ +#define CC_BASE_REF_COUNTED_MANAGED_H_ + +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "cc/base/cc_export.h" + +namespace cc { + +template <typename T> class RefCountedManaged; + +template <typename T> +class CC_EXPORT RefCountedManager { + protected: + RefCountedManager() : live_object_count_(0) {} + ~RefCountedManager() { + CHECK_EQ(0, live_object_count_); + } + + virtual void Release(T* object) = 0; + + private: + friend class RefCountedManaged<T>; + int live_object_count_; +}; + +template <typename T> +class CC_EXPORT RefCountedManaged : public base::subtle::RefCountedBase { + public: + explicit RefCountedManaged(RefCountedManager<T>* manager) + : manager_(manager) { + manager_->live_object_count_++; + } + + void AddRef() const { + base::subtle::RefCountedBase::AddRef(); + } + + void Release() { + if (base::subtle::RefCountedBase::Release()) { + manager_->Release(static_cast<T*>(this)); + + DCHECK_GT(manager_->live_object_count_, 0); + manager_->live_object_count_--; + } + } + + protected: + ~RefCountedManaged() {} + + private: + RefCountedManager<T>* manager_; + + DISALLOW_COPY_AND_ASSIGN(RefCountedManaged<T>); +}; + +} // namespace cc + +#endif // CC_BASE_REF_COUNTED_MANAGED_H_ @@ -57,6 +57,7 @@ 'base/invalidation_region.h', 'base/math_util.cc', 'base/math_util.h', + 'base/ref_counted_managed.h', 'base/region.cc', 'base/region.h', 'base/scoped_ptr_algorithm.h', diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 46a0c0e..22474a3 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -18,6 +18,7 @@ #include "cc/quads/picture_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/tile_draw_quad.h" +#include "cc/resources/tile_manager.h" #include "cc/trees/layer_tree_impl.h" #include "ui/gfx/quad_f.h" #include "ui/gfx/rect_conversions.h" @@ -453,8 +454,7 @@ scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, if (!pile_->CanRaster(tiling->contents_scale(), content_rect)) return scoped_refptr<Tile>(); - return make_scoped_refptr(new Tile( - layer_tree_impl()->tile_manager(), + return layer_tree_impl()->tile_manager()->CreateTile( pile_.get(), content_rect.size(), content_rect, @@ -462,7 +462,7 @@ scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, tiling->contents_scale(), id(), layer_tree_impl()->source_frame_number(), - is_using_lcd_text_)); + is_using_lcd_text_); } void PictureLayerImpl::UpdatePile(Tile* tile) { diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc index 7de1032..37c9cc1 100644 --- a/cc/resources/prioritized_tile_set_unittest.cc +++ b/cc/resources/prioritized_tile_set_unittest.cc @@ -64,15 +64,14 @@ class PrioritizedTileSetTest : public testing::Test { } scoped_refptr<Tile> CreateTile() { - return make_scoped_refptr(new Tile(tile_manager_.get(), - picture_pile_.get(), - settings_.default_tile_size, - gfx::Rect(), - gfx::Rect(), - 1.0, - 0, - 0, - true)); + return tile_manager_->CreateTile(picture_pile_.get(), + settings_.default_tile_size, + gfx::Rect(), + gfx::Rect(), + 1.0, + 0, + 0, + true); } private: diff --git a/cc/resources/tile.cc b/cc/resources/tile.cc index d7e1d2c..1ac8e26 100644 --- a/cc/resources/tile.cc +++ b/cc/resources/tile.cc @@ -22,7 +22,8 @@ Tile::Tile(TileManager* tile_manager, int layer_id, int source_frame_number, bool can_use_lcd_text) - : tile_manager_(tile_manager), + : RefCountedManaged<Tile>(tile_manager), + tile_manager_(tile_manager), tile_size_(tile_size), content_rect_(content_rect), contents_scale_(contents_scale), @@ -32,7 +33,6 @@ Tile::Tile(TileManager* tile_manager, can_use_lcd_text_(can_use_lcd_text), id_(s_next_id_++) { set_picture_pile(picture_pile); - tile_manager_->RegisterTile(this); } Tile::~Tile() { @@ -40,7 +40,6 @@ Tile::~Tile() { TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), "cc::Tile", this); - tile_manager_->UnregisterTile(this); } void Tile::SetPriority(WhichTree tree, const TilePriority& priority) { diff --git a/cc/resources/tile.h b/cc/resources/tile.h index 3caa407..fd184a6 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" +#include "cc/base/ref_counted_managed.h" #include "cc/resources/managed_tile_state.h" #include "cc/resources/raster_mode.h" #include "cc/resources/tile_priority.h" @@ -18,20 +19,10 @@ namespace cc { class PicturePileImpl; -class CC_EXPORT Tile : public base::RefCounted<Tile> { +class CC_EXPORT Tile : public RefCountedManaged<Tile> { public: typedef uint64 Id; - Tile(TileManager* tile_manager, - PicturePileImpl* picture_pile, - gfx::Size tile_size, - gfx::Rect content_rect, - gfx::Rect opaque_rect, - float contents_scale, - int layer_id, - int source_frame_number, - bool can_use_lcd_text); - Id id() const { return id_; } @@ -116,18 +107,26 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { gfx::Size size() const { return tile_size_.size(); } private: - // Methods called by by tile manager. friend class TileManager; friend class PrioritizedTileSet; friend class FakeTileManager; friend class BinComparator; - ManagedTileState& managed_state() { return managed_state_; } - const ManagedTileState& managed_state() const { return managed_state_; } - // Normal private methods. - friend class base::RefCounted<Tile>; + // Methods called by by tile manager. + Tile(TileManager* tile_manager, + PicturePileImpl* picture_pile, + gfx::Size tile_size, + gfx::Rect content_rect, + gfx::Rect opaque_rect, + float contents_scale, + int layer_id, + int source_frame_number, + bool can_use_lcd_text); ~Tile(); + ManagedTileState& managed_state() { return managed_state_; } + const ManagedTileState& managed_state() const { return managed_state_; } + TileManager* tile_manager_; scoped_refptr<PicturePileImpl> picture_pile_; gfx::Rect tile_size_; diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index 42e4a4d..a70c5d5 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -168,6 +168,7 @@ TileManager::~TileManager() { // our memory usage to drop to zero. global_state_ = GlobalStateThatImpactsTilePriority(); + CleanUpReleasedTiles(); DCHECK_EQ(0u, tiles_.size()); RasterWorkerPool::RasterTask::Queue empty; @@ -182,29 +183,9 @@ TileManager::~TileManager() { DCHECK_EQ(0u, resources_releasable_); } -void TileManager::RegisterTile(Tile* tile) { - DCHECK(!tile->required_for_activation()); - DCHECK(tiles_.find(tile->id()) == tiles_.end()); - - tiles_[tile->id()] = tile; - used_layer_counts_[tile->layer_id()]++; - prioritized_tiles_dirty_ = true; -} - -void TileManager::UnregisterTile(Tile* tile) { - FreeResourcesForTile(tile); - - DCHECK(tiles_.find(tile->id()) != tiles_.end()); - tiles_.erase(tile->id()); - - LayerCountMap::iterator layer_it = used_layer_counts_.find(tile->layer_id()); - DCHECK_GT(layer_it->second, 0); - if (--layer_it->second == 0) { - used_layer_counts_.erase(layer_it); - image_decode_tasks_.erase(tile->layer_id()); - } - +void TileManager::Release(Tile* tile) { prioritized_tiles_dirty_ = true; + released_tiles_.push_back(tile); } void TileManager::DidChangeTilePriority(Tile* tile) { @@ -215,14 +196,40 @@ bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; } -PrioritizedTileSet* TileManager::GetPrioritizedTileSet() { +void TileManager::CleanUpReleasedTiles() { + for (std::vector<Tile*>::iterator it = released_tiles_.begin(); + it != released_tiles_.end(); + ++it) { + Tile* tile = *it; + + FreeResourcesForTile(tile); + + DCHECK(tiles_.find(tile->id()) != tiles_.end()); + tiles_.erase(tile->id()); + + LayerCountMap::iterator layer_it = + used_layer_counts_.find(tile->layer_id()); + DCHECK_GT(layer_it->second, 0); + if (--layer_it->second == 0) { + used_layer_counts_.erase(layer_it); + image_decode_tasks_.erase(tile->layer_id()); + } + + delete tile; + } + + released_tiles_.clear(); +} + +void TileManager::UpdatePrioritizedTileSetIfNeeded() { if (!prioritized_tiles_dirty_) - return &prioritized_tiles_; + return; + + CleanUpReleasedTiles(); prioritized_tiles_.Clear(); GetTilesWithAssignedBins(&prioritized_tiles_); prioritized_tiles_dirty_ = false; - return &prioritized_tiles_; } void TileManager::DidFinishRunningTasks() { @@ -237,7 +244,7 @@ void TileManager::DidFinishRunningTasks() { did_check_for_completed_tasks_since_last_schedule_tasks_ = true; TileVector tiles_that_need_to_be_rasterized; - AssignGpuMemoryToTiles(GetPrioritizedTileSet(), + AssignGpuMemoryToTiles(&prioritized_tiles_, &tiles_that_need_to_be_rasterized); // |tiles_that_need_to_be_rasterized| will be empty when we reach a @@ -417,8 +424,10 @@ void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { did_check_for_completed_tasks_since_last_schedule_tasks_ = true; } + UpdatePrioritizedTileSetIfNeeded(); + TileVector tiles_that_need_to_be_rasterized; - AssignGpuMemoryToTiles(GetPrioritizedTileSet(), + AssignGpuMemoryToTiles(&prioritized_tiles_, &tiles_that_need_to_be_rasterized); // Finally, schedule rasterizer tasks. @@ -861,4 +870,29 @@ void TileManager::OnRasterTaskCompleted( did_initialize_visible_tile_ = true; } +scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, + gfx::Size tile_size, + gfx::Rect content_rect, + gfx::Rect opaque_rect, + float contents_scale, + int layer_id, + int source_frame_number, + bool can_use_lcd_text) { + scoped_refptr<Tile> tile = make_scoped_refptr(new Tile(this, + picture_pile, + tile_size, + content_rect, + opaque_rect, + contents_scale, + layer_id, + source_frame_number, + can_use_lcd_text)); + DCHECK(tiles_.find(tile->id()) == tiles_.end()); + + tiles_[tile->id()] = tile; + used_layer_counts_[tile->layer_id()]++; + prioritized_tiles_dirty_ = true; + return tile; +} + } // namespace cc diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h index 360bdca..4157dba 100644 --- a/cc/resources/tile_manager.h +++ b/cc/resources/tile_manager.h @@ -12,6 +12,7 @@ #include "base/containers/hash_tables.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" +#include "cc/base/ref_counted_managed.h" #include "cc/debug/rendering_stats_instrumentation.h" #include "cc/resources/managed_tile_state.h" #include "cc/resources/memory_history.h" @@ -45,7 +46,8 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( // should no longer have any memory assigned to them. Tile objects are "owned" // by layers; they automatically register with the manager when they are // created, and unregister from the manager when they are deleted. -class CC_EXPORT TileManager : public RasterWorkerPoolClient { +class CC_EXPORT TileManager : public RasterWorkerPoolClient, + public RefCountedManager<Tile> { public: static scoped_ptr<TileManager> Create( TileManagerClient* client, @@ -61,6 +63,15 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient { // Returns true when visible tiles have been initialized. bool UpdateVisibleTiles(); + scoped_refptr<Tile> CreateTile(PicturePileImpl* picture_pile, + gfx::Size tile_size, + gfx::Rect content_rect, + gfx::Rect opaque_rect, + float contents_scale, + int layer_id, + int source_frame_number, + bool can_use_lcd_text); + scoped_ptr<base::Value> BasicStateAsValue() const; scoped_ptr<base::Value> AllTilesAsValue() const; void GetMemoryStats(size_t* memory_required_bytes, @@ -102,10 +113,13 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient { // Methods called by Tile friend class Tile; - void RegisterTile(Tile* tile); - void UnregisterTile(Tile* tile); void DidChangeTilePriority(Tile* tile); + void CleanUpReleasedTiles(); + + // Overriden from RefCountedManager<Tile>: + virtual void Release(Tile* tile) OVERRIDE; + // Overriden from RasterWorkerPoolClient: virtual bool ShouldForceTasksRequiredForActivationToComplete() const OVERRIDE; @@ -149,7 +163,7 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient { Tile* tile, skia::LazyPixelRef* pixel_ref); RasterWorkerPool::RasterTask CreateRasterTask(Tile* tile); scoped_ptr<base::Value> GetMemoryRequirementsAsValue() const; - PrioritizedTileSet* GetPrioritizedTileSet(); + void UpdatePrioritizedTileSetIfNeeded(); TileManagerClient* client_; scoped_ptr<ResourcePool> resource_pool_; @@ -188,6 +202,8 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient { RasterTaskCompletionStats update_visible_tiles_stats_; + std::vector<Tile*> released_tiles_; + DISALLOW_COPY_AND_ASSIGN(TileManager); }; diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc index ce70eaf..7292f1d 100644 --- a/cc/resources/tile_manager_perftest.cc +++ b/cc/resources/tile_manager_perftest.cc @@ -106,15 +106,14 @@ class TileManagerPerfTest : public testing::Test { void CreateBinTiles(int count, ManagedTileBin bin, TileBinVector* tiles) { for (int i = 0; i < count; ++i) { scoped_refptr<Tile> tile = - make_scoped_refptr(new Tile(tile_manager_.get(), - picture_pile_.get(), - settings_.default_tile_size, - gfx::Rect(), - gfx::Rect(), - 1.0, - 0, - 0, - true)); + tile_manager_->CreateTile(picture_pile_.get(), + settings_.default_tile_size, + gfx::Rect(), + gfx::Rect(), + 1.0, + 0, + 0, + true); tile->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin)); tile->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin)); tiles->push_back(std::make_pair(tile, bin)); diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index bc78695a..2f9db48 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -79,16 +79,14 @@ class TileManagerTest : public testing::TestWithParam<bool> { gfx::Size tile_size) { TileVector tiles; for (int i = 0; i < count; ++i) { - scoped_refptr<Tile> tile = - make_scoped_refptr(new Tile(tile_manager_.get(), - picture_pile_.get(), - tile_size, - gfx::Rect(), - gfx::Rect(), - 1.0, - 0, - 0, - true)); + scoped_refptr<Tile> tile = tile_manager_->CreateTile(picture_pile_.get(), + tile_size, + gfx::Rect(), + gfx::Rect(), + 1.0, + 0, + 0, + true); tile->SetPriority(ACTIVE_TREE, active_priority); tile->SetPriority(PENDING_TREE, pending_priority); tiles.push_back(tile); diff --git a/cc/test/fake_picture_layer_tiling_client.cc b/cc/test/fake_picture_layer_tiling_client.cc index 4127b01..2117618 100644 --- a/cc/test/fake_picture_layer_tiling_client.cc +++ b/cc/test/fake_picture_layer_tiling_client.cc @@ -36,16 +36,9 @@ scoped_refptr<Tile> FakePictureLayerTilingClient::CreateTile( PictureLayerTiling*, gfx::Rect rect) { if (!allow_create_tile_) - return NULL; - return new Tile(tile_manager_.get(), - pile_.get(), - tile_size_, - rect, - gfx::Rect(), - 1, - 0, - 0, - true); + return scoped_refptr<Tile>(); + return tile_manager_->CreateTile( + pile_.get(), tile_size_, rect, gfx::Rect(), 1, 0, 0, true); } void FakePictureLayerTilingClient::SetTileSize(gfx::Size tile_size) { |