OLD | NEW |
---|---|
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> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 | 42 |
43 // The amount of time for which we want to have prepainting coverage. | 43 // The amount of time for which we want to have prepainting coverage. |
44 const double prepainting_window_time_seconds = 1.0; | 44 const double prepainting_window_time_seconds = 1.0; |
45 const double backfling_guard_distance_pixels = 314.0; | 45 const double backfling_guard_distance_pixels = 314.0; |
46 | 46 |
47 // Explicitly limit how far ahead we will prepaint to limit memory usage. | 47 // Explicitly limit how far ahead we will prepaint to limit memory usage. |
48 if (prio.distance_to_visible_in_pixels > | 48 if (prio.distance_to_visible_in_pixels > |
49 TilePriority::kMaxDistanceInContentSpace) | 49 TilePriority::kMaxDistanceInContentSpace) |
50 return NEVER_BIN; | 50 return NEVER_BIN; |
51 | 51 |
52 if (prio.time_to_visible_in_seconds == std::numeric_limits<float>::max()) | 52 if (prio.time_to_visible_in_seconds >= std::numeric_limits<float>::max()) |
reveman
2013/02/11 22:42:28
why did you change this?
whunt
2013/02/11 22:58:41
The code that calculates distance actually returns
reveman
2013/02/11 23:53:57
Ok, nice catch. I'm seeing use of both max() and i
| |
53 return NEVER_BIN; | 53 return NEVER_BIN; |
54 | 54 |
55 if (prio.time_to_visible_in_seconds == 0 || | 55 if (prio.time_to_visible_in_seconds == 0 || |
56 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) | 56 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) |
57 return NOW_BIN; | 57 return NOW_BIN; |
58 | 58 |
59 if (prio.resolution == NON_IDEAL_RESOLUTION) | 59 if (prio.resolution == NON_IDEAL_RESOLUTION) |
60 return EVENTUALLY_BIN; | 60 return EVENTUALLY_BIN; |
61 | 61 |
62 if (prio.time_to_visible_in_seconds < prepainting_window_time_seconds) | 62 if (prio.time_to_visible_in_seconds < prepainting_window_time_seconds) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 | 137 |
138 TileManager::~TileManager() { | 138 TileManager::~TileManager() { |
139 // Reset global state and manage. This should cause | 139 // Reset global state and manage. This should cause |
140 // our memory usage to drop to zero. | 140 // our memory usage to drop to zero. |
141 global_state_ = GlobalStateThatImpactsTilePriority(); | 141 global_state_ = GlobalStateThatImpactsTilePriority(); |
142 AssignGpuMemoryToTiles(); | 142 AssignGpuMemoryToTiles(); |
143 // This should finish all pending tasks and release any uninitialized | 143 // This should finish all pending tasks and release any uninitialized |
144 // resources. | 144 // resources. |
145 raster_worker_pool_.reset(); | 145 raster_worker_pool_.reset(); |
146 CheckForCompletedTileUploads(); | 146 CheckForCompletedTileUploads(); |
147 DCHECK(tiles_with_pending_set_pixels_.size() == 0); | 147 DCHECK_EQ(tiles_with_pending_set_pixels_.size(), 0); |
148 DCHECK(tiles_.size() == 0); | 148 DCHECK_EQ(all_tiles_.size(), 0); |
149 DCHECK_EQ(live_or_allocated_tiles_.size(), 0); | |
149 } | 150 } |
150 | 151 |
151 void TileManager::SetGlobalState( | 152 void TileManager::SetGlobalState( |
152 const GlobalStateThatImpactsTilePriority& global_state) { | 153 const GlobalStateThatImpactsTilePriority& global_state) { |
153 global_state_ = global_state; | 154 global_state_ = global_state; |
154 resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); | 155 resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); |
155 ScheduleManageTiles(); | 156 ScheduleManageTiles(); |
156 } | 157 } |
157 | 158 |
158 void TileManager::RegisterTile(Tile* tile) { | 159 void TileManager::RegisterTile(Tile* tile) { |
159 tiles_.push_back(tile); | 160 all_tiles_.push_back(tile); |
160 | 161 |
161 const ManagedTileState& mts = tile->managed_state(); | 162 const ManagedTileState& mts = tile->managed_state(); |
162 for (int i = 0; i < NUM_TREES; ++i) | 163 for (int i = 0; i < NUM_TREES; ++i) |
163 ++raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; | 164 ++raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; |
164 | 165 |
165 ScheduleManageTiles(); | 166 ScheduleManageTiles(); |
166 } | 167 } |
167 | 168 |
168 void TileManager::UnregisterTile(Tile* tile) { | 169 void TileManager::UnregisterTile(Tile* tile) { |
169 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 170 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
170 it != tiles_with_image_decoding_tasks_.end(); it++) { | 171 it != tiles_with_image_decoding_tasks_.end(); it++) { |
171 if (*it == tile) { | 172 if (*it == tile) { |
172 tiles_with_image_decoding_tasks_.erase(it); | 173 tiles_with_image_decoding_tasks_.erase(it); |
173 break; | 174 break; |
174 } | 175 } |
175 } | 176 } |
176 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 177 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
177 it != tiles_that_need_to_be_rasterized_.end(); it++) { | 178 it != tiles_that_need_to_be_rasterized_.end(); it++) { |
178 if (*it == tile) { | 179 if (*it == tile) { |
179 tiles_that_need_to_be_rasterized_.erase(it); | 180 tiles_that_need_to_be_rasterized_.erase(it); |
180 break; | 181 break; |
181 } | 182 } |
182 } | 183 } |
183 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); it++) { | 184 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
185 it != live_or_allocated_tiles_.end(); it++) { | |
186 if (*it == tile) { | |
187 live_or_allocated_tiles_.erase(it); | |
188 break; | |
189 } | |
190 } | |
191 for (TileVector::iterator it = all_tiles_.begin(); | |
192 it != all_tiles_.end(); it++) { | |
184 if (*it == tile) { | 193 if (*it == tile) { |
185 const ManagedTileState& mts = tile->managed_state(); | 194 const ManagedTileState& mts = tile->managed_state(); |
186 for (int i = 0; i < NUM_TREES; ++i) | 195 for (int i = 0; i < NUM_TREES; ++i) |
187 --raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; | 196 --raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; |
188 FreeResourcesForTile(tile); | 197 FreeResourcesForTile(tile); |
189 tiles_.erase(it); | 198 all_tiles_.erase(it); |
190 return; | 199 return; |
191 } | 200 } |
192 } | 201 } |
193 DCHECK(false) << "Could not find tile version."; | 202 DCHECK(false) << "Could not find tile version."; |
194 } | 203 } |
195 | 204 |
196 class BinComparator { | 205 class BinComparator { |
197 public: | 206 public: |
198 bool operator() (const Tile* a, const Tile* b) const { | 207 bool operator() (const Tile* a, const Tile* b) const { |
199 const ManagedTileState& ams = a->managed_state(); | 208 const ManagedTileState& ams = a->managed_state(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 | 256 |
248 // If i does not equal j then we'll swap them. | 257 // If i does not equal j then we'll swap them. |
249 Tile* temp = *i; | 258 Tile* temp = *i; |
250 *i = *j; | 259 *i = *j; |
251 *j = temp; | 260 *j = temp; |
252 } | 261 } |
253 | 262 |
254 TRACE_COUNTER_ID1("cc", "LiveTileCount", this, i + 1 - tiles_.begin()); | 263 TRACE_COUNTER_ID1("cc", "LiveTileCount", this, i + 1 - tiles_.begin()); |
255 | 264 |
256 // Sort by bin, resolution and time until needed. | 265 // Sort by bin, resolution and time until needed. |
257 std::sort(tiles_.begin(), i + 1, BinComparator()); | 266 std::sort(live_or_allocated_tiles_.begin(), |
267 live_or_allocated_tiles_.end(), BinComparator()); | |
258 } | 268 } |
259 | 269 |
260 void TileManager::ManageTiles() { | 270 void TileManager::ManageTiles() { |
261 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 271 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
262 manage_tiles_pending_ = false; | 272 manage_tiles_pending_ = false; |
263 ++manage_tiles_call_count_; | 273 ++manage_tiles_call_count_; |
264 | 274 |
265 const TreePriority tree_priority = global_state_.tree_priority; | 275 const TreePriority tree_priority = global_state_.tree_priority; |
266 TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size()); | 276 TRACE_COUNTER_ID1("cc", "TileCount", this, all_tiles_.size()); |
267 | 277 |
278 // Memory limit policy works by mapping some bin states to the NEVER bin. | |
279 TileManagerBin bin_map[NUM_BINS]; | |
280 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { | |
281 bin_map[NOW_BIN] = NEVER_BIN; | |
282 bin_map[SOON_BIN] = NEVER_BIN; | |
283 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | |
284 bin_map[NEVER_BIN] = NEVER_BIN; | |
285 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { | |
286 bin_map[NOW_BIN] = NOW_BIN; | |
287 bin_map[SOON_BIN] = NEVER_BIN; | |
288 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | |
289 bin_map[NEVER_BIN] = NEVER_BIN; | |
290 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { | |
291 bin_map[NOW_BIN] = NOW_BIN; | |
292 bin_map[SOON_BIN] = SOON_BIN; | |
293 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | |
294 bin_map[NEVER_BIN] = NEVER_BIN; | |
295 } else { | |
296 bin_map[NOW_BIN] = NOW_BIN; | |
297 bin_map[SOON_BIN] = SOON_BIN; | |
298 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; | |
299 bin_map[NEVER_BIN] = NEVER_BIN; | |
300 } | |
301 | |
302 live_or_allocated_tiles_.clear(); | |
268 // For each tree, bin into different categories of tiles. | 303 // For each tree, bin into different categories of tiles. |
269 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 304 for (TileVector::iterator it = all_tiles_.begin(); |
305 it != all_tiles_.end(); ++it) { | |
270 Tile* tile = *it; | 306 Tile* tile = *it; |
271 ManagedTileState& mts = tile->managed_state(); | 307 ManagedTileState& mts = tile->managed_state(); |
272 | 308 |
273 TilePriority prio[NUM_BIN_PRIORITIES]; | 309 TilePriority prio[NUM_BIN_PRIORITIES]; |
274 switch (tree_priority) { | 310 switch (tree_priority) { |
275 case SAME_PRIORITY_FOR_BOTH_TREES: | 311 case SAME_PRIORITY_FOR_BOTH_TREES: |
276 prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = | 312 prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = |
277 tile->combined_priority(); | 313 tile->combined_priority(); |
278 break; | 314 break; |
279 case SMOOTHNESS_TAKES_PRIORITY: | 315 case SMOOTHNESS_TAKES_PRIORITY: |
280 prio[HIGH_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); | 316 prio[HIGH_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); |
281 prio[LOW_PRIORITY_BIN] = tile->priority(PENDING_TREE); | 317 prio[LOW_PRIORITY_BIN] = tile->priority(PENDING_TREE); |
282 break; | 318 break; |
283 case NEW_CONTENT_TAKES_PRIORITY: | 319 case NEW_CONTENT_TAKES_PRIORITY: |
284 prio[HIGH_PRIORITY_BIN] = tile->priority(PENDING_TREE); | 320 prio[HIGH_PRIORITY_BIN] = tile->priority(PENDING_TREE); |
285 prio[LOW_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); | 321 prio[LOW_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); |
286 break; | 322 break; |
287 } | 323 } |
288 | 324 |
289 mts.resolution = prio[HIGH_PRIORITY_BIN].resolution; | 325 mts.resolution = prio[HIGH_PRIORITY_BIN].resolution; |
290 mts.time_to_needed_in_seconds = | 326 mts.time_to_needed_in_seconds = |
291 prio[HIGH_PRIORITY_BIN].time_to_visible_in_seconds; | 327 prio[HIGH_PRIORITY_BIN].time_to_visible_in_seconds; |
292 mts.bin[HIGH_PRIORITY_BIN] = BinFromTilePriority(prio[HIGH_PRIORITY_BIN]); | 328 mts.bin[HIGH_PRIORITY_BIN] = BinFromTilePriority(prio[HIGH_PRIORITY_BIN]); |
293 mts.bin[LOW_PRIORITY_BIN] = BinFromTilePriority(prio[LOW_PRIORITY_BIN]); | 329 mts.bin[LOW_PRIORITY_BIN] = BinFromTilePriority(prio[LOW_PRIORITY_BIN]); |
294 mts.gpu_memmgr_stats_bin = BinFromTilePriority(tile->combined_priority()); | 330 mts.gpu_memmgr_stats_bin = BinFromTilePriority(tile->combined_priority()); |
295 | 331 |
296 DidTileBinChange(tile, | 332 DidTileTreeBinChange(tile, |
297 BinFromTilePriority(tile->priority(ACTIVE_TREE)), | 333 BinFromTilePriority(tile->priority(ACTIVE_TREE)), |
298 ACTIVE_TREE); | 334 ACTIVE_TREE); |
299 DidTileBinChange(tile, | 335 DidTileTreeBinChange(tile, |
300 BinFromTilePriority(tile->priority(PENDING_TREE)), | 336 BinFromTilePriority(tile->priority(PENDING_TREE)), |
301 PENDING_TREE); | 337 PENDING_TREE); |
302 } | |
303 | 338 |
304 // Memory limit policy works by mapping some bin states to the NEVER bin. | |
305 TileManagerBin bin_map[NUM_BINS]; | |
306 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { | |
307 bin_map[NOW_BIN] = NEVER_BIN; | |
308 bin_map[SOON_BIN] = NEVER_BIN; | |
309 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | |
310 bin_map[NEVER_BIN] = NEVER_BIN; | |
311 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { | |
312 bin_map[NOW_BIN] = NOW_BIN; | |
313 bin_map[SOON_BIN] = NEVER_BIN; | |
314 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | |
315 bin_map[NEVER_BIN] = NEVER_BIN; | |
316 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { | |
317 bin_map[NOW_BIN] = NOW_BIN; | |
318 bin_map[SOON_BIN] = SOON_BIN; | |
319 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | |
320 bin_map[NEVER_BIN] = NEVER_BIN; | |
321 } else { | |
322 bin_map[NOW_BIN] = NOW_BIN; | |
323 bin_map[SOON_BIN] = SOON_BIN; | |
324 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; | |
325 bin_map[NEVER_BIN] = NEVER_BIN; | |
326 } | |
327 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
328 Tile* tile = *it; | |
329 ManagedTileState& mts = tile->managed_state(); | |
330 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) | 339 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
331 mts.bin[i] = bin_map[mts.bin[i]]; | 340 mts.bin[i] = bin_map[mts.bin[i]]; |
332 | 341 |
333 DidTileBinChange(tile, bin_map[mts.tree_bin[ACTIVE_TREE]], ACTIVE_TREE); | 342 DidTileTreeBinChange(tile, bin_map[mts.tree_bin[ACTIVE_TREE]], |
334 DidTileBinChange(tile, bin_map[mts.tree_bin[PENDING_TREE]], PENDING_TREE); | 343 ACTIVE_TREE); |
344 DidTileTreeBinChange(tile, bin_map[mts.tree_bin[PENDING_TREE]], | |
345 PENDING_TREE); | |
346 | |
347 if (tile->priority(ACTIVE_TREE).is_live || | |
348 tile->priority(PENDING_TREE).is_live || | |
349 tile->GetResourceId() != 0) { | |
reveman
2013/02/11 22:42:28
what if the tile is being initialized? GetResource
whunt
2013/02/11 22:58:41
Then we can't free it this round, we'll have to wa
reveman
2013/02/11 23:53:57
but you're not adding it to the vector, which mean
whunt
2013/02/12 19:15:36
I added || !tile->managed_state().can_be_freed
| |
350 live_or_allocated_tiles_.push_back(tile); | |
351 } | |
335 } | 352 } |
353 TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, | |
354 live_or_allocated_tiles_.size()); | |
336 | 355 |
337 SortTiles(); | 356 SortTiles(); |
338 | 357 |
339 // Assign gpu memory and determine what tiles need to be rasterized. | 358 // Assign gpu memory and determine what tiles need to be rasterized. |
340 AssignGpuMemoryToTiles(); | 359 AssignGpuMemoryToTiles(); |
341 | 360 |
342 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", ValueToString(AsValue())); | 361 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", ValueToString(AsValue())); |
343 | 362 |
344 // Finally, kick the rasterizer. | 363 // Finally, kick the rasterizer. |
345 DispatchMoreTasks(); | 364 DispatchMoreTasks(); |
(...skipping 28 matching lines...) Expand all Loading... | |
374 DispatchMoreTasks(); | 393 DispatchMoreTasks(); |
375 } | 394 } |
376 | 395 |
377 void TileManager::GetMemoryStats( | 396 void TileManager::GetMemoryStats( |
378 size_t* memoryRequiredBytes, | 397 size_t* memoryRequiredBytes, |
379 size_t* memoryNiceToHaveBytes, | 398 size_t* memoryNiceToHaveBytes, |
380 size_t* memoryUsedBytes) const { | 399 size_t* memoryUsedBytes) const { |
381 *memoryRequiredBytes = 0; | 400 *memoryRequiredBytes = 0; |
382 *memoryNiceToHaveBytes = 0; | 401 *memoryNiceToHaveBytes = 0; |
383 *memoryUsedBytes = 0; | 402 *memoryUsedBytes = 0; |
384 for(size_t i = 0; i < tiles_.size(); i++) { | 403 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
385 const Tile* tile = tiles_[i]; | 404 const Tile* tile = live_or_allocated_tiles_[i]; |
386 const ManagedTileState& mts = tile->managed_state(); | 405 const ManagedTileState& mts = tile->managed_state(); |
387 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 406 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
388 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 407 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
389 *memoryRequiredBytes += tile_bytes; | 408 *memoryRequiredBytes += tile_bytes; |
390 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 409 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
391 *memoryNiceToHaveBytes += tile_bytes; | 410 *memoryNiceToHaveBytes += tile_bytes; |
392 if (mts.can_use_gpu_memory) | 411 if (mts.can_use_gpu_memory) |
393 *memoryUsedBytes += tile_bytes; | 412 *memoryUsedBytes += tile_bytes; |
394 } | 413 } |
395 } | 414 } |
396 | 415 |
397 scoped_ptr<base::Value> TileManager::AsValue() const { | 416 scoped_ptr<base::Value> TileManager::AsValue() const { |
398 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 417 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
399 state->SetInteger("tile_count", tiles_.size()); | 418 state->SetInteger("tile_count", all_tiles_.size()); |
400 | 419 |
401 state->Set("global_state", global_state_.AsValue().release()); | 420 state->Set("global_state", global_state_.AsValue().release()); |
402 | 421 |
403 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); | 422 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); |
404 return state.PassAs<base::Value>(); | 423 return state.PassAs<base::Value>(); |
405 } | 424 } |
406 | 425 |
407 scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { | 426 scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { |
408 scoped_ptr<base::DictionaryValue> requirements( | 427 scoped_ptr<base::DictionaryValue> requirements( |
409 new base::DictionaryValue()); | 428 new base::DictionaryValue()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 default: | 469 default: |
451 NOTREACHED(); | 470 NOTREACHED(); |
452 } | 471 } |
453 } | 472 } |
454 | 473 |
455 return false; | 474 return false; |
456 } | 475 } |
457 | 476 |
458 void TileManager::AssignGpuMemoryToTiles() { | 477 void TileManager::AssignGpuMemoryToTiles() { |
459 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 478 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
460 // Some memory cannot be released. Figure out which. | |
461 size_t unreleasable_bytes = 0; | 479 size_t unreleasable_bytes = 0; |
462 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
463 Tile* tile = *it; | |
464 if (!tile->managed_state().can_be_freed) | |
465 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | |
466 } | |
467 | 480 |
468 // Now give memory out to the tiles until we're out, and build | 481 // Now give memory out to the tiles until we're out, and build |
469 // the needs-to-be-rasterized queue. | 482 // the needs-to-be-rasterized queue. |
470 tiles_that_need_to_be_rasterized_.erase( | 483 tiles_that_need_to_be_rasterized_.clear(); |
471 tiles_that_need_to_be_rasterized_.begin(), | |
472 tiles_that_need_to_be_rasterized_.end()); | |
473 | 484 |
474 // Reset the image decoding list so that we don't mess up with tile | 485 // Reset the image decoding list so that we don't mess up with tile |
475 // priorities. Tiles will be added to the image decoding list again | 486 // priorities. Tiles will be added to the image decoding list again |
476 // when DispatchMoreTasks() is called. | 487 // when DispatchMoreTasks() is called. |
477 tiles_with_image_decoding_tasks_.clear(); | 488 tiles_with_image_decoding_tasks_.clear(); |
478 | 489 |
479 // By clearing the tiles_that_need_to_be_rasterized_ vector and | 490 // By clearing the tiles_that_need_to_be_rasterized_ vector and |
480 // tiles_with_image_decoding_tasks_ list above we move all tiles | 491 // tiles_with_image_decoding_tasks_ list above we move all tiles |
481 // currently waiting for raster to idle state. | 492 // currently waiting for raster to idle state. |
482 // Call DidTileRasterStateChange() for each of these tiles to | 493 // Call DidTileRasterStateChange() for each of these tiles to |
483 // have this state change take effect. | 494 // have this state change take effect. |
484 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 495 // Some memory cannot be released. We figure out how much in this |
496 // loop as well. | |
497 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); | |
498 it != live_or_allocated_tiles_.end(); ++it) { | |
485 Tile* tile = *it; | 499 Tile* tile = *it; |
500 if (!tile->managed_state().can_be_freed) | |
501 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | |
486 if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) | 502 if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) |
487 DidTileRasterStateChange(tile, IDLE_STATE); | 503 DidTileRasterStateChange(tile, IDLE_STATE); |
488 } | 504 } |
489 | 505 |
490 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_ bytes; | 506 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_ bytes; |
491 size_t bytes_that_exceeded_memory_budget = 0; | 507 size_t bytes_that_exceeded_memory_budget = 0; |
492 size_t bytes_left = bytes_allocatable; | 508 size_t bytes_left = bytes_allocatable; |
493 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 509 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
510 it != live_or_allocated_tiles_.end(); ++it) { | |
494 Tile* tile = *it; | 511 Tile* tile = *it; |
495 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 512 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
496 ManagedTileState& managed_tile_state = tile->managed_state(); | 513 ManagedTileState& managed_tile_state = tile->managed_state(); |
497 if (!managed_tile_state.can_be_freed) | 514 if (!managed_tile_state.can_be_freed) |
498 continue; | 515 continue; |
499 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && | 516 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && |
500 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { | 517 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { |
501 managed_tile_state.can_use_gpu_memory = false; | 518 managed_tile_state.can_use_gpu_memory = false; |
502 FreeResourcesForTile(tile); | 519 FreeResourcesForTile(tile); |
503 continue; | 520 continue; |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
791 --raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; | 808 --raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; |
792 DCHECK_GE(raster_state_count_[mts.raster_state][i][mts.tree_bin[i]], 0); | 809 DCHECK_GE(raster_state_count_[mts.raster_state][i][mts.tree_bin[i]], 0); |
793 | 810 |
794 // Increment count for new state. | 811 // Increment count for new state. |
795 ++raster_state_count_[state][i][mts.tree_bin[i]]; | 812 ++raster_state_count_[state][i][mts.tree_bin[i]]; |
796 } | 813 } |
797 | 814 |
798 mts.raster_state = state; | 815 mts.raster_state = state; |
799 } | 816 } |
800 | 817 |
801 void TileManager::DidTileBinChange(Tile* tile, | 818 void TileManager::DidTileTreeBinChange(Tile* tile, |
802 TileManagerBin bin, | 819 TileManagerBin new_tree_bin, |
803 WhichTree tree) { | 820 WhichTree tree) { |
804 ManagedTileState& mts = tile->managed_state(); | 821 ManagedTileState& mts = tile->managed_state(); |
805 | 822 |
806 // Decrement count for current bin. | 823 // Decrement count for current bin. |
807 --raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]]; | 824 --raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]]; |
808 DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); | 825 DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); |
809 | 826 |
810 // Increment count for new bin. | 827 // Increment count for new bin. |
811 ++raster_state_count_[mts.raster_state][tree][bin]; | 828 ++raster_state_count_[mts.raster_state][tree][new_tree_bin]; |
812 | 829 |
813 mts.tree_bin[tree] = bin; | 830 mts.tree_bin[tree] = new_tree_bin; |
814 } | 831 } |
815 | 832 |
816 // static | 833 // static |
817 void TileManager::PerformRaster(uint8* buffer, | 834 void TileManager::PerformRaster(uint8* buffer, |
818 const gfx::Rect& rect, | 835 const gfx::Rect& rect, |
819 float contents_scale, | 836 float contents_scale, |
820 bool use_cheapness_estimator, | 837 bool use_cheapness_estimator, |
821 PicturePileImpl* picture_pile, | 838 PicturePileImpl* picture_pile, |
822 RenderingStats* stats) { | 839 RenderingStats* stats) { |
823 TRACE_EVENT0("cc", "TileManager::PerformRaster"); | 840 TRACE_EVENT0("cc", "TileManager::PerformRaster"); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 decode_begin_time = base::TimeTicks::Now(); | 895 decode_begin_time = base::TimeTicks::Now(); |
879 pixel_ref->Decode(); | 896 pixel_ref->Decode(); |
880 if (stats) { | 897 if (stats) { |
881 stats->totalDeferredImageDecodeCount++; | 898 stats->totalDeferredImageDecodeCount++; |
882 stats->totalDeferredImageDecodeTime += | 899 stats->totalDeferredImageDecodeTime += |
883 base::TimeTicks::Now() - decode_begin_time; | 900 base::TimeTicks::Now() - decode_begin_time; |
884 } | 901 } |
885 } | 902 } |
886 | 903 |
887 } // namespace cc | 904 } // namespace cc |
OLD | NEW |