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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 TileManager::~TileManager() { | 136 TileManager::~TileManager() { |
137 // Reset global state and manage. This should cause | 137 // Reset global state and manage. This should cause |
138 // our memory usage to drop to zero. | 138 // our memory usage to drop to zero. |
139 global_state_ = GlobalStateThatImpactsTilePriority(); | 139 global_state_ = GlobalStateThatImpactsTilePriority(); |
140 AssignGpuMemoryToTiles(); | 140 AssignGpuMemoryToTiles(); |
141 // This should finish all pending tasks and release any uninitialized | 141 // This should finish all pending tasks and release any uninitialized |
142 // resources. | 142 // resources. |
143 raster_worker_pool_.reset(); | 143 raster_worker_pool_.reset(); |
144 CheckForCompletedTileUploads(); | 144 CheckForCompletedTileUploads(); |
145 DCHECK(tiles_with_pending_set_pixels_.size() == 0); | 145 DCHECK(tiles_with_pending_set_pixels_.size() == 0); |
146 DCHECK(tiles_.size() == 0); | 146 DCHECK(all_tiles_.size() == 0); |
147 DCHECK(live_tiles_.size() == 0); | |
reveman
2013/02/05 19:31:09
do you mind changing all these checks to DCHECK_EQ
| |
147 } | 148 } |
148 | 149 |
149 void TileManager::SetGlobalState( | 150 void TileManager::SetGlobalState( |
150 const GlobalStateThatImpactsTilePriority& global_state) { | 151 const GlobalStateThatImpactsTilePriority& global_state) { |
151 global_state_ = global_state; | 152 global_state_ = global_state; |
152 resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); | 153 resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); |
153 ScheduleManageTiles(); | 154 ScheduleManageTiles(); |
154 } | 155 } |
155 | 156 |
156 void TileManager::RegisterTile(Tile* tile) { | 157 void TileManager::RegisterTile(Tile* tile) { |
157 tiles_.push_back(tile); | 158 all_tiles_.push_back(tile); |
158 | 159 |
159 const ManagedTileState& mts = tile->managed_state(); | 160 const ManagedTileState& mts = tile->managed_state(); |
160 for (int i = 0; i < NUM_TREES; ++i) | 161 for (int i = 0; i < NUM_TREES; ++i) |
161 ++raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; | 162 ++raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; |
162 | 163 |
163 ScheduleManageTiles(); | 164 ScheduleManageTiles(); |
164 } | 165 } |
165 | 166 |
166 void TileManager::UnregisterTile(Tile* tile) { | 167 void TileManager::UnregisterTile(Tile* tile) { |
167 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 168 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
168 it != tiles_with_image_decoding_tasks_.end(); it++) { | 169 it != tiles_with_image_decoding_tasks_.end(); it++) { |
169 if (*it == tile) { | 170 if (*it == tile) { |
170 tiles_with_image_decoding_tasks_.erase(it); | 171 tiles_with_image_decoding_tasks_.erase(it); |
171 break; | 172 break; |
172 } | 173 } |
173 } | 174 } |
174 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 175 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
175 it != tiles_that_need_to_be_rasterized_.end(); it++) { | 176 it != tiles_that_need_to_be_rasterized_.end(); it++) { |
176 if (*it == tile) { | 177 if (*it == tile) { |
177 tiles_that_need_to_be_rasterized_.erase(it); | 178 tiles_that_need_to_be_rasterized_.erase(it); |
178 break; | 179 break; |
179 } | 180 } |
180 } | 181 } |
181 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); it++) { | 182 for (TileVector::iterator it = live_tiles_.begin(); |
183 it != live_tiles_.end(); it++) { | |
184 if (*it == tile) { | |
185 live_tiles_.erase(it); | |
186 break; | |
187 } | |
188 } | |
189 for (TileVector::iterator it = all_tiles_.begin(); | |
190 it != all_tiles_.end(); it++) { | |
182 if (*it == tile) { | 191 if (*it == tile) { |
183 const ManagedTileState& mts = tile->managed_state(); | 192 const ManagedTileState& mts = tile->managed_state(); |
184 for (int i = 0; i < NUM_TREES; ++i) | 193 for (int i = 0; i < NUM_TREES; ++i) |
185 --raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; | 194 --raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; |
186 FreeResourcesForTile(tile); | 195 FreeResourcesForTile(tile); |
187 tiles_.erase(it); | 196 all_tiles_.erase(it); |
188 return; | 197 return; |
189 } | 198 } |
190 } | 199 } |
191 DCHECK(false) << "Could not find tile version."; | 200 DCHECK(false) << "Could not find tile version."; |
192 } | 201 } |
193 | 202 |
194 class BinComparator { | 203 class BinComparator { |
195 public: | 204 public: |
196 bool operator() (const Tile* a, const Tile* b) const { | 205 bool operator() (const Tile* a, const Tile* b) const { |
197 const ManagedTileState& ams = a->managed_state(); | 206 const ManagedTileState& ams = a->managed_state(); |
(...skipping 15 matching lines...) Expand all Loading... | |
213 if (a_rect.y() != b_rect.y()) | 222 if (a_rect.y() != b_rect.y()) |
214 return a_rect.y() < b_rect.y(); | 223 return a_rect.y() < b_rect.y(); |
215 return a_rect.x() < b_rect.x(); | 224 return a_rect.x() < b_rect.x(); |
216 } | 225 } |
217 }; | 226 }; |
218 | 227 |
219 void TileManager::SortTiles() { | 228 void TileManager::SortTiles() { |
220 TRACE_EVENT0("cc", "TileManager::SortTiles"); | 229 TRACE_EVENT0("cc", "TileManager::SortTiles"); |
221 | 230 |
222 // Sort by bin, resolution and time until needed. | 231 // Sort by bin, resolution and time until needed. |
223 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 232 std::sort(live_tiles_.begin(), live_tiles_.end(), BinComparator()); |
224 } | 233 } |
225 | 234 |
226 void TileManager::ManageTiles() { | 235 void TileManager::ManageTiles() { |
227 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 236 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
228 manage_tiles_pending_ = false; | 237 manage_tiles_pending_ = false; |
229 ++manage_tiles_call_count_; | 238 ++manage_tiles_call_count_; |
230 | 239 |
231 const TreePriority tree_priority = global_state_.tree_priority; | 240 const TreePriority tree_priority = global_state_.tree_priority; |
232 TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size()); | 241 TRACE_COUNTER_ID1("cc", "AllTileCount", this, all_tiles_.size()); |
242 | |
243 live_tiles_.resize(0); | |
reveman
2013/02/05 19:31:09
nit: use live_tiles_.erase(live_tiles_.begin(), li
whunt
2013/02/05 22:00:00
I believe that resize(0) is faster but probably no
reveman
2013/02/05 22:16:41
sg, we can change all this to resize(0) later.
| |
244 for (TileVector::iterator it = all_tiles_.begin(); | |
245 it != all_tiles_.end(); ++it) { | |
246 if ((*it)->priority( ACTIVE_TREE).is_live || | |
reveman
2013/02/05 19:31:09
nit: I like when things align but not sure the cod
whunt
2013/02/05 22:00:00
If the system doesn't bounce it and you don't boun
| |
247 (*it)->priority(PENDING_TREE).is_live) | |
reveman
2013/02/05 19:31:09
should we be using (*it)->combined_priority().is_l
whunt
2013/02/05 22:00:00
To be honest, I have no idea, should we?. I'm hap
reveman
2013/02/05 22:16:41
the result is the same right now. look at "TilePri
| |
248 live_tiles_.push_back(*it); | |
249 } | |
250 | |
251 TRACE_COUNTER_ID1("cc", "LiveTileCount", this, live_tiles_.size()); | |
233 | 252 |
234 // For each tree, bin into different categories of tiles. | 253 // For each tree, bin into different categories of tiles. |
235 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 254 for (TileVector::iterator it = live_tiles_.begin(); |
255 it != live_tiles_.end(); ++it) { | |
236 Tile* tile = *it; | 256 Tile* tile = *it; |
237 ManagedTileState& mts = tile->managed_state(); | 257 ManagedTileState& mts = tile->managed_state(); |
238 | 258 |
239 TilePriority prio[NUM_BIN_PRIORITIES]; | 259 TilePriority prio[NUM_BIN_PRIORITIES]; |
240 switch (tree_priority) { | 260 switch (tree_priority) { |
241 case SAME_PRIORITY_FOR_BOTH_TREES: | 261 case SAME_PRIORITY_FOR_BOTH_TREES: |
242 prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = | 262 prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = |
243 tile->combined_priority(); | 263 tile->combined_priority(); |
244 break; | 264 break; |
245 case SMOOTHNESS_TAKES_PRIORITY: | 265 case SMOOTHNESS_TAKES_PRIORITY: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 bin_map[NOW_BIN] = NOW_BIN; | 303 bin_map[NOW_BIN] = NOW_BIN; |
284 bin_map[SOON_BIN] = SOON_BIN; | 304 bin_map[SOON_BIN] = SOON_BIN; |
285 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 305 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
286 bin_map[NEVER_BIN] = NEVER_BIN; | 306 bin_map[NEVER_BIN] = NEVER_BIN; |
287 } else { | 307 } else { |
288 bin_map[NOW_BIN] = NOW_BIN; | 308 bin_map[NOW_BIN] = NOW_BIN; |
289 bin_map[SOON_BIN] = SOON_BIN; | 309 bin_map[SOON_BIN] = SOON_BIN; |
290 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; | 310 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; |
291 bin_map[NEVER_BIN] = NEVER_BIN; | 311 bin_map[NEVER_BIN] = NEVER_BIN; |
292 } | 312 } |
293 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 313 for (TileVector::iterator it = live_tiles_.begin(); |
314 it != live_tiles_.end(); ++it) { | |
294 Tile* tile = *it; | 315 Tile* tile = *it; |
295 ManagedTileState& mts = tile->managed_state(); | 316 ManagedTileState& mts = tile->managed_state(); |
296 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) | 317 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
297 mts.bin[i] = bin_map[mts.bin[i]]; | 318 mts.bin[i] = bin_map[mts.bin[i]]; |
298 | 319 |
299 DidTileBinChange(tile, bin_map[mts.tree_bin[ACTIVE_TREE]], ACTIVE_TREE); | 320 DidTileBinChange(tile, bin_map[mts.tree_bin[ACTIVE_TREE]], ACTIVE_TREE); |
300 DidTileBinChange(tile, bin_map[mts.tree_bin[PENDING_TREE]], PENDING_TREE); | 321 DidTileBinChange(tile, bin_map[mts.tree_bin[PENDING_TREE]], PENDING_TREE); |
301 } | 322 } |
302 | 323 |
303 SortTiles(); | 324 SortTiles(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 DispatchMoreTasks(); | 361 DispatchMoreTasks(); |
341 } | 362 } |
342 | 363 |
343 void TileManager::GetMemoryStats( | 364 void TileManager::GetMemoryStats( |
344 size_t* memoryRequiredBytes, | 365 size_t* memoryRequiredBytes, |
345 size_t* memoryNiceToHaveBytes, | 366 size_t* memoryNiceToHaveBytes, |
346 size_t* memoryUsedBytes) const { | 367 size_t* memoryUsedBytes) const { |
347 *memoryRequiredBytes = 0; | 368 *memoryRequiredBytes = 0; |
348 *memoryNiceToHaveBytes = 0; | 369 *memoryNiceToHaveBytes = 0; |
349 *memoryUsedBytes = 0; | 370 *memoryUsedBytes = 0; |
350 for(size_t i = 0; i < tiles_.size(); i++) { | 371 for(size_t i = 0; i < all_tiles_.size(); i++) { |
reveman
2013/02/05 22:16:41
nit: you didn't introduce this but I'd be happy if
| |
351 const Tile* tile = tiles_[i]; | 372 const Tile* tile = all_tiles_[i]; |
352 const ManagedTileState& mts = tile->managed_state(); | 373 const ManagedTileState& mts = tile->managed_state(); |
353 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 374 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
354 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 375 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
355 *memoryRequiredBytes += tile_bytes; | 376 *memoryRequiredBytes += tile_bytes; |
356 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 377 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
357 *memoryNiceToHaveBytes += tile_bytes; | 378 *memoryNiceToHaveBytes += tile_bytes; |
358 if (mts.can_use_gpu_memory) | 379 if (mts.can_use_gpu_memory) |
359 *memoryUsedBytes += tile_bytes; | 380 *memoryUsedBytes += tile_bytes; |
360 } | 381 } |
361 } | 382 } |
362 | 383 |
363 scoped_ptr<base::Value> TileManager::AsValue() const { | 384 scoped_ptr<base::Value> TileManager::AsValue() const { |
364 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 385 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
365 state->SetInteger("tile_count", tiles_.size()); | 386 state->SetInteger("all_tile_count", all_tiles_.size()); |
387 state->SetInteger("live_tile_count", live_tiles_.size()); | |
366 | 388 |
367 state->Set("global_state", global_state_.AsValue().release()); | 389 state->Set("global_state", global_state_.AsValue().release()); |
368 | 390 |
369 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); | 391 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); |
370 return state.PassAs<base::Value>(); | 392 return state.PassAs<base::Value>(); |
371 } | 393 } |
372 | 394 |
373 scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { | 395 scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { |
374 scoped_ptr<base::DictionaryValue> requirements( | 396 scoped_ptr<base::DictionaryValue> requirements( |
375 new base::DictionaryValue()); | 397 new base::DictionaryValue()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 } | 440 } |
419 } | 441 } |
420 | 442 |
421 return false; | 443 return false; |
422 } | 444 } |
423 | 445 |
424 void TileManager::AssignGpuMemoryToTiles() { | 446 void TileManager::AssignGpuMemoryToTiles() { |
425 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 447 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
426 // Some memory cannot be released. Figure out which. | 448 // Some memory cannot be released. Figure out which. |
427 size_t unreleasable_bytes = 0; | 449 size_t unreleasable_bytes = 0; |
428 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 450 for (TileVector::iterator it = live_tiles_.begin(); |
451 it != live_tiles_.end(); ++it) { | |
429 Tile* tile = *it; | 452 Tile* tile = *it; |
430 if (!tile->managed_state().can_be_freed) | 453 if (!tile->managed_state().can_be_freed) |
431 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 454 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
432 } | 455 } |
433 | 456 |
434 // Now give memory out to the tiles until we're out, and build | 457 // Now give memory out to the tiles until we're out, and build |
435 // the needs-to-be-rasterized queue. | 458 // the needs-to-be-rasterized queue. |
436 tiles_that_need_to_be_rasterized_.erase( | 459 tiles_that_need_to_be_rasterized_.erase( |
437 tiles_that_need_to_be_rasterized_.begin(), | 460 tiles_that_need_to_be_rasterized_.begin(), |
438 tiles_that_need_to_be_rasterized_.end()); | 461 tiles_that_need_to_be_rasterized_.end()); |
439 | 462 |
440 // Reset the image decoding list so that we don't mess up with tile | 463 // Reset the image decoding list so that we don't mess up with tile |
441 // priorities. Tiles will be added to the image decoding list again | 464 // priorities. Tiles will be added to the image decoding list again |
442 // when DispatchMoreTasks() is called. | 465 // when DispatchMoreTasks() is called. |
443 tiles_with_image_decoding_tasks_.clear(); | 466 tiles_with_image_decoding_tasks_.clear(); |
444 | 467 |
445 // By clearing the tiles_that_need_to_be_rasterized_ vector and | 468 // By clearing the tiles_that_need_to_be_rasterized_ vector and |
446 // tiles_with_image_decoding_tasks_ list above we move all tiles | 469 // tiles_with_image_decoding_tasks_ list above we move all tiles |
447 // currently waiting for raster to idle state. | 470 // currently waiting for raster to idle state. |
448 // Call DidTileRasterStateChange() for each of these tiles to | 471 // Call DidTileRasterStateChange() for each of these tiles to |
449 // have this state change take effect. | 472 // have this state change take effect. |
450 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 473 for (TileVector::iterator it = live_tiles_.begin(); |
474 it != live_tiles_.end(); ++it) { | |
451 Tile* tile = *it; | 475 Tile* tile = *it; |
452 if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) | 476 if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) |
453 DidTileRasterStateChange(tile, IDLE_STATE); | 477 DidTileRasterStateChange(tile, IDLE_STATE); |
454 } | 478 } |
455 | 479 |
456 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_ bytes; | 480 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_ bytes; |
457 size_t bytes_that_exceeded_memory_budget = 0; | 481 size_t bytes_that_exceeded_memory_budget = 0; |
458 size_t bytes_left = bytes_allocatable; | 482 size_t bytes_left = bytes_allocatable; |
459 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 483 for (TileVector::iterator it = live_tiles_.begin(); |
484 it != live_tiles_.end(); ++it) { | |
460 Tile* tile = *it; | 485 Tile* tile = *it; |
461 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 486 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
462 ManagedTileState& managed_tile_state = tile->managed_state(); | 487 ManagedTileState& managed_tile_state = tile->managed_state(); |
463 if (!managed_tile_state.can_be_freed) | 488 if (!managed_tile_state.can_be_freed) |
464 continue; | 489 continue; |
465 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && | 490 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && |
466 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { | 491 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { |
467 managed_tile_state.can_use_gpu_memory = false; | 492 managed_tile_state.can_use_gpu_memory = false; |
468 FreeResourcesForTile(tile); | 493 FreeResourcesForTile(tile); |
469 continue; | 494 continue; |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
791 decode_begin_time = base::TimeTicks::Now(); | 816 decode_begin_time = base::TimeTicks::Now(); |
792 pixel_ref->Decode(); | 817 pixel_ref->Decode(); |
793 if (stats) { | 818 if (stats) { |
794 stats->totalDeferredImageDecodeCount++; | 819 stats->totalDeferredImageDecodeCount++; |
795 stats->totalDeferredImageDecodeTime += | 820 stats->totalDeferredImageDecodeTime += |
796 base::TimeTicks::Now() - decode_begin_time; | 821 base::TimeTicks::Now() - decode_begin_time; |
797 } | 822 } |
798 } | 823 } |
799 | 824 |
800 } // namespace cc | 825 } // namespace cc |
OLD | NEW |