Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(775)

Side by Side Diff: cc/tile_manager.cc

Issue 11417002: First draft of TileManager's tile prioritzation system (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/tile_manager.h ('k') | cc/tile_priority.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/tile_manager.h" 5 #include "cc/tile_manager.h"
6 6
7 #include <algorithm>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "cc/tile.h"
8 11
9 namespace cc { 12 namespace cc {
10 13
11 TileManager::TileManager(TileManagerClient* client) 14 TileManager::TileManager(TileManagerClient* client)
12 : client_(client) 15 : client_(client)
13 , manage_tiles_pending_(false) 16 , manage_tiles_pending_(false)
14 { 17 {
15 } 18 }
16 19
17 TileManager::~TileManager() { 20 TileManager::~TileManager() {
21 // Reset global state and manage. This should cause
22 // our memory usage to drop to zero.
23 global_state_ = GlobalStateThatImpactsTilePriority();
18 ManageTiles(); 24 ManageTiles();
19 DCHECK(tile_versions_.size() == 0); 25 DCHECK(tiles_.size() == 0);
20 } 26 }
21 27
22 void TileManager::SetGlobalState(const GlobalStateThatImpactsTilePriority& globa l_state) { 28 void TileManager::SetGlobalState(const GlobalStateThatImpactsTilePriority& globa l_state) {
23 global_state_ = global_state; 29 global_state_ = global_state;
24 ScheduleManageTiles(); 30 ScheduleManageTiles();
25 } 31 }
26 32
27 void TileManager::ManageTiles() { 33 void TileManager::RegisterTile(Tile* tile) {
28 // Figure out how much memory we would be willing to give out. 34 tiles_.push_back(tile);
29
30 // Free up memory.
31
32 // GC old versions.
33 }
34
35 void TileManager::DidCreateTileVersion(TileVersion* version) {
36 tile_versions_.push_back(version);
37 ScheduleManageTiles(); 35 ScheduleManageTiles();
38 } 36 }
39 37
40 void TileManager::DidDeleteTileVersion(TileVersion* version) { 38 void TileManager::UnregisterTile(Tile* tile) {
41 for (size_t i = 0; i < tile_versions_.size(); i++) { 39 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); it++) {
42 if (tile_versions_[i] == version) { 40 if (*it == tile) {
43 tile_versions_.erase(tile_versions_.begin() + i); 41 tiles_.erase(it);
44 return; 42 return;
45 } 43 }
46 } 44 }
47 DCHECK(false) << "Could not find tile version."; 45 DCHECK(false) << "Could not find tile version.";
48 } 46 }
49 47
50 void TileManager::WillModifyTileVersionPriority(TileVersion*, const TilePriority & new_priority) { 48 void TileManager::WillModifyTilePriority(Tile*, WhichTree tree, const TilePriori ty& new_priority) {
51 // TODO(nduca): Do something smarter if reprioritization turns out to be 49 // TODO(nduca): Do something smarter if reprioritization turns out to be
52 // costly. 50 // costly.
53 ScheduleManageTiles(); 51 ScheduleManageTiles();
54 } 52 }
55 53
56 void TileManager::ScheduleManageTiles() { 54 void TileManager::ScheduleManageTiles() {
57 if (manage_tiles_pending_) 55 if (manage_tiles_pending_)
58 return; 56 return;
59 ScheduleManageTiles(); 57 ScheduleManageTiles();
60 manage_tiles_pending_ = true; 58 manage_tiles_pending_ = true;
61 } 59 }
62 60
61 class BinComparator {
62 public:
63 bool operator() (const Tile* a, const Tile* b) const {
64 const ManagedTileState& ams = a->managed_state();
65 const ManagedTileState& bms = b->managed_state();
66 if (ams.bin != bms.bin)
67 return ams.bin < bms.bin;
68
69 if (ams.resolution != bms.resolution)
70 return ams.resolution < ams.resolution;
71
72 return
73 ams.time_to_needed_in_seconds <
74 bms.time_to_needed_in_seconds;
75 }
76 };
77
78 void TileManager::ManageTiles() {
79 // The amount of time for which we want to have prepainting coverage.
80 const double prepainting_window_time_seconds = 1.0;
81 const double backfling_guard_distance_pixels = 314.0;
82
83 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority ;
84
85 // Bin into three categories of tiles: things we need now, things we need soon , and eventually
86 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
87 Tile* tile = *it;
88 ManagedTileState& mts = tile->managed_state();
89 TilePriority prio;
90 if (smoothness_takes_priority)
91 prio = tile->priority(ACTIVE_TREE);
92 else
93 prio = tile->combined_priority();
94
95 mts.resolution = prio.resolution;
96 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds();
97
98 if (mts.time_to_needed_in_seconds ==
99 std::numeric_limits<float>::max()) {
100 mts.bin = NEVER_BIN;
101 continue;
102 }
103
104 if (mts.resolution == NON_IDEAL_RESOLUTION) {
105 mts.bin = EVENTUALLY_BIN;
106 continue;
107 }
108
109 if (mts.time_to_needed_in_seconds == 0 ||
110 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) {
111 mts.bin = NOW_BIN;
112 continue;
113 }
114
115 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) {
116 mts.bin = SOON_BIN;
117 continue;
118 }
119
120 mts.bin = EVENTUALLY_BIN;
121 }
122
123 // Memory limit policy works by mapping some bin states to the NEVER bin.
124 TileManagerBin bin_map[NUM_BINS];
125 if (global_state_.memory_limit_policy == ALLOW_NOTHING) {
126 bin_map[NOW_BIN] = NEVER_BIN;
127 bin_map[SOON_BIN] = NEVER_BIN;
128 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
129 bin_map[NEVER_BIN] = NEVER_BIN;
130 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) {
131 bin_map[NOW_BIN] = NOW_BIN;
132 bin_map[SOON_BIN] = NEVER_BIN;
133 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
134 bin_map[NEVER_BIN] = NEVER_BIN;
135 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) {
136 bin_map[NOW_BIN] = NOW_BIN;
137 bin_map[SOON_BIN] = SOON_BIN;
138 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
139 bin_map[NEVER_BIN] = NEVER_BIN;
140 } else {
141 bin_map[NOW_BIN] = NOW_BIN;
142 bin_map[SOON_BIN] = SOON_BIN;
143 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
144 bin_map[NEVER_BIN] = NEVER_BIN;
145 }
146 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
147 Tile* tile = *it;
148 TileManagerBin bin = bin_map[tile->managed_state().bin];
149 tile->managed_state().bin = bin;
150 }
151
152 // Sort by bin.
153 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
154
155 // Some memory cannot be released. Figure out which.
156 size_t unreleasable_bytes = 0;
157 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
158 Tile* tile = *it;
159 if (tile->managed_state().resource_id_can_be_freed)
160 unreleasable_bytes += tile->bytes_consumed_if_allocated();
161 }
162
163 // Now give memory out to the tiles until we're out, and build
164 // the needs-to-be-painted and needs-to-be-freed queues.
165 tiles_that_need_to_be_painted_.erase(
166 tiles_that_need_to_be_painted_.begin(),
167 tiles_that_need_to_be_painted_.end());
168
169 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes;
170 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
171 Tile* tile = *it;
172 size_t tile_bytes = tile->bytes_consumed_if_allocated();
173 ManagedTileState& managed_tile_state = tile->managed_state();
174 if (managed_tile_state.resource_id_can_be_freed)
175 continue;
176 if (tile_bytes > bytes_left) {
177 managed_tile_state.can_use_gpu_memory = false;
178 if (managed_tile_state.resource_id && managed_tile_state.resource_id_can_b e_freed)
179 FreeResourcesForTile(tile);
180 continue;
181 }
182 bytes_left -= tile_bytes;
183 managed_tile_state.can_use_gpu_memory = true;
184 if (!managed_tile_state.resource_id)
185 tiles_that_need_to_be_painted_.push_back(tile);
186 }
187
188 // Reverse two tiles_that_need_* vectors such that pop_back gets
189 // the highest priority tile.
190 std::reverse(
191 tiles_that_need_to_be_painted_.begin(),
192 tiles_that_need_to_be_painted_.end());
193
194 // Finally, kick the rasterizer.
195 ScheduleMorePaintingJobs();
63 } 196 }
197
198 void TileManager::FreeResourcesForTile(Tile* tile) {
199 DCHECK(!tile->managed_state().can_use_gpu_memory &&
200 tile->managed_state().resource_id_can_be_freed);
201 // TODO(nduca): Do something intelligent here.
202 }
203
204 void TileManager::ScheduleMorePaintingJobs() {
205 // TODO(nduca): The next big thing.
206 }
207
208
209 }
OLDNEW
« no previous file with comments | « cc/tile_manager.h ('k') | cc/tile_priority.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698