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 } |
| 207 |
| 208 NOTREACHED(); |
| 209 return "Invalid TaskSet"; |
| 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", "TileManager::DidFinishRunningTasks", "task_set", |
319 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL"); | 336 TaskSetName(task_set)); |
320 | 337 |
321 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > | 338 switch (task_set) { |
322 global_state_.soft_memory_limit_in_bytes; | 339 case ALL: { |
| 340 bool memory_usage_above_limit = |
| 341 resource_pool_->total_memory_usage_bytes() > |
| 342 global_state_.soft_memory_limit_in_bytes; |
323 | 343 |
324 // When OOM, keep re-assigning memory until we reach a steady state | 344 // When OOM, keep re-assigning memory until we reach a steady state |
325 // where top-priority tiles are initialized. | 345 // where top-priority tiles are initialized. |
326 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 346 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
327 !memory_usage_above_limit) | 347 !memory_usage_above_limit) |
328 return; | 348 return; |
329 | 349 |
330 rasterizer_->CheckForCompletedTasks(); | 350 rasterizer_->CheckForCompletedTasks(); |
331 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 351 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
332 | 352 |
333 TileVector tiles_that_need_to_be_rasterized; | 353 TileVector tiles_that_need_to_be_rasterized; |
334 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | 354 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); |
335 | 355 |
336 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 356 // |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. | 357 // steady memory state. Keep scheduling tasks until we reach this state. |
338 if (!tiles_that_need_to_be_rasterized.empty()) { | 358 if (!tiles_that_need_to_be_rasterized.empty()) { |
339 ScheduleTasks(tiles_that_need_to_be_rasterized); | 359 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 360 return; |
| 361 } |
| 362 |
| 363 FreeResourcesForReleasedTiles(); |
| 364 |
| 365 resource_pool_->ReduceResourceUsage(); |
| 366 |
| 367 // We don't reserve memory for required-for-activation tiles during |
| 368 // accelerated gestures, so we just postpone activation when we don't |
| 369 // have these tiles, and activate after the accelerated gesture. |
| 370 // Likewise if we don't allow any tiles (as is the case when we're |
| 371 // invisible), if we have tiles that aren't ready, then we shouldn't |
| 372 // activate as activation can cause checkerboards. |
| 373 bool allow_rasterize_on_demand = |
| 374 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && |
| 375 global_state_.memory_limit_policy != ALLOW_NOTHING; |
| 376 |
| 377 // Use on-demand raster for any required-for-activation tiles that have |
| 378 // not |
| 379 // been been assigned memory after reaching a steady memory state. This |
| 380 // ensures that we activate even when OOM. Note that we have to rebuilt |
| 381 // the |
| 382 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that |
| 383 // would otherwise not be picked up by the old raster queue. |
| 384 client_->BuildRasterQueue(&raster_priority_queue_, |
| 385 global_state_.tree_priority); |
| 386 bool ready_to_activate = true; |
| 387 while (!raster_priority_queue_.IsEmpty()) { |
| 388 Tile* tile = raster_priority_queue_.Top(); |
| 389 ManagedTileState& mts = tile->managed_state(); |
| 390 |
| 391 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { |
| 392 // If we can't raster on demand, give up early (and don't activate). |
| 393 if (!allow_rasterize_on_demand) { |
| 394 ready_to_activate = false; |
| 395 break; |
| 396 } |
| 397 |
| 398 mts.draw_info.set_rasterize_on_demand(); |
| 399 client_->NotifyTileStateChanged(tile); |
| 400 } |
| 401 raster_priority_queue_.Pop(); |
| 402 } |
| 403 |
| 404 if (ready_to_activate) { |
| 405 DCHECK(IsReadyToActivate()); |
| 406 ready_to_activate_check_notifier_.Schedule(); |
| 407 } |
| 408 raster_priority_queue_.Reset(); |
340 return; | 409 return; |
341 } | 410 } |
342 | 411 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(); | 412 ready_to_activate_check_notifier_.Schedule(); |
385 } | 413 return; |
386 raster_priority_queue_.Reset(); | 414 case REQUIRED_FOR_DRAW: |
387 return; | 415 ready_to_draw_check_notifier_.Schedule(); |
| 416 return; |
388 } | 417 } |
389 | 418 |
390 if (task_set == REQUIRED_FOR_ACTIVATION) { | 419 NOTREACHED(); |
391 TRACE_EVENT1("cc", | |
392 "TileManager::DidFinishRunningTasks", | |
393 "task_set", | |
394 "REQUIRED_FOR_ACTIVATION"); | |
395 ready_to_activate_check_notifier_.Schedule(); | |
396 } | |
397 } | 420 } |
398 | 421 |
399 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { | 422 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { |
400 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 423 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
401 | 424 |
402 global_state_ = state; | 425 global_state_ = state; |
403 | 426 |
404 // We need to call CheckForCompletedTasks() once in-between each call | 427 // We need to call CheckForCompletedTasks() once in-between each call |
405 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 428 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
406 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 429 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 | 706 |
684 DCHECK(mts.draw_info.requires_resource()); | 707 DCHECK(mts.draw_info.requires_resource()); |
685 DCHECK(!mts.draw_info.resource_); | 708 DCHECK(!mts.draw_info.resource_); |
686 | 709 |
687 if (!mts.raster_task.get()) | 710 if (!mts.raster_task.get()) |
688 mts.raster_task = CreateRasterTask(tile); | 711 mts.raster_task = CreateRasterTask(tile); |
689 | 712 |
690 TaskSetCollection task_sets; | 713 TaskSetCollection task_sets; |
691 if (tile->required_for_activation()) | 714 if (tile->required_for_activation()) |
692 task_sets.set(REQUIRED_FOR_ACTIVATION); | 715 task_sets.set(REQUIRED_FOR_ACTIVATION); |
| 716 if (tile->required_for_draw()) |
| 717 task_sets.set(REQUIRED_FOR_DRAW); |
693 task_sets.set(ALL); | 718 task_sets.set(ALL); |
694 raster_queue_.items.push_back( | 719 raster_queue_.items.push_back( |
695 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); | 720 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); |
696 } | 721 } |
697 | 722 |
698 // We must reduce the amount of unused resoruces before calling | 723 // We must reduce the amount of unused resoruces before calling |
699 // ScheduleTasks to prevent usage from rising above limits. | 724 // ScheduleTasks to prevent usage from rising above limits. |
700 resource_pool_->ReduceResourceUsage(); | 725 resource_pool_->ReduceResourceUsage(); |
701 | 726 |
702 // Schedule running of |raster_queue_|. This replaces any previously | 727 // Schedule running of |raster_queue_|. This replaces any previously |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 } | 876 } |
852 | 877 |
853 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { | 878 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { |
854 rasterizer_ = rasterizer; | 879 rasterizer_ = rasterizer; |
855 rasterizer_->SetClient(this); | 880 rasterizer_->SetClient(this); |
856 } | 881 } |
857 | 882 |
858 bool TileManager::IsReadyToActivate() const { | 883 bool TileManager::IsReadyToActivate() const { |
859 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); | 884 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
860 | 885 |
861 for (std::vector<PictureLayerImpl*>::const_iterator it = layers.begin(); | 886 for (const auto& layer : layers) { |
862 it != layers.end(); | 887 if (!layer->AllTilesRequiredForActivationAreReadyToDraw()) |
863 ++it) { | |
864 if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw()) | |
865 return false; | 888 return false; |
866 } | 889 } |
867 | 890 |
| 891 return true; |
| 892 } |
| 893 |
| 894 bool TileManager::IsReadyToDraw() const { |
| 895 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
| 896 |
| 897 for (const auto& layer : layers) { |
| 898 if (!layer->AllTilesRequiredForDrawAreReadyToDraw()) |
| 899 return false; |
| 900 } |
| 901 |
868 return true; | 902 return true; |
869 } | 903 } |
870 | 904 |
871 void TileManager::CheckIfReadyToActivate() { | 905 void TileManager::CheckIfReadyToActivate() { |
872 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | 906 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
873 | 907 |
874 rasterizer_->CheckForCompletedTasks(); | 908 rasterizer_->CheckForCompletedTasks(); |
875 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 909 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
876 | 910 |
877 if (IsReadyToActivate()) | 911 if (IsReadyToActivate()) |
878 client_->NotifyReadyToActivate(); | 912 client_->NotifyReadyToActivate(); |
879 } | 913 } |
880 | 914 |
| 915 void TileManager::CheckIfReadyToDraw() { |
| 916 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToDraw"); |
| 917 |
| 918 rasterizer_->CheckForCompletedTasks(); |
| 919 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 920 |
| 921 if (IsReadyToDraw()) |
| 922 client_->NotifyReadyToDraw(); |
| 923 } |
| 924 |
881 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 925 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
882 } | 926 } |
883 | 927 |
884 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 928 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) |
885 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | 929 : memory_bytes_(memory_bytes), resource_count_(resource_count) { |
886 } | 930 } |
887 | 931 |
888 // static | 932 // static |
889 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( | 933 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( |
890 const gfx::Size& size, | 934 const gfx::Size& size, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 result -= other; | 966 result -= other; |
923 return result; | 967 return result; |
924 } | 968 } |
925 | 969 |
926 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 970 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
927 return memory_bytes_ > limit.memory_bytes_ || | 971 return memory_bytes_ > limit.memory_bytes_ || |
928 resource_count_ > limit.resource_count_; | 972 resource_count_ > limit.resource_count_; |
929 } | 973 } |
930 | 974 |
931 } // namespace cc | 975 } // namespace cc |
OLD | NEW |