| 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 | 168 |
| 169 private: | 169 private: |
| 170 skia::RefPtr<SkPixelRef> pixel_ref_; | 170 skia::RefPtr<SkPixelRef> pixel_ref_; |
| 171 int layer_id_; | 171 int layer_id_; |
| 172 RenderingStatsInstrumentation* rendering_stats_; | 172 RenderingStatsInstrumentation* rendering_stats_; |
| 173 const base::Callback<void(bool was_canceled)> reply_; | 173 const base::Callback<void(bool was_canceled)> reply_; |
| 174 | 174 |
| 175 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 175 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
| 176 }; | 176 }; |
| 177 | 177 |
| 178 const char* TaskSetName(TaskSet task_set) { |
| 179 switch (task_set) { |
| 180 case TileManager::ALL: |
| 181 return "ALL"; |
| 182 case TileManager::REQUIRED_FOR_ACTIVATION: |
| 183 return "REQUIRED_FOR_ACTIVATION"; |
| 184 case TileManager::REQUIRED_FOR_DRAW: |
| 185 return "REQUIRED_FOR_DRAW"; |
| 186 } |
| 187 |
| 188 NOTREACHED(); |
| 189 return "Invalid TaskSet"; |
| 190 } |
| 191 |
| 178 } // namespace | 192 } // namespace |
| 179 | 193 |
| 180 RasterTaskCompletionStats::RasterTaskCompletionStats() | 194 RasterTaskCompletionStats::RasterTaskCompletionStats() |
| 181 : completed_count(0u), canceled_count(0u) {} | 195 : completed_count(0u), canceled_count(0u) {} |
| 182 | 196 |
| 183 scoped_refptr<base::debug::ConvertableToTraceFormat> | 197 scoped_refptr<base::debug::ConvertableToTraceFormat> |
| 184 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { | 198 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { |
| 185 scoped_refptr<base::debug::TracedValue> state = | 199 scoped_refptr<base::debug::TracedValue> state = |
| 186 new base::debug::TracedValue(); | 200 new base::debug::TracedValue(); |
| 187 state->SetInteger("completed_count", stats.completed_count); | 201 state->SetInteger("completed_count", stats.completed_count); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 218 rasterizer_(rasterizer), | 232 rasterizer_(rasterizer), |
| 219 scheduled_raster_task_limit_(scheduled_raster_task_limit), | 233 scheduled_raster_task_limit_(scheduled_raster_task_limit), |
| 220 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), | 234 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), |
| 221 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 235 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 222 did_initialize_visible_tile_(false), | 236 did_initialize_visible_tile_(false), |
| 223 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 237 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 224 did_oom_on_last_assign_(false), | 238 did_oom_on_last_assign_(false), |
| 225 ready_to_activate_check_notifier_( | 239 ready_to_activate_check_notifier_( |
| 226 task_runner_.get(), | 240 task_runner_.get(), |
| 227 base::Bind(&TileManager::CheckIfReadyToActivate, | 241 base::Bind(&TileManager::CheckIfReadyToActivate, |
| 228 base::Unretained(this))) { | 242 base::Unretained(this))), |
| 243 ready_to_draw_check_notifier_(task_runner_.get(), |
| 244 base::Bind(&TileManager::CheckIfReadyToDraw, |
| 245 base::Unretained(this))) { |
| 229 rasterizer_->SetClient(this); | 246 rasterizer_->SetClient(this); |
| 230 } | 247 } |
| 231 | 248 |
| 232 TileManager::~TileManager() { | 249 TileManager::~TileManager() { |
| 233 // Reset global state and manage. This should cause | 250 // Reset global state and manage. This should cause |
| 234 // our memory usage to drop to zero. | 251 // our memory usage to drop to zero. |
| 235 global_state_ = GlobalStateThatImpactsTilePriority(); | 252 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 236 | 253 |
| 237 RasterTaskQueue empty; | 254 RasterTaskQueue empty; |
| 238 rasterizer_->ScheduleTasks(&empty); | 255 rasterizer_->ScheduleTasks(&empty); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 used_layer_counts_.erase(layer_it); | 305 used_layer_counts_.erase(layer_it); |
| 289 image_decode_tasks_.erase(tile->layer_id()); | 306 image_decode_tasks_.erase(tile->layer_id()); |
| 290 } | 307 } |
| 291 | 308 |
| 292 delete tile; | 309 delete tile; |
| 293 it = released_tiles_.erase(it); | 310 it = released_tiles_.erase(it); |
| 294 } | 311 } |
| 295 } | 312 } |
| 296 | 313 |
| 297 void TileManager::DidFinishRunningTasks(TaskSet task_set) { | 314 void TileManager::DidFinishRunningTasks(TaskSet task_set) { |
| 298 if (task_set == ALL) { | 315 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", |
| 299 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL"); | 316 TaskSetName(task_set)); |
| 300 | 317 |
| 301 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > | 318 switch (task_set) { |
| 302 global_state_.soft_memory_limit_in_bytes; | 319 case ALL: { |
| 320 bool memory_usage_above_limit = |
| 321 resource_pool_->total_memory_usage_bytes() > |
| 322 global_state_.soft_memory_limit_in_bytes; |
| 303 | 323 |
| 304 // When OOM, keep re-assigning memory until we reach a steady state | 324 // When OOM, keep re-assigning memory until we reach a steady state |
| 305 // where top-priority tiles are initialized. | 325 // where top-priority tiles are initialized. |
| 306 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 326 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
| 307 !memory_usage_above_limit) | 327 !memory_usage_above_limit) |
| 308 return; | 328 return; |
| 309 | 329 |
| 310 rasterizer_->CheckForCompletedTasks(); | 330 rasterizer_->CheckForCompletedTasks(); |
| 311 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 331 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 312 | 332 |
| 313 TileVector tiles_that_need_to_be_rasterized; | 333 TileVector tiles_that_need_to_be_rasterized; |
| 314 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | 334 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); |
| 315 | 335 |
| 316 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 336 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 317 // steady memory state. Keep scheduling tasks until we reach this state. | 337 // steady memory state. Keep scheduling tasks until we reach this state. |
| 318 if (!tiles_that_need_to_be_rasterized.empty()) { | 338 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 319 ScheduleTasks(tiles_that_need_to_be_rasterized); | 339 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 340 return; |
| 341 } |
| 342 |
| 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 |
| 358 // not |
| 359 // been been assigned memory after reaching a steady memory state. This |
| 360 // ensures that we activate even when OOM. Note that we have to rebuilt |
| 361 // the |
| 362 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that |
| 363 // would otherwise not be picked up by the old raster queue. |
| 364 client_->BuildRasterQueue(&raster_priority_queue_, |
| 365 global_state_.tree_priority); |
| 366 bool ready_to_activate = true; |
| 367 while (!raster_priority_queue_.IsEmpty()) { |
| 368 Tile* tile = raster_priority_queue_.Top(); |
| 369 ManagedTileState& mts = tile->managed_state(); |
| 370 |
| 371 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { |
| 372 // If we can't raster on demand, give up early (and don't activate). |
| 373 if (!allow_rasterize_on_demand) { |
| 374 ready_to_activate = false; |
| 375 break; |
| 376 } |
| 377 |
| 378 mts.draw_info.set_rasterize_on_demand(); |
| 379 client_->NotifyTileStateChanged(tile); |
| 380 } |
| 381 raster_priority_queue_.Pop(); |
| 382 } |
| 383 |
| 384 if (ready_to_activate) { |
| 385 DCHECK(IsReadyToActivate()); |
| 386 ready_to_activate_check_notifier_.Schedule(); |
| 387 } |
| 388 raster_priority_queue_.Reset(); |
| 320 return; | 389 return; |
| 321 } | 390 } |
| 322 | 391 case REQUIRED_FOR_ACTIVATION: |
| 323 FreeResourcesForReleasedTiles(); | |
| 324 | |
| 325 resource_pool_->ReduceResourceUsage(); | |
| 326 | |
| 327 // We don't reserve memory for required-for-activation tiles during | |
| 328 // accelerated gestures, so we just postpone activation when we don't | |
| 329 // have these tiles, and activate after the accelerated gesture. | |
| 330 // Likewise if we don't allow any tiles (as is the case when we're | |
| 331 // invisible), if we have tiles that aren't ready, then we shouldn't | |
| 332 // activate as activation can cause checkerboards. | |
| 333 bool allow_rasterize_on_demand = | |
| 334 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | |
| 335 global_state_.memory_limit_policy != ALLOW_NOTHING; | |
| 336 | |
| 337 // Use on-demand raster for any required-for-activation tiles that have not | |
| 338 // been been assigned memory after reaching a steady memory state. This | |
| 339 // ensures that we activate even when OOM. Note that we have to rebuilt the | |
| 340 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | |
| 341 // would otherwise not be picked up by the old raster queue. | |
| 342 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 343 global_state_.tree_priority); | |
| 344 bool ready_to_activate = true; | |
| 345 while (!raster_priority_queue_.IsEmpty()) { | |
| 346 Tile* tile = raster_priority_queue_.Top(); | |
| 347 ManagedTileState& mts = tile->managed_state(); | |
| 348 | |
| 349 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { | |
| 350 // If we can't raster on demand, give up early (and don't activate). | |
| 351 if (!allow_rasterize_on_demand) { | |
| 352 ready_to_activate = false; | |
| 353 break; | |
| 354 } | |
| 355 | |
| 356 mts.draw_info.set_rasterize_on_demand(); | |
| 357 client_->NotifyTileStateChanged(tile); | |
| 358 } | |
| 359 raster_priority_queue_.Pop(); | |
| 360 } | |
| 361 | |
| 362 if (ready_to_activate) { | |
| 363 DCHECK(IsReadyToActivate()); | |
| 364 ready_to_activate_check_notifier_.Schedule(); | 392 ready_to_activate_check_notifier_.Schedule(); |
| 365 } | 393 return; |
| 366 raster_priority_queue_.Reset(); | 394 case REQUIRED_FOR_DRAW: |
| 367 return; | 395 ready_to_draw_check_notifier_.Schedule(); |
| 396 return; |
| 368 } | 397 } |
| 369 | 398 |
| 370 if (task_set == REQUIRED_FOR_ACTIVATION) { | 399 NOTREACHED(); |
| 371 TRACE_EVENT1("cc", | |
| 372 "TileManager::DidFinishRunningTasks", | |
| 373 "task_set", | |
| 374 "REQUIRED_FOR_ACTIVATION"); | |
| 375 ready_to_activate_check_notifier_.Schedule(); | |
| 376 } | |
| 377 } | 400 } |
| 378 | 401 |
| 379 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { | 402 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { |
| 380 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 403 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 381 | 404 |
| 382 global_state_ = state; | 405 global_state_ = state; |
| 383 | 406 |
| 384 // We need to call CheckForCompletedTasks() once in-between each call | 407 // We need to call CheckForCompletedTasks() once in-between each call |
| 385 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 408 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
| 386 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 409 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 | 687 |
| 665 DCHECK(mts.draw_info.requires_resource()); | 688 DCHECK(mts.draw_info.requires_resource()); |
| 666 DCHECK(!mts.draw_info.resource_); | 689 DCHECK(!mts.draw_info.resource_); |
| 667 | 690 |
| 668 if (!mts.raster_task.get()) | 691 if (!mts.raster_task.get()) |
| 669 mts.raster_task = CreateRasterTask(tile); | 692 mts.raster_task = CreateRasterTask(tile); |
| 670 | 693 |
| 671 TaskSetCollection task_sets; | 694 TaskSetCollection task_sets; |
| 672 if (tile->required_for_activation()) | 695 if (tile->required_for_activation()) |
| 673 task_sets.set(REQUIRED_FOR_ACTIVATION); | 696 task_sets.set(REQUIRED_FOR_ACTIVATION); |
| 697 if (tile->required_for_draw()) |
| 698 task_sets.set(REQUIRED_FOR_DRAW); |
| 674 task_sets.set(ALL); | 699 task_sets.set(ALL); |
| 675 raster_queue_.items.push_back( | 700 raster_queue_.items.push_back( |
| 676 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); | 701 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); |
| 677 } | 702 } |
| 678 | 703 |
| 679 // We must reduce the amount of unused resoruces before calling | 704 // We must reduce the amount of unused resoruces before calling |
| 680 // ScheduleTasks to prevent usage from rising above limits. | 705 // ScheduleTasks to prevent usage from rising above limits. |
| 681 resource_pool_->ReduceResourceUsage(); | 706 resource_pool_->ReduceResourceUsage(); |
| 682 | 707 |
| 683 // Schedule running of |raster_queue_|. This replaces any previously | 708 // Schedule running of |raster_queue_|. This replaces any previously |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 | 858 |
| 834 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { | 859 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { |
| 835 rasterizer_ = rasterizer; | 860 rasterizer_ = rasterizer; |
| 836 rasterizer_->SetClient(this); | 861 rasterizer_->SetClient(this); |
| 837 } | 862 } |
| 838 | 863 |
| 839 bool TileManager::IsReadyToActivate() const { | 864 bool TileManager::IsReadyToActivate() const { |
| 840 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); | 865 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); |
| 841 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); | 866 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
| 842 | 867 |
| 843 for (std::vector<PictureLayerImpl*>::const_iterator it = layers.begin(); | 868 for (const auto& layer : layers) { |
| 844 it != layers.end(); | 869 if (!layer->AllTilesRequiredForActivationAreReadyToDraw()) |
| 845 ++it) { | |
| 846 if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw()) | |
| 847 return false; | 870 return false; |
| 848 } | 871 } |
| 849 | 872 |
| 873 return true; |
| 874 } |
| 875 |
| 876 bool TileManager::IsReadyToDraw() const { |
| 877 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
| 878 |
| 879 for (const auto& layer : layers) { |
| 880 if (!layer->AllTilesRequiredForDrawAreReadyToDraw()) |
| 881 return false; |
| 882 } |
| 883 |
| 850 return true; | 884 return true; |
| 851 } | 885 } |
| 852 | 886 |
| 853 void TileManager::CheckIfReadyToActivate() { | 887 void TileManager::CheckIfReadyToActivate() { |
| 854 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | 888 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
| 855 | 889 |
| 856 rasterizer_->CheckForCompletedTasks(); | 890 rasterizer_->CheckForCompletedTasks(); |
| 857 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 891 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 858 | 892 |
| 859 if (IsReadyToActivate()) | 893 if (IsReadyToActivate()) |
| 860 client_->NotifyReadyToActivate(); | 894 client_->NotifyReadyToActivate(); |
| 861 } | 895 } |
| 862 | 896 |
| 897 void TileManager::CheckIfReadyToDraw() { |
| 898 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToDraw"); |
| 899 |
| 900 rasterizer_->CheckForCompletedTasks(); |
| 901 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 902 |
| 903 if (IsReadyToDraw()) |
| 904 client_->NotifyReadyToDraw(); |
| 905 } |
| 906 |
| 863 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 907 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
| 864 } | 908 } |
| 865 | 909 |
| 866 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 910 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) |
| 867 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | 911 : memory_bytes_(memory_bytes), resource_count_(resource_count) { |
| 868 } | 912 } |
| 869 | 913 |
| 870 // static | 914 // static |
| 871 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( | 915 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( |
| 872 const gfx::Size& size, | 916 const gfx::Size& size, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 result -= other; | 948 result -= other; |
| 905 return result; | 949 return result; |
| 906 } | 950 } |
| 907 | 951 |
| 908 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 952 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
| 909 return memory_bytes_ > limit.memory_bytes_ || | 953 return memory_bytes_ > limit.memory_bytes_ || |
| 910 resource_count_ > limit.resource_count_; | 954 resource_count_ > limit.resource_count_; |
| 911 } | 955 } |
| 912 | 956 |
| 913 } // namespace cc | 957 } // namespace cc |
| OLD | NEW |