summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-07 22:04:47 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-07 22:04:47 +0000
commiteeedf44230437227a66e852f1c5e1b83f25bede9 (patch)
treec3ae47e4d4f1783b73401eff31a6672501c0cf26 /cc
parent9c9e0247efce1cb09489db56f6578c840b5e6e1b (diff)
downloadchromium_src-eeedf44230437227a66e852f1c5e1b83f25bede9.zip
chromium_src-eeedf44230437227a66e852f1c5e1b83f25bede9.tar.gz
chromium_src-eeedf44230437227a66e852f1c5e1b83f25bede9.tar.bz2
cc: Added priority ref tile set instead of sorting tiles.
This patch adds a new class PriorityRefTileSet to maintain a priority ordering to tiles within TileManager. It sorts things that need sorting, and doesn't sort other things. For instance, NOW and SOON bins are sorted. EVENTUALLY and NEVER bins are not. BUG=267151 Review URL: https://chromiumcodereview.appspot.com/21945006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216284 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/cc_tests.gyp3
-rw-r--r--cc/resources/managed_tile_state.cc9
-rw-r--r--cc/resources/managed_tile_state.h24
-rw-r--r--cc/resources/prioritized_tile_set.cc126
-rw-r--r--cc/resources/prioritized_tile_set.h56
-rw-r--r--cc/resources/prioritized_tile_set_unittest.cc470
-rw-r--r--cc/resources/tile.h1
-rw-r--r--cc/resources/tile_manager.cc207
-rw-r--r--cc/resources/tile_manager.h11
-rw-r--r--cc/resources/tile_manager_perftest.cc51
-rw-r--r--cc/resources/tile_manager_unittest.cc51
-rw-r--r--cc/test/fake_picture_pile_impl.cc10
-rw-r--r--cc/test/fake_picture_pile_impl.h2
-rw-r--r--cc/test/fake_tile_manager.cc6
-rw-r--r--cc/test/fake_tile_manager.h2
-rw-r--r--cc/test/test_tile_priorities.cc23
-rw-r--r--cc/test/test_tile_priorities.h34
18 files changed, 869 insertions, 219 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 315e10a3..78060a4 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -292,6 +292,8 @@
'resources/prioritized_resource.h',
'resources/prioritized_resource_manager.cc',
'resources/prioritized_resource_manager.h',
+ 'resources/prioritized_tile_set.cc',
+ 'resources/prioritized_tile_set.h',
'resources/priority_calculator.cc',
'resources/priority_calculator.h',
'resources/raster_mode.cc',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index f633ce4..7e2ff87 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -54,6 +54,7 @@
'resources/picture_pile_unittest.cc',
'resources/picture_unittest.cc',
'resources/prioritized_resource_unittest.cc',
+ 'resources/prioritized_tile_set_unittest.cc',
'resources/raster_worker_pool_unittest.cc',
'resources/resource_provider_unittest.cc',
'resources/resource_update_controller_unittest.cc',
@@ -171,6 +172,8 @@
'test/solid_color_content_layer_client.cc',
'test/skia_common.cc',
'test/skia_common.h',
+ 'test/test_tile_priorities.cc',
+ 'test/test_tile_priorities.h',
'test/test_web_graphics_context_3d.cc',
'test/test_web_graphics_context_3d.h',
'test/tiled_layer_test_common.cc',
diff --git a/cc/resources/managed_tile_state.cc b/cc/resources/managed_tile_state.cc
index f5607ea..6f85331 100644
--- a/cc/resources/managed_tile_state.cc
+++ b/cc/resources/managed_tile_state.cc
@@ -12,15 +12,24 @@ namespace cc {
scoped_ptr<base::Value> ManagedTileBinAsValue(ManagedTileBin bin) {
switch (bin) {
+ case NOW_AND_READY_TO_DRAW_BIN:
+ return scoped_ptr<base::Value>(base::Value::CreateStringValue(
+ "NOW_AND_READY_TO_DRAW_BIN"));
case NOW_BIN:
return scoped_ptr<base::Value>(base::Value::CreateStringValue(
"NOW_BIN"));
case SOON_BIN:
return scoped_ptr<base::Value>(base::Value::CreateStringValue(
"SOON_BIN"));
+ case EVENTUALLY_AND_ACTIVE_BIN:
+ return scoped_ptr<base::Value>(base::Value::CreateStringValue(
+ "EVENTUALLY_AND_ACTIVE_BIN"));
case EVENTUALLY_BIN:
return scoped_ptr<base::Value>(base::Value::CreateStringValue(
"EVENTUALLY_BIN"));
+ case NEVER_AND_ACTIVE_BIN:
+ return scoped_ptr<base::Value>(base::Value::CreateStringValue(
+ "NEVER_AND_ACTIVE_BIN"));
case NEVER_BIN:
return scoped_ptr<base::Value>(base::Value::CreateStringValue(
"NEVER_BIN"));
diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h
index 2f61b39..c6065f9 100644
--- a/cc/resources/managed_tile_state.h
+++ b/cc/resources/managed_tile_state.h
@@ -17,11 +17,14 @@ class TileManager;
// Tile manager classifying tiles into a few basic bins:
enum ManagedTileBin {
- NOW_BIN = 0, // Needed ASAP.
- SOON_BIN = 1, // Impl-side version of prepainting.
- EVENTUALLY_BIN = 2, // Nice to have, if we've got memory and time.
- NEVER_BIN = 3, // Dont bother.
- NUM_BINS = 4
+ NOW_AND_READY_TO_DRAW_BIN = 0, // Ready to draw and within viewport.
+ NOW_BIN = 1, // Needed ASAP.
+ SOON_BIN = 2, // Impl-side version of prepainting.
+ EVENTUALLY_AND_ACTIVE_BIN = 3, // Nice to have, and has a task or resource.
+ EVENTUALLY_BIN = 4, // Nice to have, if we've got memory and time.
+ NEVER_AND_ACTIVE_BIN = 5, // Dont bother, but has a task or resource.
+ NEVER_BIN = 6, // Dont bother.
+ NUM_BINS = 7
// NOTE: Be sure to update ManagedTileBinAsValue and kBinPolicyMap when adding
// or reordering fields.
};
@@ -98,6 +101,7 @@ class CC_EXPORT ManagedTileState {
private:
friend class TileManager;
+ friend class PrioritizedTileSet;
friend class Tile;
friend class ManagedTileState;
@@ -136,12 +140,10 @@ class CC_EXPORT ManagedTileState {
// Ephemeral state, valid only during TileManager::ManageTiles.
bool is_in_never_bin_on_both_trees() const {
- return bin[HIGH_PRIORITY_BIN] == NEVER_BIN &&
- bin[LOW_PRIORITY_BIN] == NEVER_BIN;
- }
- bool is_in_now_bin_on_either_tree() const {
- return bin[HIGH_PRIORITY_BIN] == NOW_BIN ||
- bin[LOW_PRIORITY_BIN] == NOW_BIN;
+ return (bin[HIGH_PRIORITY_BIN] == NEVER_BIN ||
+ bin[HIGH_PRIORITY_BIN] == NEVER_AND_ACTIVE_BIN) &&
+ (bin[LOW_PRIORITY_BIN] == NEVER_BIN ||
+ bin[LOW_PRIORITY_BIN] == NEVER_AND_ACTIVE_BIN);
}
ManagedTileBin bin[NUM_BIN_PRIORITIES];
diff --git a/cc/resources/prioritized_tile_set.cc b/cc/resources/prioritized_tile_set.cc
new file mode 100644
index 0000000..5b40945
--- /dev/null
+++ b/cc/resources/prioritized_tile_set.cc
@@ -0,0 +1,126 @@
+// 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.
+
+#include "cc/resources/prioritized_tile_set.h"
+
+#include <algorithm>
+
+#include "cc/resources/managed_tile_state.h"
+#include "cc/resources/tile.h"
+
+namespace cc {
+
+class BinComparator {
+ public:
+ bool operator()(const scoped_refptr<Tile>& a,
+ const scoped_refptr<Tile>& b) const {
+ const ManagedTileState& ams = a->managed_state();
+ const ManagedTileState& bms = b->managed_state();
+
+ if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN])
+ return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN];
+
+ if (ams.required_for_activation != bms.required_for_activation)
+ return ams.required_for_activation;
+
+ if (ams.resolution != bms.resolution)
+ return ams.resolution < bms.resolution;
+
+ if (ams.time_to_needed_in_seconds != bms.time_to_needed_in_seconds)
+ return ams.time_to_needed_in_seconds < bms.time_to_needed_in_seconds;
+
+ if (ams.distance_to_visible_in_pixels !=
+ bms.distance_to_visible_in_pixels) {
+ return ams.distance_to_visible_in_pixels <
+ bms.distance_to_visible_in_pixels;
+ }
+
+ gfx::Rect a_rect = a->content_rect();
+ gfx::Rect b_rect = b->content_rect();
+ if (a_rect.y() != b_rect.y())
+ return a_rect.y() < b_rect.y();
+ return a_rect.x() < b_rect.x();
+ }
+};
+
+namespace {
+
+typedef std::vector<scoped_refptr<Tile> > TileVector;
+
+void SortBinTiles(ManagedTileBin bin, TileVector* tiles) {
+ switch (bin) {
+ case NOW_AND_READY_TO_DRAW_BIN:
+ break;
+ case NOW_BIN:
+ case SOON_BIN:
+ case EVENTUALLY_AND_ACTIVE_BIN:
+ case EVENTUALLY_BIN:
+ case NEVER_AND_ACTIVE_BIN:
+ case NEVER_BIN:
+ std::sort(tiles->begin(), tiles->end(), BinComparator());
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace
+
+PrioritizedTileSet::PrioritizedTileSet() {}
+
+PrioritizedTileSet::~PrioritizedTileSet() {}
+
+void PrioritizedTileSet::InsertTile(Tile* tile, ManagedTileBin bin) {
+ tiles_[bin].push_back(make_scoped_refptr(tile));
+}
+
+void PrioritizedTileSet::Clear() {
+ for (int bin = 0; bin < NUM_BINS; ++bin)
+ tiles_[bin].clear();
+}
+
+void PrioritizedTileSet::Sort() {
+ for (int bin = 0; bin < NUM_BINS; ++bin)
+ SortBinTiles(static_cast<ManagedTileBin>(bin), &tiles_[bin]);
+}
+
+PrioritizedTileSet::PriorityIterator::PriorityIterator(
+ PrioritizedTileSet* tile_set)
+ : tile_set_(tile_set),
+ current_bin_(NOW_AND_READY_TO_DRAW_BIN),
+ iterator_(tile_set->tiles_[current_bin_].begin()) {
+ if (iterator_ == tile_set_->tiles_[current_bin_].end())
+ AdvanceList();
+}
+
+PrioritizedTileSet::PriorityIterator::~PriorityIterator() {}
+
+PrioritizedTileSet::PriorityIterator&
+PrioritizedTileSet::PriorityIterator::operator++() {
+ // We can't increment past the end of the tiles.
+ DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end());
+
+ ++iterator_;
+ if (iterator_ == tile_set_->tiles_[current_bin_].end())
+ AdvanceList();
+ return *this;
+}
+
+Tile* PrioritizedTileSet::PriorityIterator::operator*() {
+ DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end());
+ return iterator_->get();
+}
+
+void PrioritizedTileSet::PriorityIterator::AdvanceList() {
+ DCHECK(iterator_ == tile_set_->tiles_[current_bin_].end());
+
+ while (current_bin_ != NEVER_BIN) {
+ current_bin_ = static_cast<ManagedTileBin>(current_bin_ + 1);
+ iterator_ = tile_set_->tiles_[current_bin_].begin();
+ if (iterator_ != tile_set_->tiles_[current_bin_].end())
+ break;
+ }
+}
+
+} // namespace cc
diff --git a/cc/resources/prioritized_tile_set.h b/cc/resources/prioritized_tile_set.h
new file mode 100644
index 0000000..fe1b2a0
--- /dev/null
+++ b/cc/resources/prioritized_tile_set.h
@@ -0,0 +1,56 @@
+// 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_RESOURCES_PRIORITIZED_TILE_SET_H_
+#define CC_RESOURCES_PRIORITIZED_TILE_SET_H_
+
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+#include "cc/resources/managed_tile_state.h"
+
+namespace cc {
+class Tile;
+
+class CC_EXPORT PrioritizedTileSet {
+ public:
+ PrioritizedTileSet();
+ ~PrioritizedTileSet();
+
+ void InsertTile(Tile* tile, ManagedTileBin bin);
+ void Clear();
+ void Sort();
+
+ class CC_EXPORT PriorityIterator {
+ public:
+ explicit PriorityIterator(PrioritizedTileSet* set);
+ ~PriorityIterator();
+
+ PriorityIterator& operator++();
+ Tile* operator->() { return *(*this); }
+ Tile* operator*();
+ operator bool() const {
+ return iterator_ != tile_set_->tiles_[current_bin_].end();
+ }
+
+ private:
+ void AdvanceList();
+
+ PrioritizedTileSet* tile_set_;
+ ManagedTileBin current_bin_;
+ std::vector<scoped_refptr<Tile> >::iterator iterator_;
+ };
+
+ private:
+ friend class PriorityIterator;
+
+ typedef scoped_refptr<Tile> TileRef;
+ std::vector<TileRef> tiles_[NUM_BINS];
+};
+
+} // namespace cc
+
+#endif // CC_RESOURCES_PRIORITIZED_TILE_SET_H_
diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc
new file mode 100644
index 0000000..645fa04
--- /dev/null
+++ b/cc/resources/prioritized_tile_set_unittest.cc
@@ -0,0 +1,470 @@
+// 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.
+
+#include <algorithm>
+#include <vector>
+
+#include "cc/resources/managed_tile_state.h"
+#include "cc/resources/prioritized_tile_set.h"
+#include "cc/resources/tile.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_picture_pile_impl.h"
+#include "cc/test/fake_tile_manager.h"
+#include "cc/test/fake_tile_manager_client.h"
+#include "cc/test/test_tile_priorities.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+
+class BinComparator {
+ public:
+ bool operator()(const scoped_refptr<Tile>& a,
+ const scoped_refptr<Tile>& b) const {
+ const ManagedTileState& ams = a->managed_state();
+ const ManagedTileState& bms = b->managed_state();
+
+ if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN])
+ return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN];
+
+ if (ams.required_for_activation != bms.required_for_activation)
+ return ams.required_for_activation;
+
+ if (ams.resolution != bms.resolution)
+ return ams.resolution < bms.resolution;
+
+ if (ams.time_to_needed_in_seconds != bms.time_to_needed_in_seconds)
+ return ams.time_to_needed_in_seconds < bms.time_to_needed_in_seconds;
+
+ if (ams.distance_to_visible_in_pixels !=
+ bms.distance_to_visible_in_pixels) {
+ return ams.distance_to_visible_in_pixels <
+ bms.distance_to_visible_in_pixels;
+ }
+
+ gfx::Rect a_rect = a->content_rect();
+ gfx::Rect b_rect = b->content_rect();
+ if (a_rect.y() != b_rect.y())
+ return a_rect.y() < b_rect.y();
+ return a_rect.x() < b_rect.x();
+ }
+};
+
+namespace {
+
+class PrioritizedTileSetTest : public testing::Test {
+ public:
+ PrioritizedTileSetTest()
+ : output_surface_(FakeOutputSurface::Create3d()),
+ resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)),
+ tile_manager_(new FakeTileManager(&tile_manager_client_,
+ resource_provider_.get())),
+ picture_pile_(FakePicturePileImpl::CreatePile()) {}
+
+ 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));
+ }
+
+ private:
+ FakeTileManagerClient tile_manager_client_;
+ LayerTreeSettings settings_;
+ scoped_ptr<FakeOutputSurface> output_surface_;
+ scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<FakeTileManager> tile_manager_;
+ scoped_refptr<FakePicturePileImpl> picture_pile_;
+};
+
+TEST_F(PrioritizedTileSetTest, EmptyIterator) {
+ PrioritizedTileSet set;
+ set.Sort();
+
+ PrioritizedTileSet::PriorityIterator it(&set);
+ EXPECT_FALSE(it);
+}
+
+TEST_F(PrioritizedTileSetTest, NonEmptyIterator) {
+ PrioritizedTileSet set;
+ scoped_refptr<Tile> tile = CreateTile();
+ set.InsertTile(tile, NOW_BIN);
+ set.Sort();
+
+ PrioritizedTileSet::PriorityIterator it(&set);
+ EXPECT_TRUE(it);
+ EXPECT_TRUE(*it == tile.get());
+ ++it;
+ EXPECT_FALSE(it);
+}
+
+TEST_F(PrioritizedTileSetTest, NowAndReadyToDrawBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, NOW_AND_READY_TO_DRAW_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in the same order as inserted.
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, NowBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, NOW_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in BinComparator order.
+ std::sort(tiles.begin(), tiles.end(), BinComparator());
+
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, SoonBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, SOON_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in BinComparator order.
+ std::sort(tiles.begin(), tiles.end(), BinComparator());
+
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, EventuallyAndActiveBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, EVENTUALLY_AND_ACTIVE_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in BinComparator order.
+ std::sort(tiles.begin(), tiles.end(), BinComparator());
+
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, EventuallyBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, EVENTUALLY_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in BinComparator order.
+ std::sort(tiles.begin(), tiles.end(), BinComparator());
+
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, NeverAndActiveBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, NEVER_AND_ACTIVE_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in BinComparator order.
+ std::sort(tiles.begin(), tiles.end(), BinComparator());
+
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, NeverBin) {
+ PrioritizedTileSet set;
+ TilePriority priorities[4] = {
+ TilePriorityForEventualBin(),
+ TilePriorityForNowBin(),
+ TilePriority(),
+ TilePriorityForSoonBin()};
+
+ std::vector<scoped_refptr<Tile> > tiles;
+ for (int priority = 0; priority < 4; ++priority) {
+ for (int i = 0; i < 5; ++i) {
+ scoped_refptr<Tile> tile = CreateTile();
+ tile->SetPriority(ACTIVE_TREE, priorities[priority]);
+ tile->SetPriority(PENDING_TREE, priorities[priority]);
+ tiles.push_back(tile);
+ set.InsertTile(tile, NEVER_BIN);
+ }
+ }
+
+ set.Sort();
+
+ // Tiles should appear in BinComparator order.
+ std::sort(tiles.begin(), tiles.end(), BinComparator());
+
+ int i = 0;
+ for (PrioritizedTileSet::PriorityIterator it(&set);
+ it;
+ ++it) {
+ EXPECT_TRUE(*it == tiles[i].get());
+ ++i;
+ }
+ EXPECT_EQ(20, i);
+}
+
+TEST_F(PrioritizedTileSetTest, TilesForEachBin) {
+ scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile();
+ scoped_refptr<Tile> now_bin = CreateTile();
+ scoped_refptr<Tile> soon_bin = CreateTile();
+ scoped_refptr<Tile> eventually_and_active_bin = CreateTile();
+ scoped_refptr<Tile> eventually_bin = CreateTile();
+ scoped_refptr<Tile> never_bin = CreateTile();
+ scoped_refptr<Tile> never_and_active_bin = CreateTile();
+
+ PrioritizedTileSet set;
+ set.InsertTile(soon_bin, SOON_BIN);
+ set.InsertTile(never_and_active_bin, NEVER_AND_ACTIVE_BIN);
+ set.InsertTile(eventually_bin, EVENTUALLY_BIN);
+ set.InsertTile(now_bin, NOW_BIN);
+ set.InsertTile(eventually_and_active_bin, EVENTUALLY_AND_ACTIVE_BIN);
+ set.InsertTile(never_bin, NEVER_BIN);
+ set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN);
+
+ set.Sort();
+
+ // Tiles should appear in order.
+ PrioritizedTileSet::PriorityIterator it(&set);
+ EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == now_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == soon_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == eventually_and_active_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == eventually_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == never_and_active_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == never_bin.get());
+ ++it;
+ EXPECT_FALSE(it);
+}
+
+TEST_F(PrioritizedTileSetTest, TilesForFirstAndLastBins) {
+ scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile();
+ scoped_refptr<Tile> never_bin = CreateTile();
+
+ PrioritizedTileSet set;
+ set.InsertTile(never_bin, NEVER_BIN);
+ set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN);
+
+ set.Sort();
+
+ // Only two tiles should appear and they should appear in order.
+ PrioritizedTileSet::PriorityIterator it(&set);
+ EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == never_bin.get());
+ ++it;
+ EXPECT_FALSE(it);
+}
+
+TEST_F(PrioritizedTileSetTest, MultipleIterators) {
+ scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile();
+ scoped_refptr<Tile> now_bin = CreateTile();
+ scoped_refptr<Tile> soon_bin = CreateTile();
+ scoped_refptr<Tile> eventually_bin = CreateTile();
+ scoped_refptr<Tile> never_bin = CreateTile();
+
+ PrioritizedTileSet set;
+ set.InsertTile(soon_bin, SOON_BIN);
+ set.InsertTile(eventually_bin, EVENTUALLY_BIN);
+ set.InsertTile(now_bin, NOW_BIN);
+ set.InsertTile(never_bin, NEVER_BIN);
+ set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN);
+
+ set.Sort();
+
+ // Tiles should appear in order.
+ PrioritizedTileSet::PriorityIterator it(&set);
+ EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == now_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == soon_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == eventually_bin.get());
+ ++it;
+ EXPECT_TRUE(*it == never_bin.get());
+ ++it;
+ EXPECT_FALSE(it);
+
+ // Creating multiple iterators shouldn't affect old iterators.
+ PrioritizedTileSet::PriorityIterator second_it(&set);
+ EXPECT_TRUE(second_it);
+ EXPECT_FALSE(it);
+
+ ++second_it;
+ EXPECT_TRUE(second_it);
+ ++second_it;
+ EXPECT_TRUE(second_it);
+ EXPECT_FALSE(it);
+
+ PrioritizedTileSet::PriorityIterator third_it(&set);
+ EXPECT_TRUE(third_it);
+ ++second_it;
+ ++second_it;
+ EXPECT_TRUE(second_it);
+ EXPECT_TRUE(third_it);
+ EXPECT_FALSE(it);
+
+ ++third_it;
+ ++third_it;
+ EXPECT_TRUE(third_it);
+ EXPECT_TRUE(*third_it == soon_bin.get());
+ EXPECT_TRUE(second_it);
+ EXPECT_TRUE(*second_it == never_bin.get());
+ EXPECT_FALSE(it);
+
+ ++second_it;
+ EXPECT_TRUE(third_it);
+ EXPECT_FALSE(second_it);
+ EXPECT_FALSE(it);
+
+ set.Clear();
+
+ PrioritizedTileSet::PriorityIterator empty_it(&set);
+ EXPECT_FALSE(empty_it);
+}
+
+} // namespace
+} // namespace cc
+
diff --git a/cc/resources/tile.h b/cc/resources/tile.h
index 408d4b1..be9b19a 100644
--- a/cc/resources/tile.h
+++ b/cc/resources/tile.h
@@ -120,6 +120,7 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
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_; }
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 41e2631..aa6c1ad 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -27,32 +27,46 @@ namespace {
// Memory limit policy works by mapping some bin states to the NEVER bin.
const ManagedTileBin kBinPolicyMap[NUM_TILE_MEMORY_LIMIT_POLICIES][NUM_BINS] = {
{ // [ALLOW_NOTHING]
- NEVER_BIN, // [NOW_BIN]
- NEVER_BIN, // [SOON_BIN]
- NEVER_BIN, // [EVENTUALLY_BIN]
- NEVER_BIN // [NEVER_BIN]
+ NEVER_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
+ NEVER_BIN, // [NOW_BIN]
+ NEVER_BIN, // [SOON_BIN]
+ NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
+ NEVER_BIN, // [EVENTUALLY_BIN]
+ NEVER_BIN, // [NEVER_AND_ACTIVE_BIN]
+ NEVER_BIN // [NEVER_BIN]
}, { // [ALLOW_ABSOLUTE_MINIMUM]
- NOW_BIN, // [NOW_BIN]
- NEVER_BIN, // [SOON_BIN]
- NEVER_BIN, // [EVENTUALLY_BIN]
- NEVER_BIN // [NEVER_BIN]
+ NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
+ NOW_BIN, // [NOW_BIN]
+ NEVER_BIN, // [SOON_BIN]
+ NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
+ NEVER_BIN, // [EVENTUALLY_BIN]
+ NEVER_BIN, // [NEVER_AND_ACTIVE_BIN]
+ NEVER_BIN // [NEVER_BIN]
}, { // [ALLOW_PREPAINT_ONLY]
- NOW_BIN, // [NOW_BIN]
- SOON_BIN, // [SOON_BIN]
- NEVER_BIN, // [EVENTUALLY_BIN]
- NEVER_BIN // [NEVER_BIN]
+ NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
+ NOW_BIN, // [NOW_BIN]
+ SOON_BIN, // [SOON_BIN]
+ NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
+ NEVER_BIN, // [EVENTUALLY_BIN]
+ NEVER_BIN, // [NEVER_AND_ACTIVE_BIN]
+ NEVER_BIN // [NEVER_BIN]
}, { // [ALLOW_ANYTHING]
- NOW_BIN, // [NOW_BIN]
- SOON_BIN, // [SOON_BIN]
- EVENTUALLY_BIN, // [EVENTUALLY_BIN]
- NEVER_BIN // [NEVER_BIN]
+ NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
+ NOW_BIN, // [NOW_BIN]
+ SOON_BIN, // [SOON_BIN]
+ EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
+ EVENTUALLY_BIN, // [EVENTUALLY_BIN]
+ NEVER_AND_ACTIVE_BIN, // [NEVER_AND_ACTIVE_BIN]
+ NEVER_BIN // [NEVER_BIN]
}
};
// Determine bin based on three categories of tiles: things we need now,
// things we need soon, and eventually.
inline ManagedTileBin BinFromTilePriority(const TilePriority& prio,
- TreePriority tree_priority) {
+ TreePriority tree_priority,
+ bool is_ready_to_draw,
+ bool is_active) {
// The amount of time for which we want to have prepainting coverage.
const float kPrepaintingWindowTimeSeconds = 1.0f;
const float kBackflingGuardDistancePixels = 314.0f;
@@ -64,19 +78,19 @@ inline ManagedTileBin BinFromTilePriority(const TilePriority& prio,
if (prio.distance_to_visible_in_pixels ==
std::numeric_limits<float>::infinity())
- return NEVER_BIN;
+ return is_active ? NEVER_AND_ACTIVE_BIN : NEVER_BIN;
if (can_be_in_now_bin && prio.time_to_visible_in_seconds == 0)
- return NOW_BIN;
+ return is_ready_to_draw ? NOW_AND_READY_TO_DRAW_BIN : NOW_BIN;
if (prio.resolution == NON_IDEAL_RESOLUTION)
- return EVENTUALLY_BIN;
+ return is_active ? EVENTUALLY_AND_ACTIVE_BIN : EVENTUALLY_BIN;
if (prio.distance_to_visible_in_pixels < kBackflingGuardDistancePixels ||
prio.time_to_visible_in_seconds < kPrepaintingWindowTimeSeconds)
return SOON_BIN;
- return EVENTUALLY_BIN;
+ return is_active ? EVENTUALLY_AND_ACTIVE_BIN : EVENTUALLY_BIN;
}
// Limit to the number of raster tasks that can be scheduled.
@@ -145,8 +159,8 @@ TileManager::~TileManager() {
// our memory usage to drop to zero.
global_state_ = GlobalStateThatImpactsTilePriority();
- // Clear |sorted_tiles_| so that tiles kept alive by it can be freed.
- sorted_tiles_.clear();
+ // Clear |prioritized_tiles_| so that tiles kept alive by it can be freed.
+ prioritized_tiles_.Clear();
DCHECK_EQ(0u, tiles_.size());
TileVector empty;
@@ -196,7 +210,8 @@ void TileManager::DidFinishRunningTasks() {
raster_worker_pool_->CheckForCompletedTasks();
TileVector tiles_that_need_to_be_rasterized;
- AssignGpuMemoryToTiles(sorted_tiles_, &tiles_that_need_to_be_rasterized);
+ AssignGpuMemoryToTiles(&prioritized_tiles_,
+ &tiles_that_need_to_be_rasterized);
// |tiles_that_need_to_be_rasterized| will be empty when we reach a
// steady memory state. Keep scheduling tasks until we reach this state.
@@ -233,51 +248,9 @@ void TileManager::DidFinishRunningTasksRequiredForActivation() {
client_->NotifyReadyToActivate();
}
-class BinComparator {
- public:
- bool operator()(const scoped_refptr<Tile>& a,
- const scoped_refptr<Tile>& b) const {
- const ManagedTileState& ams = a->managed_state();
- const ManagedTileState& bms = b->managed_state();
-
- if (ams.visible_and_ready_to_draw != bms.visible_and_ready_to_draw)
- return ams.visible_and_ready_to_draw;
-
- if (ams.bin[HIGH_PRIORITY_BIN] != bms.bin[HIGH_PRIORITY_BIN])
- return ams.bin[HIGH_PRIORITY_BIN] < bms.bin[HIGH_PRIORITY_BIN];
-
- if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN])
- return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN];
-
- if (ams.required_for_activation != bms.required_for_activation)
- return ams.required_for_activation;
-
- if (ams.resolution != bms.resolution)
- return ams.resolution < bms.resolution;
-
- if (ams.time_to_needed_in_seconds != bms.time_to_needed_in_seconds)
- return ams.time_to_needed_in_seconds < bms.time_to_needed_in_seconds;
-
- if (ams.distance_to_visible_in_pixels !=
- bms.distance_to_visible_in_pixels) {
- return ams.distance_to_visible_in_pixels <
- bms.distance_to_visible_in_pixels;
- }
-
- gfx::Rect a_rect = a->content_rect();
- gfx::Rect b_rect = b->content_rect();
- if (a_rect.y() != b_rect.y())
- return a_rect.y() < b_rect.y();
- return a_rect.x() < b_rect.x();
- }
-};
-
-void TileManager::GetTilesWithAssignedBins(TileRefVector* tiles) {
+void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins");
- DCHECK_EQ(0u, tiles->size());
- tiles->reserve(tiles_.size());
-
const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy;
const TreePriority tree_priority = global_state_.tree_priority;
@@ -302,6 +275,11 @@ void TileManager::GetTilesWithAssignedBins(TileRefVector* tiles) {
break;
}
+ bool tile_is_ready_to_draw = tile->IsReadyToDraw();
+ bool tile_is_active =
+ tile_is_ready_to_draw ||
+ !mts.tile_versions[mts.raster_mode].raster_task_.is_null();
+
mts.resolution = prio[HIGH_PRIORITY_BIN].resolution;
mts.time_to_needed_in_seconds =
prio[HIGH_PRIORITY_BIN].time_to_visible_in_seconds;
@@ -309,56 +287,80 @@ void TileManager::GetTilesWithAssignedBins(TileRefVector* tiles) {
prio[HIGH_PRIORITY_BIN].distance_to_visible_in_pixels;
mts.required_for_activation =
prio[HIGH_PRIORITY_BIN].required_for_activation;
+
mts.bin[HIGH_PRIORITY_BIN] =
- BinFromTilePriority(prio[HIGH_PRIORITY_BIN], tree_priority);
+ BinFromTilePriority(prio[HIGH_PRIORITY_BIN],
+ tree_priority,
+ tile_is_ready_to_draw,
+ tile_is_active);
mts.bin[LOW_PRIORITY_BIN] =
- BinFromTilePriority(prio[LOW_PRIORITY_BIN], tree_priority);
+ BinFromTilePriority(prio[LOW_PRIORITY_BIN],
+ tree_priority,
+ tile_is_ready_to_draw,
+ tile_is_active);
mts.gpu_memmgr_stats_bin =
- BinFromTilePriority(tile->combined_priority(), tree_priority);
-
- mts.tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][
- BinFromTilePriority(tile->priority(ACTIVE_TREE), tree_priority)];
- mts.tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][
- BinFromTilePriority(tile->priority(PENDING_TREE), tree_priority)];
+ BinFromTilePriority(tile->combined_priority(),
+ tree_priority,
+ tile_is_ready_to_draw,
+ tile_is_active);
+
+ ManagedTileBin active_bin =
+ BinFromTilePriority(tile->priority(ACTIVE_TREE),
+ tree_priority,
+ tile_is_ready_to_draw,
+ tile_is_active);
+ mts.tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
+
+ ManagedTileBin pending_bin =
+ BinFromTilePriority(tile->priority(PENDING_TREE),
+ tree_priority,
+ tile_is_ready_to_draw,
+ tile_is_active);
+ mts.tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
for (int i = 0; i < NUM_BIN_PRIORITIES; ++i)
mts.bin[i] = kBinPolicyMap[memory_policy][mts.bin[i]];
mts.visible_and_ready_to_draw =
- mts.tree_bin[ACTIVE_TREE] == NOW_BIN && tile->IsReadyToDraw();
+ mts.tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
- // Skip and free resources for tiles in the NEVER_BIN on both trees.
- if (mts.is_in_never_bin_on_both_trees())
+ if (mts.is_in_never_bin_on_both_trees()) {
FreeResourcesForTile(tile);
- else
- tiles->push_back(make_scoped_refptr(tile));
- }
-}
-
-void TileManager::SortTiles(TileRefVector* tiles) {
- TRACE_EVENT0("cc", "TileManager::SortTiles");
+ continue;
+ }
- // Sort by bin, resolution and time until needed.
- std::sort(tiles->begin(), tiles->end(), BinComparator());
+ // Note that if the tile is visible_and_ready_to_draw, then we always want
+ // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN
+ // is something different. The reason for this is that if we're prioritizing
+ // the pending tree, we still want visible tiles to take the highest
+ // priority.
+ ManagedTileBin priority_bin = mts.visible_and_ready_to_draw
+ ? NOW_AND_READY_TO_DRAW_BIN
+ : mts.bin[HIGH_PRIORITY_BIN];
+
+ // Insert the tile into a priority set.
+ tiles->InsertTile(tile, priority_bin);
+ }
}
-void TileManager::GetSortedTilesWithAssignedBins(TileRefVector* tiles) {
- TRACE_EVENT0("cc", "TileManager::GetSortedTilesWithAssignedBins");
+void TileManager::GetPrioritizedTileSet(PrioritizedTileSet* tiles) {
+ TRACE_EVENT0("cc", "TileManager::GetPrioritizedTileSet");
GetTilesWithAssignedBins(tiles);
- SortTiles(tiles);
+ tiles->Sort();
}
void TileManager::ManageTiles() {
TRACE_EVENT0("cc", "TileManager::ManageTiles");
- // Clear |sorted_tiles_| so that tiles kept alive by it can be freed.
- sorted_tiles_.clear();
+ // Clear |prioritized_tiles_| so that tiles kept alive by it can be freed.
+ prioritized_tiles_.Clear();
- GetSortedTilesWithAssignedBins(&sorted_tiles_);
+ GetPrioritizedTileSet(&prioritized_tiles_);
TileVector tiles_that_need_to_be_rasterized;
- AssignGpuMemoryToTiles(sorted_tiles_, &tiles_that_need_to_be_rasterized);
+ AssignGpuMemoryToTiles(&prioritized_tiles_,
+ &tiles_that_need_to_be_rasterized);
CleanUpUnusedImageDecodeTasks();
TRACE_EVENT_INSTANT1(
@@ -406,7 +408,8 @@ void TileManager::GetMemoryStats(
continue;
size_t tile_bytes = tile->bytes_consumed_if_allocated();
- if (mts.gpu_memmgr_stats_bin == NOW_BIN)
+ if ((mts.gpu_memmgr_stats_bin == NOW_BIN) ||
+ (mts.gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN))
*memory_required_bytes += tile_bytes;
if (mts.gpu_memmgr_stats_bin != NEVER_BIN)
*memory_nice_to_have_bytes += tile_bytes;
@@ -468,7 +471,7 @@ RasterMode TileManager::DetermineRasterMode(const Tile* tile) const {
}
void TileManager::AssignGpuMemoryToTiles(
- const TileRefVector& sorted_tiles,
+ PrioritizedTileSet* tiles,
TileVector* tiles_that_need_to_be_rasterized) {
TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
@@ -476,10 +479,10 @@ void TileManager::AssignGpuMemoryToTiles(
// the needs-to-be-rasterized queue.
size_t bytes_releasable = 0;
size_t resources_releasable = 0;
- for (TileRefVector::const_iterator it = sorted_tiles.begin();
- it != sorted_tiles.end();
+ for (PrioritizedTileSet::PriorityIterator it(tiles);
+ it;
++it) {
- const Tile* tile = it->get();
+ const Tile* tile = *it;
const ManagedTileState& mts = tile->managed_state();
for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
if (mts.tile_versions[mode].resource_) {
@@ -512,10 +515,10 @@ void TileManager::AssignGpuMemoryToTiles(
bool oomed = false;
unsigned schedule_priority = 1u;
- for (TileRefVector::const_iterator it = sorted_tiles.begin();
- it != sorted_tiles.end();
+ for (PrioritizedTileSet::PriorityIterator it(tiles);
+ it;
++it) {
- Tile* tile = it->get();
+ Tile* tile = *it;
ManagedTileState& mts = tile->managed_state();
mts.scheduled_priority = schedule_priority++;
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index f6f5785..2e226c9 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -16,6 +16,7 @@
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/memory_history.h"
#include "cc/resources/picture_pile_impl.h"
+#include "cc/resources/prioritized_tile_set.h"
#include "cc/resources/raster_worker_pool.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/tile.h"
@@ -98,7 +99,6 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient {
virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE;
typedef std::vector<Tile*> TileVector;
- typedef std::vector<scoped_refptr<Tile> > TileRefVector;
typedef std::set<Tile*> TileSet;
// Virtual for test
@@ -106,11 +106,10 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient {
const TileVector& tiles_that_need_to_be_rasterized);
void AssignGpuMemoryToTiles(
- const TileRefVector& sorted_tiles,
+ PrioritizedTileSet* tiles,
TileVector* tiles_that_need_to_be_rasterized);
- void GetTilesWithAssignedBins(TileRefVector* tiles);
- void SortTiles(TileRefVector* tiles);
- void GetSortedTilesWithAssignedBins(TileRefVector* tiles);
+ void GetTilesWithAssignedBins(PrioritizedTileSet* tiles);
+ void GetPrioritizedTileSet(PrioritizedTileSet* tiles);
private:
void OnImageDecodeTaskCompleted(
@@ -142,7 +141,7 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient {
typedef base::hash_map<Tile::Id, Tile*> TileMap;
TileMap tiles_;
- TileRefVector sorted_tiles_;
+ PrioritizedTileSet prioritized_tiles_;
bool all_tiles_that_need_to_be_rasterized_have_memory_;
bool all_tiles_required_for_activation_have_memory_;
diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc
index 677dffc..ca6f997 100644
--- a/cc/resources/tile_manager_perftest.cc
+++ b/cc/resources/tile_manager_perftest.cc
@@ -6,8 +6,10 @@
#include "cc/resources/tile.h"
#include "cc/resources/tile_priority.h"
#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/fake_tile_manager.h"
#include "cc/test/fake_tile_manager_client.h"
+#include "cc/test/test_tile_priorities.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,53 +21,6 @@ static const int kTimeLimitMillis = 2000;
static const int kWarmupRuns = 5;
static const int kTimeCheckInterval = 10;
-class FakePicturePileImpl : public PicturePileImpl {
- public:
- FakePicturePileImpl() {
- gfx::Size size(std::numeric_limits<int>::max(),
- std::numeric_limits<int>::max());
- Resize(size);
- recorded_region_ = Region(gfx::Rect(size));
- }
-
- protected:
- virtual ~FakePicturePileImpl() {}
-};
-
-class TilePriorityForSoonBin : public TilePriority {
- public:
- TilePriorityForSoonBin() : TilePriority(
- HIGH_RESOLUTION,
- 0.5,
- 300.0) {}
-};
-
-class TilePriorityForEventualBin : public TilePriority {
- public:
- TilePriorityForEventualBin() : TilePriority(
- NON_IDEAL_RESOLUTION,
- 1.0,
- 315.0) {}
-};
-
-class TilePriorityForNowBin : public TilePriority {
- public:
- TilePriorityForNowBin() : TilePriority(
- HIGH_RESOLUTION,
- 0,
- 0) {}
-};
-
-class TilePriorityRequiredForActivation : public TilePriority {
- public:
- TilePriorityRequiredForActivation() : TilePriority(
- HIGH_RESOLUTION,
- 0,
- 0) {
- required_for_activation = true;
- }
-};
-
class TileManagerPerfTest : public testing::Test {
public:
typedef std::vector<scoped_refptr<Tile> > TileVector;
@@ -87,7 +42,7 @@ class TileManagerPerfTest : public testing::Test {
state.tree_priority = SMOOTHNESS_TAKES_PRIORITY;
tile_manager_->SetGlobalState(state);
- picture_pile_ = make_scoped_refptr(new FakePicturePileImpl());
+ picture_pile_ = FakePicturePileImpl::CreatePile();
}
virtual void TearDown() OVERRIDE {
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index f55f1e4..6fb0690 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -5,60 +5,15 @@
#include "cc/resources/tile.h"
#include "cc/resources/tile_priority.h"
#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/fake_tile_manager.h"
#include "cc/test/fake_tile_manager_client.h"
+#include "cc/test/test_tile_priorities.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
namespace {
-class FakePicturePileImpl : public PicturePileImpl {
- public:
- FakePicturePileImpl() {
- gfx::Size size(std::numeric_limits<int>::max(),
- std::numeric_limits<int>::max());
- Resize(size);
- recorded_region_ = Region(gfx::Rect(size));
- }
-
- protected:
- virtual ~FakePicturePileImpl() {}
-};
-
-class TilePriorityForSoonBin : public TilePriority {
- public:
- TilePriorityForSoonBin() : TilePriority(
- HIGH_RESOLUTION,
- 0.5,
- 300.0) {}
-};
-
-class TilePriorityForEventualBin : public TilePriority {
- public:
- TilePriorityForEventualBin() : TilePriority(
- NON_IDEAL_RESOLUTION,
- 1.0,
- 315.0) {}
-};
-
-class TilePriorityForNowBin : public TilePriority {
- public:
- TilePriorityForNowBin() : TilePriority(
- HIGH_RESOLUTION,
- 0,
- 0) {}
-};
-
-class TilePriorityRequiredForActivation : public TilePriority {
- public:
- TilePriorityRequiredForActivation() : TilePriority(
- HIGH_RESOLUTION,
- 0,
- 0) {
- required_for_activation = true;
- }
-};
-
class TileManagerTest : public testing::TestWithParam<bool> {
public:
typedef std::vector<scoped_refptr<Tile> > TileVector;
@@ -90,7 +45,7 @@ class TileManagerTest : public testing::TestWithParam<bool> {
state.tree_priority = tree_priority;
tile_manager_->SetGlobalState(state);
- picture_pile_ = make_scoped_refptr(new FakePicturePileImpl());
+ picture_pile_ = FakePicturePileImpl::CreatePile();
}
void SetTreePriority(TreePriority tree_priority) {
diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc
index 80df818..c79d0ae 100644
--- a/cc/test/fake_picture_pile_impl.cc
+++ b/cc/test/fake_picture_pile_impl.cc
@@ -4,6 +4,7 @@
#include "cc/test/fake_picture_pile_impl.h"
+#include <limits>
#include <utility>
#include "cc/test/fake_rendering_stats_instrumentation.h"
@@ -42,6 +43,15 @@ scoped_refptr<FakePicturePileImpl> FakePicturePileImpl::CreateEmptyPile(
return pile;
}
+scoped_refptr<FakePicturePileImpl> FakePicturePileImpl::CreatePile() {
+ scoped_refptr<FakePicturePileImpl> pile(new FakePicturePileImpl());
+ gfx::Size size(std::numeric_limits<int>::max(),
+ std::numeric_limits<int>::max());
+ pile->Resize(size);
+ pile->recorded_region_ = Region(gfx::Rect(size));
+ return pile;
+}
+
void FakePicturePileImpl::AddRecordingAt(int x, int y) {
EXPECT_GE(x, 0);
EXPECT_GE(y, 0);
diff --git a/cc/test/fake_picture_pile_impl.h b/cc/test/fake_picture_pile_impl.h
index a606934..1b35ecfc 100644
--- a/cc/test/fake_picture_pile_impl.h
+++ b/cc/test/fake_picture_pile_impl.h
@@ -21,6 +21,8 @@ class FakePicturePileImpl : public PicturePileImpl {
gfx::Size tile_size,
gfx::Size layer_bounds);
+ static scoped_refptr<FakePicturePileImpl> CreatePile();
+
TilingData& tiling() { return tiling_; }
void AddRecordingAt(int x, int y);
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index e302a23..c132254 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -42,10 +42,10 @@ FakeTileManager::~FakeTileManager() {}
void FakeTileManager::AssignMemoryToTiles() {
tiles_for_raster.clear();
- all_tiles.clear();
+ all_tiles.Clear();
- GetSortedTilesWithAssignedBins(&all_tiles);
- AssignGpuMemoryToTiles(all_tiles, &tiles_for_raster);
+ GetPrioritizedTileSet(&all_tiles);
+ AssignGpuMemoryToTiles(&all_tiles, &tiles_for_raster);
}
bool FakeTileManager::HasBeenAssignedMemory(Tile* tile) {
diff --git a/cc/test/fake_tile_manager.h b/cc/test/fake_tile_manager.h
index 77dbb78..f49c0ee 100644
--- a/cc/test/fake_tile_manager.h
+++ b/cc/test/fake_tile_manager.h
@@ -24,7 +24,7 @@ class FakeTileManager : public TileManager {
virtual ~FakeTileManager();
std::vector<Tile*> tiles_for_raster;
- std::vector<scoped_refptr<Tile> > all_tiles;
+ PrioritizedTileSet all_tiles;
};
} // namespace cc
diff --git a/cc/test/test_tile_priorities.cc b/cc/test/test_tile_priorities.cc
new file mode 100644
index 0000000..f83f9b9
--- /dev/null
+++ b/cc/test/test_tile_priorities.cc
@@ -0,0 +1,23 @@
+// 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.
+
+#include "cc/test/test_tile_priorities.h"
+
+namespace cc {
+
+TilePriorityForSoonBin::TilePriorityForSoonBin()
+ : TilePriority(HIGH_RESOLUTION, 0.5, 300.0) {}
+
+TilePriorityForEventualBin::TilePriorityForEventualBin()
+ : TilePriority(NON_IDEAL_RESOLUTION, 1.0, 315.0) {}
+
+TilePriorityForNowBin::TilePriorityForNowBin()
+ : TilePriority(HIGH_RESOLUTION, 0, 0) {}
+
+TilePriorityRequiredForActivation::TilePriorityRequiredForActivation()
+ : TilePriority(HIGH_RESOLUTION, 0, 0) {
+ required_for_activation = true;
+}
+
+} // namespace cc
diff --git a/cc/test/test_tile_priorities.h b/cc/test/test_tile_priorities.h
new file mode 100644
index 0000000..cc54105
--- /dev/null
+++ b/cc/test/test_tile_priorities.h
@@ -0,0 +1,34 @@
+// 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_TEST_TEST_TILE_PRIORITIES_H_
+#define CC_TEST_TEST_TILE_PRIORITIES_H_
+
+#include "cc/resources/tile_priority.h"
+
+namespace cc {
+
+class TilePriorityForSoonBin : public TilePriority {
+ public:
+ TilePriorityForSoonBin();
+};
+
+class TilePriorityForEventualBin : public TilePriority {
+ public:
+ TilePriorityForEventualBin();
+};
+
+class TilePriorityForNowBin : public TilePriority {
+ public:
+ TilePriorityForNowBin();
+};
+
+class TilePriorityRequiredForActivation : public TilePriority {
+ public:
+ TilePriorityRequiredForActivation();
+};
+
+} // namespace cc
+
+#endif // CC_TEST_TEST_TILE_PRIORITIES_H_