summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/base/ref_counted_managed.h63
-rw-r--r--cc/cc.gyp1
-rw-r--r--cc/layers/picture_layer_impl.cc6
-rw-r--r--cc/resources/prioritized_tile_set_unittest.cc17
-rw-r--r--cc/resources/tile.cc5
-rw-r--r--cc/resources/tile.h31
-rw-r--r--cc/resources/tile_manager.cc88
-rw-r--r--cc/resources/tile_manager.h24
-rw-r--r--cc/resources/tile_manager_perftest.cc17
-rw-r--r--cc/resources/tile_manager_unittest.cc18
-rw-r--r--cc/test/fake_picture_layer_tiling_client.cc13
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_
diff --git a/cc/cc.gyp b/cc/cc.gyp
index ffc8615..4ce4228 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -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) {