Chromium Code Reviews| 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/resources/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 | 188 |
| 189 private: | 189 private: |
| 190 skia::RefPtr<SkPixelRef> pixel_ref_; | 190 skia::RefPtr<SkPixelRef> pixel_ref_; |
| 191 int layer_id_; | 191 int layer_id_; |
| 192 RenderingStatsInstrumentation* rendering_stats_; | 192 RenderingStatsInstrumentation* rendering_stats_; |
| 193 const base::Callback<void(bool was_canceled)> reply_; | 193 const base::Callback<void(bool was_canceled)> reply_; |
| 194 | 194 |
| 195 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 195 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 const char* TaskSetName(TaskSet task_set) { | |
| 199 switch (task_set) { | |
| 200 case TileManager::ALL: | |
| 201 return "ALL"; | |
| 202 case TileManager::REQUIRED_FOR_ACTIVATION: | |
| 203 return "REQUIRED_FOR_ACTIVATION"; | |
| 204 case TileManager::REQUIRED_FOR_DRAW: | |
| 205 return "REQUIRED_FOR_DRAW"; | |
| 206 default: | |
|
danakj
2014/11/04 22:06:13
same here, no default please, move it below the sw
ernstm
2014/11/04 22:41:14
Done.
| |
| 207 NOTREACHED(); | |
| 208 return "Invalid TaskSet"; | |
| 209 } | |
| 210 } | |
| 211 | |
| 198 } // namespace | 212 } // namespace |
| 199 | 213 |
| 200 RasterTaskCompletionStats::RasterTaskCompletionStats() | 214 RasterTaskCompletionStats::RasterTaskCompletionStats() |
| 201 : completed_count(0u), canceled_count(0u) {} | 215 : completed_count(0u), canceled_count(0u) {} |
| 202 | 216 |
| 203 scoped_refptr<base::debug::ConvertableToTraceFormat> | 217 scoped_refptr<base::debug::ConvertableToTraceFormat> |
| 204 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { | 218 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { |
| 205 scoped_refptr<base::debug::TracedValue> state = | 219 scoped_refptr<base::debug::TracedValue> state = |
| 206 new base::debug::TracedValue(); | 220 new base::debug::TracedValue(); |
| 207 state->SetInteger("completed_count", stats.completed_count); | 221 state->SetInteger("completed_count", stats.completed_count); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 238 rasterizer_(rasterizer), | 252 rasterizer_(rasterizer), |
| 239 scheduled_raster_task_limit_(scheduled_raster_task_limit), | 253 scheduled_raster_task_limit_(scheduled_raster_task_limit), |
| 240 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), | 254 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), |
| 241 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 255 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 242 did_initialize_visible_tile_(false), | 256 did_initialize_visible_tile_(false), |
| 243 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 257 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 244 did_oom_on_last_assign_(false), | 258 did_oom_on_last_assign_(false), |
| 245 ready_to_activate_check_notifier_( | 259 ready_to_activate_check_notifier_( |
| 246 task_runner_.get(), | 260 task_runner_.get(), |
| 247 base::Bind(&TileManager::CheckIfReadyToActivate, | 261 base::Bind(&TileManager::CheckIfReadyToActivate, |
| 248 base::Unretained(this))) { | 262 base::Unretained(this))), |
| 263 ready_to_draw_check_notifier_(task_runner_.get(), | |
| 264 base::Bind(&TileManager::CheckIfReadyToDraw, | |
| 265 base::Unretained(this))) { | |
| 249 rasterizer_->SetClient(this); | 266 rasterizer_->SetClient(this); |
| 250 } | 267 } |
| 251 | 268 |
| 252 TileManager::~TileManager() { | 269 TileManager::~TileManager() { |
| 253 // Reset global state and manage. This should cause | 270 // Reset global state and manage. This should cause |
| 254 // our memory usage to drop to zero. | 271 // our memory usage to drop to zero. |
| 255 global_state_ = GlobalStateThatImpactsTilePriority(); | 272 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 256 | 273 |
| 257 RasterTaskQueue empty; | 274 RasterTaskQueue empty; |
| 258 rasterizer_->ScheduleTasks(&empty); | 275 rasterizer_->ScheduleTasks(&empty); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 used_layer_counts_.erase(layer_it); | 325 used_layer_counts_.erase(layer_it); |
| 309 image_decode_tasks_.erase(tile->layer_id()); | 326 image_decode_tasks_.erase(tile->layer_id()); |
| 310 } | 327 } |
| 311 | 328 |
| 312 delete tile; | 329 delete tile; |
| 313 it = released_tiles_.erase(it); | 330 it = released_tiles_.erase(it); |
| 314 } | 331 } |
| 315 } | 332 } |
| 316 | 333 |
| 317 void TileManager::DidFinishRunningTasks(TaskSet task_set) { | 334 void TileManager::DidFinishRunningTasks(TaskSet task_set) { |
| 318 if (task_set == ALL) { | 335 TRACE_EVENT1("cc", |
| 319 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL"); | 336 "TileManager::DidFinishRunningTasks", |
| 337 "task_set", | |
| 338 TaskSetName(task_set)); | |
| 320 | 339 |
| 321 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > | 340 switch (task_set) { |
| 322 global_state_.soft_memory_limit_in_bytes; | 341 case ALL: { |
| 342 bool memory_usage_above_limit = | |
| 343 resource_pool_->total_memory_usage_bytes() > | |
| 344 global_state_.soft_memory_limit_in_bytes; | |
| 323 | 345 |
| 324 // When OOM, keep re-assigning memory until we reach a steady state | 346 // When OOM, keep re-assigning memory until we reach a steady state |
| 325 // where top-priority tiles are initialized. | 347 // where top-priority tiles are initialized. |
| 326 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 348 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
| 327 !memory_usage_above_limit) | 349 !memory_usage_above_limit) |
| 328 return; | 350 return; |
| 329 | 351 |
| 330 rasterizer_->CheckForCompletedTasks(); | 352 rasterizer_->CheckForCompletedTasks(); |
| 331 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 353 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 332 | 354 |
| 333 TileVector tiles_that_need_to_be_rasterized; | 355 TileVector tiles_that_need_to_be_rasterized; |
| 334 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | 356 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); |
| 335 | 357 |
| 336 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 358 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 337 // steady memory state. Keep scheduling tasks until we reach this state. | 359 // steady memory state. Keep scheduling tasks until we reach this state. |
| 338 if (!tiles_that_need_to_be_rasterized.empty()) { | 360 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 339 ScheduleTasks(tiles_that_need_to_be_rasterized); | 361 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 362 return; | |
| 363 } | |
| 364 | |
| 365 FreeResourcesForReleasedTiles(); | |
| 366 | |
| 367 resource_pool_->ReduceResourceUsage(); | |
| 368 | |
| 369 // We don't reserve memory for required-for-activation tiles during | |
| 370 // accelerated gestures, so we just postpone activation when we don't | |
| 371 // have these tiles, and activate after the accelerated gesture. | |
| 372 // Likewise if we don't allow any tiles (as is the case when we're | |
| 373 // invisible), if we have tiles that aren't ready, then we shouldn't | |
| 374 // activate as activation can cause checkerboards. | |
| 375 bool allow_rasterize_on_demand = | |
| 376 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | |
| 377 global_state_.memory_limit_policy != ALLOW_NOTHING; | |
| 378 | |
| 379 // Use on-demand raster for any required-for-activation tiles that have | |
| 380 // not | |
| 381 // been been assigned memory after reaching a steady memory state. This | |
| 382 // ensures that we activate even when OOM. Note that we have to rebuilt | |
| 383 // the | |
| 384 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | |
| 385 // would otherwise not be picked up by the old raster queue. | |
| 386 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 387 global_state_.tree_priority); | |
| 388 bool ready_to_activate = true; | |
| 389 while (!raster_priority_queue_.IsEmpty()) { | |
| 390 Tile* tile = raster_priority_queue_.Top(); | |
| 391 ManagedTileState& mts = tile->managed_state(); | |
| 392 | |
| 393 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { | |
| 394 // If we can't raster on demand, give up early (and don't activate). | |
| 395 if (!allow_rasterize_on_demand) { | |
| 396 ready_to_activate = false; | |
| 397 break; | |
| 398 } | |
| 399 | |
| 400 mts.draw_info.set_rasterize_on_demand(); | |
| 401 client_->NotifyTileStateChanged(tile); | |
| 402 } | |
| 403 raster_priority_queue_.Pop(); | |
| 404 } | |
| 405 | |
| 406 if (ready_to_activate) { | |
| 407 DCHECK(IsReadyToActivate()); | |
| 408 ready_to_activate_check_notifier_.Schedule(); | |
| 409 } | |
| 410 raster_priority_queue_.Reset(); | |
| 340 return; | 411 return; |
| 341 } | 412 } |
| 342 | 413 case REQUIRED_FOR_ACTIVATION: |
| 343 FreeResourcesForReleasedTiles(); | |
| 344 | |
| 345 resource_pool_->ReduceResourceUsage(); | |
| 346 | |
| 347 // We don't reserve memory for required-for-activation tiles during | |
| 348 // accelerated gestures, so we just postpone activation when we don't | |
| 349 // have these tiles, and activate after the accelerated gesture. | |
| 350 // Likewise if we don't allow any tiles (as is the case when we're | |
| 351 // invisible), if we have tiles that aren't ready, then we shouldn't | |
| 352 // activate as activation can cause checkerboards. | |
| 353 bool allow_rasterize_on_demand = | |
| 354 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | |
| 355 global_state_.memory_limit_policy != ALLOW_NOTHING; | |
| 356 | |
| 357 // Use on-demand raster for any required-for-activation tiles that have not | |
| 358 // been been assigned memory after reaching a steady memory state. This | |
| 359 // ensures that we activate even when OOM. Note that we have to rebuilt the | |
| 360 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | |
| 361 // would otherwise not be picked up by the old raster queue. | |
| 362 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 363 global_state_.tree_priority); | |
| 364 bool ready_to_activate = true; | |
| 365 while (!raster_priority_queue_.IsEmpty()) { | |
| 366 Tile* tile = raster_priority_queue_.Top(); | |
| 367 ManagedTileState& mts = tile->managed_state(); | |
| 368 | |
| 369 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { | |
| 370 // If we can't raster on demand, give up early (and don't activate). | |
| 371 if (!allow_rasterize_on_demand) { | |
| 372 ready_to_activate = false; | |
| 373 break; | |
| 374 } | |
| 375 | |
| 376 mts.draw_info.set_rasterize_on_demand(); | |
| 377 client_->NotifyTileStateChanged(tile); | |
| 378 } | |
| 379 raster_priority_queue_.Pop(); | |
| 380 } | |
| 381 | |
| 382 if (ready_to_activate) { | |
| 383 DCHECK(IsReadyToActivate()); | |
| 384 ready_to_activate_check_notifier_.Schedule(); | 414 ready_to_activate_check_notifier_.Schedule(); |
| 385 } | 415 return; |
| 386 raster_priority_queue_.Reset(); | 416 case REQUIRED_FOR_DRAW: |
| 387 return; | 417 ready_to_draw_check_notifier_.Schedule(); |
| 388 } | 418 return; |
| 389 | 419 default: |
|
danakj
2014/11/04 22:02:59
don't use default unless you have to, it avoids co
ernstm
2014/11/04 22:41:14
Done.
| |
| 390 if (task_set == REQUIRED_FOR_ACTIVATION) { | 420 NOTREACHED(); |
| 391 TRACE_EVENT1("cc", | |
| 392 "TileManager::DidFinishRunningTasks", | |
| 393 "task_set", | |
| 394 "REQUIRED_FOR_ACTIVATION"); | |
| 395 ready_to_activate_check_notifier_.Schedule(); | |
| 396 } | 421 } |
| 397 } | 422 } |
| 398 | 423 |
| 399 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { | 424 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { |
| 400 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 425 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 401 | 426 |
| 402 global_state_ = state; | 427 global_state_ = state; |
| 403 | 428 |
| 404 // We need to call CheckForCompletedTasks() once in-between each call | 429 // We need to call CheckForCompletedTasks() once in-between each call |
| 405 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 430 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 | 708 |
| 684 DCHECK(mts.draw_info.requires_resource()); | 709 DCHECK(mts.draw_info.requires_resource()); |
| 685 DCHECK(!mts.draw_info.resource_); | 710 DCHECK(!mts.draw_info.resource_); |
| 686 | 711 |
| 687 if (!mts.raster_task.get()) | 712 if (!mts.raster_task.get()) |
| 688 mts.raster_task = CreateRasterTask(tile); | 713 mts.raster_task = CreateRasterTask(tile); |
| 689 | 714 |
| 690 TaskSetCollection task_sets; | 715 TaskSetCollection task_sets; |
| 691 if (tile->required_for_activation()) | 716 if (tile->required_for_activation()) |
| 692 task_sets.set(REQUIRED_FOR_ACTIVATION); | 717 task_sets.set(REQUIRED_FOR_ACTIVATION); |
| 718 if (tile->required_for_draw()) | |
| 719 task_sets.set(REQUIRED_FOR_DRAW); | |
| 693 task_sets.set(ALL); | 720 task_sets.set(ALL); |
| 694 raster_queue_.items.push_back( | 721 raster_queue_.items.push_back( |
| 695 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); | 722 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); |
| 696 } | 723 } |
| 697 | 724 |
| 698 // We must reduce the amount of unused resoruces before calling | 725 // We must reduce the amount of unused resoruces before calling |
| 699 // ScheduleTasks to prevent usage from rising above limits. | 726 // ScheduleTasks to prevent usage from rising above limits. |
| 700 resource_pool_->ReduceResourceUsage(); | 727 resource_pool_->ReduceResourceUsage(); |
| 701 | 728 |
| 702 // Schedule running of |raster_queue_|. This replaces any previously | 729 // Schedule running of |raster_queue_|. This replaces any previously |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 851 } | 878 } |
| 852 | 879 |
| 853 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { | 880 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { |
| 854 rasterizer_ = rasterizer; | 881 rasterizer_ = rasterizer; |
| 855 rasterizer_->SetClient(this); | 882 rasterizer_->SetClient(this); |
| 856 } | 883 } |
| 857 | 884 |
| 858 bool TileManager::IsReadyToActivate() const { | 885 bool TileManager::IsReadyToActivate() const { |
| 859 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); | 886 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
| 860 | 887 |
| 861 for (std::vector<PictureLayerImpl*>::const_iterator it = layers.begin(); | 888 for (const auto& layer : layers) { |
| 862 it != layers.end(); | 889 if (!layer->AllTilesRequiredForActivationAreReadyToDraw()) |
| 863 ++it) { | |
| 864 if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw()) | |
| 865 return false; | 890 return false; |
| 866 } | 891 } |
| 867 | 892 |
| 893 return true; | |
| 894 } | |
| 895 | |
| 896 bool TileManager::IsReadyToDraw() const { | |
| 897 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); | |
| 898 | |
| 899 for (const auto& layer : layers) { | |
| 900 if (!layer->AllTilesRequiredForDrawAreReadyToDraw()) | |
| 901 return false; | |
| 902 } | |
| 903 | |
| 868 return true; | 904 return true; |
| 869 } | 905 } |
| 870 | 906 |
| 871 void TileManager::CheckIfReadyToActivate() { | 907 void TileManager::CheckIfReadyToActivate() { |
| 872 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | 908 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
| 873 | 909 |
| 874 rasterizer_->CheckForCompletedTasks(); | 910 rasterizer_->CheckForCompletedTasks(); |
| 875 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 911 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 876 | 912 |
| 877 if (IsReadyToActivate()) | 913 if (IsReadyToActivate()) |
| 878 client_->NotifyReadyToActivate(); | 914 client_->NotifyReadyToActivate(); |
| 879 } | 915 } |
| 880 | 916 |
| 917 void TileManager::CheckIfReadyToDraw() { | |
| 918 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToDraw"); | |
| 919 | |
| 920 rasterizer_->CheckForCompletedTasks(); | |
| 921 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | |
| 922 | |
| 923 if (IsReadyToDraw()) | |
| 924 client_->NotifyReadyToDraw(); | |
| 925 } | |
| 926 | |
| 881 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 927 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
| 882 } | 928 } |
| 883 | 929 |
| 884 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 930 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) |
| 885 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | 931 : memory_bytes_(memory_bytes), resource_count_(resource_count) { |
| 886 } | 932 } |
| 887 | 933 |
| 888 // static | 934 // static |
| 889 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( | 935 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( |
| 890 const gfx::Size& size, | 936 const gfx::Size& size, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 result -= other; | 968 result -= other; |
| 923 return result; | 969 return result; |
| 924 } | 970 } |
| 925 | 971 |
| 926 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 972 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
| 927 return memory_bytes_ > limit.memory_bytes_ || | 973 return memory_bytes_ > limit.memory_bytes_ || |
| 928 resource_count_ > limit.resource_count_; | 974 resource_count_ > limit.resource_count_; |
| 929 } | 975 } |
| 930 | 976 |
| 931 } // namespace cc | 977 } // namespace cc |
| OLD | NEW |