| 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/tiles/tile_manager.h" | 5 #include "cc/tiles/tile_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 state->SetInteger("completed_count", | 300 state->SetInteger("completed_count", |
| 301 base::saturated_cast<int>(stats.completed_count)); | 301 base::saturated_cast<int>(stats.completed_count)); |
| 302 state->SetInteger("canceled_count", | 302 state->SetInteger("canceled_count", |
| 303 base::saturated_cast<int>(stats.canceled_count)); | 303 base::saturated_cast<int>(stats.canceled_count)); |
| 304 return std::move(state); | 304 return std::move(state); |
| 305 } | 305 } |
| 306 | 306 |
| 307 TileManager::TileManager(TileManagerClient* client, | 307 TileManager::TileManager(TileManagerClient* client, |
| 308 base::SequencedTaskRunner* task_runner, | 308 base::SequencedTaskRunner* task_runner, |
| 309 size_t scheduled_raster_task_limit, | 309 size_t scheduled_raster_task_limit, |
| 310 bool use_partial_raster) | 310 bool use_partial_raster, |
| 311 int max_preraster_distance_in_screen_pixels) |
| 311 : client_(client), | 312 : client_(client), |
| 312 task_runner_(task_runner), | 313 task_runner_(task_runner), |
| 313 resource_pool_(nullptr), | 314 resource_pool_(nullptr), |
| 314 tile_task_manager_(nullptr), | 315 tile_task_manager_(nullptr), |
| 315 scheduled_raster_task_limit_(scheduled_raster_task_limit), | 316 scheduled_raster_task_limit_(scheduled_raster_task_limit), |
| 316 use_partial_raster_(use_partial_raster), | 317 use_partial_raster_(use_partial_raster), |
| 317 use_gpu_rasterization_(false), | 318 use_gpu_rasterization_(false), |
| 318 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), | 319 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), |
| 319 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 320 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 320 did_oom_on_last_assign_(false), | 321 did_oom_on_last_assign_(false), |
| 321 more_tiles_need_prepare_check_notifier_( | 322 more_tiles_need_prepare_check_notifier_( |
| 322 task_runner_, | 323 task_runner_, |
| 323 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, | 324 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, |
| 324 base::Unretained(this))), | 325 base::Unretained(this))), |
| 325 signals_check_notifier_(task_runner_, | 326 signals_check_notifier_(task_runner_, |
| 326 base::Bind(&TileManager::CheckAndIssueSignals, | 327 base::Bind(&TileManager::CheckAndIssueSignals, |
| 327 base::Unretained(this))), | 328 base::Unretained(this))), |
| 328 has_scheduled_tile_tasks_(false), | 329 has_scheduled_tile_tasks_(false), |
| 329 prepare_tiles_count_(0u), | 330 prepare_tiles_count_(0u), |
| 330 next_tile_id_(0u), | 331 next_tile_id_(0u), |
| 332 max_preraster_distance_in_screen_pixels_( |
| 333 max_preraster_distance_in_screen_pixels), |
| 331 task_set_finished_weak_ptr_factory_(this) {} | 334 task_set_finished_weak_ptr_factory_(this) {} |
| 332 | 335 |
| 333 TileManager::~TileManager() { | 336 TileManager::~TileManager() { |
| 334 FinishTasksAndCleanUp(); | 337 FinishTasksAndCleanUp(); |
| 335 } | 338 } |
| 336 | 339 |
| 337 void TileManager::FinishTasksAndCleanUp() { | 340 void TileManager::FinishTasksAndCleanUp() { |
| 338 if (!tile_task_manager_) | 341 if (!tile_task_manager_) |
| 339 return; | 342 return; |
| 340 | 343 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 351 tile_task_manager_->CheckForCompletedTasks(); | 354 tile_task_manager_->CheckForCompletedTasks(); |
| 352 | 355 |
| 353 FreeResourcesForReleasedTiles(); | 356 FreeResourcesForReleasedTiles(); |
| 354 CleanUpReleasedTiles(); | 357 CleanUpReleasedTiles(); |
| 355 | 358 |
| 356 tile_task_manager_ = nullptr; | 359 tile_task_manager_ = nullptr; |
| 357 resource_pool_ = nullptr; | 360 resource_pool_ = nullptr; |
| 358 more_tiles_need_prepare_check_notifier_.Cancel(); | 361 more_tiles_need_prepare_check_notifier_.Cancel(); |
| 359 signals_check_notifier_.Cancel(); | 362 signals_check_notifier_.Cancel(); |
| 360 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | 363 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 364 |
| 365 for (auto& draw_image_pair : locked_images_) |
| 366 image_decode_controller_->UnrefImage(draw_image_pair.first); |
| 367 locked_images_.clear(); |
| 361 } | 368 } |
| 362 | 369 |
| 363 void TileManager::SetResources(ResourcePool* resource_pool, | 370 void TileManager::SetResources(ResourcePool* resource_pool, |
| 364 ImageDecodeController* image_decode_controller, | 371 ImageDecodeController* image_decode_controller, |
| 365 TileTaskManager* tile_task_manager, | 372 TileTaskManager* tile_task_manager, |
| 366 size_t scheduled_raster_task_limit, | 373 size_t scheduled_raster_task_limit, |
| 367 bool use_gpu_rasterization) { | 374 bool use_gpu_rasterization) { |
| 368 DCHECK(!tile_task_manager_); | 375 DCHECK(!tile_task_manager_); |
| 369 DCHECK(tile_task_manager); | 376 DCHECK(tile_task_manager); |
| 370 | 377 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 // We need to call CheckForCompletedTasks() once in-between each call | 468 // We need to call CheckForCompletedTasks() once in-between each call |
| 462 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 469 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
| 463 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 470 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
| 464 tile_task_manager_->CheckForCompletedTasks(); | 471 tile_task_manager_->CheckForCompletedTasks(); |
| 465 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 472 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 466 } | 473 } |
| 467 | 474 |
| 468 FreeResourcesForReleasedTiles(); | 475 FreeResourcesForReleasedTiles(); |
| 469 CleanUpReleasedTiles(); | 476 CleanUpReleasedTiles(); |
| 470 | 477 |
| 471 std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized = | 478 PrioritizedWorkToSchedule prioritized_work = AssignGpuMemoryToTiles(); |
| 472 AssignGpuMemoryToTiles(); | |
| 473 | 479 |
| 474 // Inform the client that will likely require a draw if the highest priority | 480 // Inform the client that will likely require a draw if the highest priority |
| 475 // tile that will be rasterized is required for draw. | 481 // tile that will be rasterized is required for draw. |
| 476 client_->SetIsLikelyToRequireADraw( | 482 client_->SetIsLikelyToRequireADraw( |
| 477 !tiles_that_need_to_be_rasterized.empty() && | 483 !prioritized_work.tiles_to_raster.empty() && |
| 478 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); | 484 prioritized_work.tiles_to_raster.front().tile()->required_for_draw()); |
| 479 | 485 |
| 480 // Schedule tile tasks. | 486 // Schedule tile tasks. |
| 481 ScheduleTasks(tiles_that_need_to_be_rasterized); | 487 ScheduleTasks(prioritized_work); |
| 482 | 488 |
| 483 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, | 489 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, |
| 484 "state", BasicStateAsValue()); | 490 "state", BasicStateAsValue()); |
| 485 return true; | 491 return true; |
| 486 } | 492 } |
| 487 | 493 |
| 488 void TileManager::Flush() { | 494 void TileManager::Flush() { |
| 489 TRACE_EVENT0("cc", "TileManager::Flush"); | 495 TRACE_EVENT0("cc", "TileManager::Flush"); |
| 490 | 496 |
| 491 if (!tile_task_manager_) { | 497 if (!tile_task_manager_) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 case ALLOW_PREPAINT_ONLY: | 581 case ALLOW_PREPAINT_ONLY: |
| 576 return priority.priority_bin > TilePriority::SOON; | 582 return priority.priority_bin > TilePriority::SOON; |
| 577 case ALLOW_ANYTHING: | 583 case ALLOW_ANYTHING: |
| 578 return priority.distance_to_visible == | 584 return priority.distance_to_visible == |
| 579 std::numeric_limits<float>::infinity(); | 585 std::numeric_limits<float>::infinity(); |
| 580 } | 586 } |
| 581 NOTREACHED(); | 587 NOTREACHED(); |
| 582 return true; | 588 return true; |
| 583 } | 589 } |
| 584 | 590 |
| 585 std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() { | 591 TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { |
| 586 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); | 592 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 587 | 593 |
| 588 DCHECK(resource_pool_); | 594 DCHECK(resource_pool_); |
| 589 DCHECK(tile_task_manager_); | 595 DCHECK(tile_task_manager_); |
| 590 | 596 |
| 591 // Maintain the list of released resources that can potentially be re-used | 597 // Maintain the list of released resources that can potentially be re-used |
| 592 // or deleted. If this operation becomes expensive too, only do this after | 598 // or deleted. If this operation becomes expensive too, only do this after |
| 593 // some resource(s) was returned. Note that in that case, one also need to | 599 // some resource(s) was returned. Note that in that case, one also need to |
| 594 // invalidate when releasing some resource from the pool. | 600 // invalidate when releasing some resource from the pool. |
| 595 resource_pool_->CheckBusyResources(); | 601 resource_pool_->CheckBusyResources(); |
| 596 | 602 |
| 597 // Now give memory out to the tiles until we're out, and build | 603 // Now give memory out to the tiles until we're out, and build |
| 598 // the needs-to-be-rasterized queue. | 604 // the needs-to-be-rasterized queue. |
| 599 unsigned schedule_priority = 1u; | 605 unsigned schedule_priority = 1u; |
| 600 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 606 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
| 601 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 607 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
| 602 | 608 |
| 603 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 609 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, |
| 604 global_state_.num_resources_limit); | 610 global_state_.num_resources_limit); |
| 605 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 611 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, |
| 606 global_state_.num_resources_limit); | 612 global_state_.num_resources_limit); |
| 607 MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(), | 613 MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(), |
| 608 resource_pool_->resource_count()); | 614 resource_pool_->resource_count()); |
| 609 | 615 |
| 610 std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( | 616 std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( |
| 611 client_->BuildRasterQueue(global_state_.tree_priority, | 617 client_->BuildRasterQueue(global_state_.tree_priority, |
| 612 RasterTilePriorityQueue::Type::ALL)); | 618 RasterTilePriorityQueue::Type::ALL)); |
| 613 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue; | 619 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue; |
| 614 std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized; | 620 PrioritizedWorkToSchedule work_to_schedule; |
| 615 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { | 621 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
| 616 const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); | 622 const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); |
| 617 Tile* tile = prioritized_tile.tile(); | 623 Tile* tile = prioritized_tile.tile(); |
| 618 TilePriority priority = prioritized_tile.priority(); | 624 TilePriority priority = prioritized_tile.priority(); |
| 619 | 625 |
| 620 if (TilePriorityViolatesMemoryPolicy(priority)) { | 626 if (TilePriorityViolatesMemoryPolicy(priority)) { |
| 621 TRACE_EVENT_INSTANT0( | 627 TRACE_EVENT_INSTANT0( |
| 622 "cc", "TileManager::AssignGpuMemory tile violates memory policy", | 628 "cc", "TileManager::AssignGpuMemory tile violates memory policy", |
| 623 TRACE_EVENT_SCOPE_THREAD); | 629 TRACE_EVENT_SCOPE_THREAD); |
| 624 break; | 630 break; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 637 if (is_solid_color) { | 643 if (is_solid_color) { |
| 638 tile->draw_info().set_solid_color(color); | 644 tile->draw_info().set_solid_color(color); |
| 639 tile->draw_info().set_was_ever_ready_to_draw(); | 645 tile->draw_info().set_was_ever_ready_to_draw(); |
| 640 if (!tile_is_needed_now) | 646 if (!tile_is_needed_now) |
| 641 tile->draw_info().set_was_a_prepaint_tile(); | 647 tile->draw_info().set_was_a_prepaint_tile(); |
| 642 client_->NotifyTileStateChanged(tile); | 648 client_->NotifyTileStateChanged(tile); |
| 643 continue; | 649 continue; |
| 644 } | 650 } |
| 645 } | 651 } |
| 646 | 652 |
| 653 // Prepaint tiles that are far away are only processed for images. |
| 654 if (!tile->required_for_activation() && !tile->required_for_draw() && |
| 655 priority.distance_to_visible > |
| 656 max_preraster_distance_in_screen_pixels_) { |
| 657 work_to_schedule.tiles_to_process_for_images.push_back(prioritized_tile); |
| 658 continue; |
| 659 } |
| 660 |
| 647 // We won't be able to schedule this tile, so break out early. | 661 // We won't be able to schedule this tile, so break out early. |
| 648 if (tiles_that_need_to_be_rasterized.size() >= | 662 if (work_to_schedule.tiles_to_raster.size() >= |
| 649 scheduled_raster_task_limit_) { | 663 scheduled_raster_task_limit_) { |
| 650 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 664 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
| 651 break; | 665 break; |
| 652 } | 666 } |
| 653 | 667 |
| 654 tile->scheduled_priority_ = schedule_priority++; | 668 tile->scheduled_priority_ = schedule_priority++; |
| 655 | 669 |
| 656 DCHECK(tile->draw_info().mode() == TileDrawInfo::OOM_MODE || | 670 DCHECK(tile->draw_info().mode() == TileDrawInfo::OOM_MODE || |
| 657 !tile->draw_info().IsReadyToDraw()); | 671 !tile->draw_info().IsReadyToDraw()); |
| 658 | 672 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 683 // If we couldn't fit the tile into our current memory limit, then we're | 697 // If we couldn't fit the tile into our current memory limit, then we're |
| 684 // done. | 698 // done. |
| 685 if (!memory_usage_is_within_limit) { | 699 if (!memory_usage_is_within_limit) { |
| 686 if (tile_is_needed_now) | 700 if (tile_is_needed_now) |
| 687 had_enough_memory_to_schedule_tiles_needed_now = false; | 701 had_enough_memory_to_schedule_tiles_needed_now = false; |
| 688 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 702 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
| 689 break; | 703 break; |
| 690 } | 704 } |
| 691 | 705 |
| 692 memory_usage += memory_required_by_tile_to_be_scheduled; | 706 memory_usage += memory_required_by_tile_to_be_scheduled; |
| 693 tiles_that_need_to_be_rasterized.push_back(prioritized_tile); | 707 work_to_schedule.tiles_to_raster.push_back(prioritized_tile); |
| 694 | 708 |
| 695 // Since we scheduled the tile, set whether it was a prepaint or not | 709 // Since we scheduled the tile, set whether it was a prepaint or not |
| 696 // assuming that the tile will successfully finish running. We don't have | 710 // assuming that the tile will successfully finish running. We don't have |
| 697 // priority information at the time the tile completes, so it should be done | 711 // priority information at the time the tile completes, so it should be done |
| 698 // here. | 712 // here. |
| 699 if (!tile_is_needed_now) | 713 if (!tile_is_needed_now) |
| 700 tile->draw_info().set_was_a_prepaint_tile(); | 714 tile->draw_info().set_was_a_prepaint_tile(); |
| 701 } | 715 } |
| 702 | 716 |
| 703 // Note that we should try and further reduce memory in case the above loop | 717 // Note that we should try and further reduce memory in case the above loop |
| (...skipping 11 matching lines...) Expand all Loading... |
| 715 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); | 729 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); |
| 716 DCHECK_GE(memory_stats_from_last_assign_.total_bytes_used, 0); | 730 DCHECK_GE(memory_stats_from_last_assign_.total_bytes_used, 0); |
| 717 memory_stats_from_last_assign_.had_enough_memory = | 731 memory_stats_from_last_assign_.had_enough_memory = |
| 718 had_enough_memory_to_schedule_tiles_needed_now; | 732 had_enough_memory_to_schedule_tiles_needed_now; |
| 719 | 733 |
| 720 TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles", | 734 TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles", |
| 721 "all_tiles_that_need_to_be_rasterized_are_scheduled", | 735 "all_tiles_that_need_to_be_rasterized_are_scheduled", |
| 722 all_tiles_that_need_to_be_rasterized_are_scheduled_, | 736 all_tiles_that_need_to_be_rasterized_are_scheduled_, |
| 723 "had_enough_memory_to_schedule_tiles_needed_now", | 737 "had_enough_memory_to_schedule_tiles_needed_now", |
| 724 had_enough_memory_to_schedule_tiles_needed_now); | 738 had_enough_memory_to_schedule_tiles_needed_now); |
| 725 return tiles_that_need_to_be_rasterized; | 739 return work_to_schedule; |
| 726 } | 740 } |
| 727 | 741 |
| 728 void TileManager::FreeResourcesForTile(Tile* tile) { | 742 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 729 TileDrawInfo& draw_info = tile->draw_info(); | 743 TileDrawInfo& draw_info = tile->draw_info(); |
| 730 if (draw_info.resource_) { | 744 if (draw_info.resource_) { |
| 731 resource_pool_->ReleaseResource(draw_info.resource_, tile->id()); | 745 resource_pool_->ReleaseResource(draw_info.resource_, tile->id()); |
| 732 draw_info.resource_ = nullptr; | 746 draw_info.resource_ = nullptr; |
| 733 } | 747 } |
| 734 } | 748 } |
| 735 | 749 |
| 736 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | 750 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
| 737 Tile* tile) { | 751 Tile* tile) { |
| 738 bool was_ready_to_draw = tile->draw_info().IsReadyToDraw(); | 752 bool was_ready_to_draw = tile->draw_info().IsReadyToDraw(); |
| 739 FreeResourcesForTile(tile); | 753 FreeResourcesForTile(tile); |
| 740 if (was_ready_to_draw) | 754 if (was_ready_to_draw) |
| 741 client_->NotifyTileStateChanged(tile); | 755 client_->NotifyTileStateChanged(tile); |
| 742 } | 756 } |
| 743 | 757 |
| 744 void TileManager::ScheduleTasks( | 758 void TileManager::ScheduleTasks( |
| 745 const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized) { | 759 const PrioritizedWorkToSchedule& work_to_schedule) { |
| 760 const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized = |
| 761 work_to_schedule.tiles_to_raster; |
| 746 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count", | 762 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count", |
| 747 tiles_that_need_to_be_rasterized.size()); | 763 tiles_that_need_to_be_rasterized.size()); |
| 748 | 764 |
| 749 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 765 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
| 750 | 766 |
| 751 if (!has_scheduled_tile_tasks_) { | 767 if (!has_scheduled_tile_tasks_) { |
| 752 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); | 768 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); |
| 753 } | 769 } |
| 754 | 770 |
| 755 // Cancel existing OnTaskSetFinished callbacks. | 771 // Cancel existing OnTaskSetFinished callbacks. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 // A tile should use a foreground task cateogry if it is either blocking | 825 // A tile should use a foreground task cateogry if it is either blocking |
| 810 // future compositing (required for draw or required for activation), or if | 826 // future compositing (required for draw or required for activation), or if |
| 811 // it has a priority bin of NOW for another reason (low resolution tiles). | 827 // it has a priority bin of NOW for another reason (low resolution tiles). |
| 812 bool use_foreground_category = | 828 bool use_foreground_category = |
| 813 tile->required_for_draw() || tile->required_for_activation() || | 829 tile->required_for_draw() || tile->required_for_activation() || |
| 814 prioritized_tile.priority().priority_bin == TilePriority::NOW; | 830 prioritized_tile.priority().priority_bin == TilePriority::NOW; |
| 815 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, | 831 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, |
| 816 use_foreground_category); | 832 use_foreground_category); |
| 817 } | 833 } |
| 818 | 834 |
| 835 const std::vector<PrioritizedTile>& tiles_to_process_for_images = |
| 836 work_to_schedule.tiles_to_process_for_images; |
| 837 std::vector<std::pair<DrawImage, scoped_refptr<TileTask>>> new_locked_images; |
| 838 for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) { |
| 839 Tile* tile = prioritized_tile.tile(); |
| 840 |
| 841 std::vector<DrawImage> images; |
| 842 prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
| 843 tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
| 844 ImageDecodeController::TracingInfo tracing_info( |
| 845 prepare_tiles_count_, prioritized_tile.priority().priority_bin); |
| 846 for (DrawImage& draw_image : images) { |
| 847 scoped_refptr<TileTask> task; |
| 848 bool need_to_unref_when_finished = |
| 849 image_decode_controller_->GetTaskForImageAndRef(draw_image, |
| 850 tracing_info, &task); |
| 851 // We only care about images that need to be locked (ie they need to be |
| 852 // unreffed later). |
| 853 if (!need_to_unref_when_finished) |
| 854 continue; |
| 855 new_locked_images.emplace_back(draw_image, task); |
| 856 |
| 857 // If there's no actual task associated with this image, then we're done. |
| 858 if (!task) |
| 859 continue; |
| 860 |
| 861 auto decode_it = std::find_if(graph_.nodes.begin(), graph_.nodes.end(), |
| 862 [&task](const TaskGraph::Node& node) { |
| 863 return node.task == task.get(); |
| 864 }); |
| 865 // If this task is already in the graph, then we don't have to insert it. |
| 866 if (decode_it != graph_.nodes.end()) |
| 867 continue; |
| 868 |
| 869 InsertNodeForDecodeTask(&graph_, task.get(), false, priority++); |
| 870 all_count++; |
| 871 graph_.edges.push_back(TaskGraph::Edge(task.get(), all_done_task.get())); |
| 872 } |
| 873 } |
| 874 |
| 875 for (auto& draw_image_pair : locked_images_) |
| 876 image_decode_controller_->UnrefImage(draw_image_pair.first); |
| 877 // The old locked images have to stay around until past the ScheduleTasks call |
| 878 // below, so we do a swap instead of a move. |
| 879 locked_images_.swap(new_locked_images); |
| 880 |
| 819 // Insert nodes for our task completion tasks. We enqueue these using | 881 // Insert nodes for our task completion tasks. We enqueue these using |
| 820 // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and | 882 // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and |
| 821 // we'd like to run these tasks as soon as possible. | 883 // we'd like to run these tasks as soon as possible. |
| 822 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), | 884 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), |
| 823 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 885 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
| 824 kRequiredForActivationDoneTaskPriority, | 886 kRequiredForActivationDoneTaskPriority, |
| 825 required_for_activate_count); | 887 required_for_activate_count); |
| 826 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), | 888 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), |
| 827 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 889 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
| 828 kRequiredForDrawDoneTaskPriority, required_for_draw_count); | 890 kRequiredForDrawDoneTaskPriority, required_for_draw_count); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 } | 1124 } |
| 1063 } | 1125 } |
| 1064 } | 1126 } |
| 1065 | 1127 |
| 1066 void TileManager::CheckIfMoreTilesNeedToBePrepared() { | 1128 void TileManager::CheckIfMoreTilesNeedToBePrepared() { |
| 1067 tile_task_manager_->CheckForCompletedTasks(); | 1129 tile_task_manager_->CheckForCompletedTasks(); |
| 1068 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 1130 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 1069 | 1131 |
| 1070 // When OOM, keep re-assigning memory until we reach a steady state | 1132 // When OOM, keep re-assigning memory until we reach a steady state |
| 1071 // where top-priority tiles are initialized. | 1133 // where top-priority tiles are initialized. |
| 1072 std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized = | 1134 PrioritizedWorkToSchedule work_to_schedule = AssignGpuMemoryToTiles(); |
| 1073 AssignGpuMemoryToTiles(); | |
| 1074 | 1135 |
| 1075 // Inform the client that will likely require a draw if the highest priority | 1136 // Inform the client that will likely require a draw if the highest priority |
| 1076 // tile that will be rasterized is required for draw. | 1137 // tile that will be rasterized is required for draw. |
| 1077 client_->SetIsLikelyToRequireADraw( | 1138 client_->SetIsLikelyToRequireADraw( |
| 1078 !tiles_that_need_to_be_rasterized.empty() && | 1139 !work_to_schedule.tiles_to_raster.empty() && |
| 1079 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); | 1140 work_to_schedule.tiles_to_raster.front().tile()->required_for_draw()); |
| 1080 | 1141 |
| 1081 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 1142 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 1082 // steady memory state. Keep scheduling tasks until we reach this state. | 1143 // steady memory state. Keep scheduling tasks until we reach this state. |
| 1083 if (!tiles_that_need_to_be_rasterized.empty()) { | 1144 if (!work_to_schedule.tiles_to_raster.empty()) { |
| 1084 ScheduleTasks(tiles_that_need_to_be_rasterized); | 1145 ScheduleTasks(work_to_schedule); |
| 1085 return; | 1146 return; |
| 1086 } | 1147 } |
| 1087 | 1148 |
| 1149 // If we're not in SMOOTHNESS_TAKES_PRIORITY mode, we should unlock all |
| 1150 // images since we're technically going idle here at least for this frame. |
| 1151 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) { |
| 1152 for (auto& draw_image_pair : locked_images_) |
| 1153 image_decode_controller_->UnrefImage(draw_image_pair.first); |
| 1154 locked_images_.clear(); |
| 1155 } |
| 1156 |
| 1088 FreeResourcesForReleasedTiles(); | 1157 FreeResourcesForReleasedTiles(); |
| 1089 | 1158 |
| 1090 resource_pool_->ReduceResourceUsage(); | 1159 resource_pool_->ReduceResourceUsage(); |
| 1091 image_decode_controller_->ReduceCacheUsage(); | 1160 image_decode_controller_->ReduceCacheUsage(); |
| 1092 | 1161 |
| 1093 signals_.all_tile_tasks_completed = true; | 1162 signals_.all_tile_tasks_completed = true; |
| 1094 signals_check_notifier_.Schedule(); | 1163 signals_check_notifier_.Schedule(); |
| 1095 | 1164 |
| 1096 // We don't reserve memory for required-for-activation tiles during | 1165 // We don't reserve memory for required-for-activation tiles during |
| 1097 // accelerated gestures, so we just postpone activation when we don't | 1166 // accelerated gestures, so we just postpone activation when we don't |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 | 1315 |
| 1247 void TileManager::Signals::reset() { | 1316 void TileManager::Signals::reset() { |
| 1248 ready_to_activate = false; | 1317 ready_to_activate = false; |
| 1249 did_notify_ready_to_activate = false; | 1318 did_notify_ready_to_activate = false; |
| 1250 ready_to_draw = false; | 1319 ready_to_draw = false; |
| 1251 did_notify_ready_to_draw = false; | 1320 did_notify_ready_to_draw = false; |
| 1252 all_tile_tasks_completed = false; | 1321 all_tile_tasks_completed = false; |
| 1253 did_notify_all_tile_tasks_completed = false; | 1322 did_notify_all_tile_tasks_completed = false; |
| 1254 } | 1323 } |
| 1255 | 1324 |
| 1325 TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule() = default; |
| 1326 TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule( |
| 1327 PrioritizedWorkToSchedule&& other) = default; |
| 1328 TileManager::PrioritizedWorkToSchedule::~PrioritizedWorkToSchedule() = default; |
| 1329 |
| 1256 } // namespace cc | 1330 } // namespace cc |
| OLD | NEW |