| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 | 315 |
| 316 tile_task_runner_ = nullptr; | 316 tile_task_runner_ = nullptr; |
| 317 resource_pool_ = nullptr; | 317 resource_pool_ = nullptr; |
| 318 more_tiles_need_prepare_check_notifier_.Cancel(); | 318 more_tiles_need_prepare_check_notifier_.Cancel(); |
| 319 signals_check_notifier_.Cancel(); | 319 signals_check_notifier_.Cancel(); |
| 320 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | 320 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 321 } | 321 } |
| 322 | 322 |
| 323 void TileManager::SetResources(ResourcePool* resource_pool, | 323 void TileManager::SetResources(ResourcePool* resource_pool, |
| 324 TileTaskRunner* tile_task_runner, | 324 TileTaskRunner* tile_task_runner, |
| 325 size_t scheduled_raster_task_limit) { | 325 size_t scheduled_raster_task_limit, |
| 326 bool is_using_gpu_rasterization) { |
| 326 DCHECK(!tile_task_runner_); | 327 DCHECK(!tile_task_runner_); |
| 327 DCHECK(tile_task_runner); | 328 DCHECK(tile_task_runner); |
| 328 | 329 |
| 329 scheduled_raster_task_limit_ = scheduled_raster_task_limit; | 330 scheduled_raster_task_limit_ = scheduled_raster_task_limit; |
| 330 resource_pool_ = resource_pool; | 331 resource_pool_ = resource_pool; |
| 331 tile_task_runner_ = tile_task_runner; | 332 tile_task_runner_ = tile_task_runner; |
| 333 image_decode_controller_.SetIsUsingGpuRasterization( |
| 334 is_using_gpu_rasterization); |
| 332 } | 335 } |
| 333 | 336 |
| 334 void TileManager::Release(Tile* tile) { | 337 void TileManager::Release(Tile* tile) { |
| 335 released_tiles_.push_back(tile); | 338 released_tiles_.push_back(tile); |
| 336 } | 339 } |
| 337 | 340 |
| 338 void TileManager::FreeResourcesForReleasedTiles() { | 341 void TileManager::FreeResourcesForReleasedTiles() { |
| 339 for (auto* tile : released_tiles_) | 342 for (auto* tile : released_tiles_) |
| 340 FreeResourcesForTile(tile); | 343 FreeResourcesForTile(tile); |
| 341 } | 344 } |
| 342 | 345 |
| 343 void TileManager::CleanUpReleasedTiles() { | 346 void TileManager::CleanUpReleasedTiles() { |
| 344 std::vector<Tile*> tiles_to_retain; | 347 std::vector<Tile*> tiles_to_retain; |
| 345 for (auto* tile : released_tiles_) { | 348 for (auto* tile : released_tiles_) { |
| 346 if (tile->HasRasterTask()) { | 349 if (tile->HasRasterTask()) { |
| 347 tiles_to_retain.push_back(tile); | 350 tiles_to_retain.push_back(tile); |
| 348 continue; | 351 continue; |
| 349 } | 352 } |
| 350 | 353 |
| 351 DCHECK(!tile->draw_info().has_resource()); | 354 DCHECK(!tile->draw_info().has_resource()); |
| 352 DCHECK(tiles_.find(tile->id()) != tiles_.end()); | 355 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 353 tiles_.erase(tile->id()); | 356 tiles_.erase(tile->id()); |
| 354 | 357 |
| 355 image_decode_controller_.SubtractLayerUsedCount(tile->layer_id()); | |
| 356 delete tile; | 358 delete tile; |
| 357 } | 359 } |
| 358 released_tiles_.swap(tiles_to_retain); | 360 released_tiles_.swap(tiles_to_retain); |
| 359 } | 361 } |
| 360 | 362 |
| 361 void TileManager::DidFinishRunningTileTasksRequiredForActivation() { | 363 void TileManager::DidFinishRunningTileTasksRequiredForActivation() { |
| 362 TRACE_EVENT0("cc", | 364 TRACE_EVENT0("cc", |
| 363 "TileManager::DidFinishRunningTileTasksRequiredForActivation"); | 365 "TileManager::DidFinishRunningTileTasksRequiredForActivation"); |
| 364 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", | 366 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", |
| 365 ScheduledTasksStateAsValue()); | 367 ScheduledTasksStateAsValue()); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 CreateTaskSetFinishedTask(&TileManager::DidFinishRunningAllTileTasks); | 717 CreateTaskSetFinishedTask(&TileManager::DidFinishRunningAllTileTasks); |
| 716 | 718 |
| 717 // Build a new task queue containing all task currently needed. Tasks | 719 // Build a new task queue containing all task currently needed. Tasks |
| 718 // are added in order of priority, highest priority task first. | 720 // are added in order of priority, highest priority task first. |
| 719 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { | 721 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { |
| 720 Tile* tile = prioritized_tile.tile(); | 722 Tile* tile = prioritized_tile.tile(); |
| 721 | 723 |
| 722 DCHECK(tile->draw_info().requires_resource()); | 724 DCHECK(tile->draw_info().requires_resource()); |
| 723 DCHECK(!tile->draw_info().resource_); | 725 DCHECK(!tile->draw_info().resource_); |
| 724 | 726 |
| 725 if (!tile->raster_task_) { | 727 if (!tile->raster_task_) |
| 726 tile->raster_task_ = CreateRasterTask(prioritized_tile); | 728 tile->raster_task_ = CreateRasterTask(prioritized_tile); |
| 727 } | |
| 728 | 729 |
| 729 RasterTask* task = tile->raster_task_.get(); | 730 RasterTask* task = tile->raster_task_.get(); |
| 730 DCHECK(!task->HasCompleted()); | 731 DCHECK(!task->HasCompleted()); |
| 731 | 732 |
| 732 if (!tile->raster_task_.get()) | |
| 733 tile->raster_task_ = CreateRasterTask(prioritized_tile); | |
| 734 | |
| 735 if (tile->required_for_activation()) { | 733 if (tile->required_for_activation()) { |
| 736 required_for_activate_count++; | 734 required_for_activate_count++; |
| 737 graph_.edges.push_back( | 735 graph_.edges.push_back( |
| 738 TaskGraph::Edge(task, required_for_activation_done_task.get())); | 736 TaskGraph::Edge(task, required_for_activation_done_task.get())); |
| 739 } | 737 } |
| 740 if (tile->required_for_draw()) { | 738 if (tile->required_for_draw()) { |
| 741 required_for_draw_count++; | 739 required_for_draw_count++; |
| 742 graph_.edges.push_back( | 740 graph_.edges.push_back( |
| 743 TaskGraph::Edge(task, required_for_draw_done_task.get())); | 741 TaskGraph::Edge(task, required_for_draw_done_task.get())); |
| 744 } | 742 } |
| 745 all_count++; | 743 all_count++; |
| 746 graph_.edges.push_back(TaskGraph::Edge(task, all_done_task.get())); | 744 graph_.edges.push_back(TaskGraph::Edge(task, all_done_task.get())); |
| 747 | 745 |
| 748 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); | 746 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); |
| 749 } | 747 } |
| 750 | 748 |
| 751 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), | 749 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), |
| 752 kRequiredForActivationDoneTaskPriority, | 750 kRequiredForActivationDoneTaskPriority, |
| 753 required_for_activate_count); | 751 required_for_activate_count); |
| 754 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), | 752 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), |
| 755 kRequiredForDrawDoneTaskPriority, required_for_draw_count); | 753 kRequiredForDrawDoneTaskPriority, required_for_draw_count); |
| 756 InsertNodeForTask(&graph_, all_done_task.get(), kAllDoneTaskPriority, | 754 InsertNodeForTask(&graph_, all_done_task.get(), kAllDoneTaskPriority, |
| 757 all_count); | 755 all_count); |
| 758 | 756 |
| 759 // We must reduce the amount of unused resoruces before calling | 757 // We must reduce the amount of unused resoruces before calling |
| 760 // ScheduleTasks to prevent usage from rising above limits. | 758 // ScheduleTasks to prevent usage from rising above limits. |
| 761 resource_pool_->ReduceResourceUsage(); | 759 resource_pool_->ReduceResourceUsage(); |
| 760 image_decode_controller_.ReduceCacheUsage(); |
| 762 | 761 |
| 763 // Schedule running of |raster_queue_|. This replaces any previously | 762 // Schedule running of |raster_queue_|. This replaces any previously |
| 764 // scheduled tasks and effectively cancels all tasks not present | 763 // scheduled tasks and effectively cancels all tasks not present |
| 765 // in |raster_queue_|. | 764 // in |raster_queue_|. |
| 766 tile_task_runner_->ScheduleTasks(&graph_); | 765 tile_task_runner_->ScheduleTasks(&graph_); |
| 767 | 766 |
| 768 // It's now safe to clean up orphan tasks as raster worker pool is not | 767 // It's now safe to clean up orphan tasks as raster worker pool is not |
| 769 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has | 768 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has |
| 770 // been called. | 769 // been called. |
| 771 orphan_tasks_.clear(); | 770 orphan_tasks_.clear(); |
| 772 | 771 |
| 773 // It's also now safe to replace our *_done_task_ tasks. | 772 // It's also now safe to replace our *_done_task_ tasks. |
| 774 required_for_activation_done_task_ = | 773 required_for_activation_done_task_ = |
| 775 std::move(required_for_activation_done_task); | 774 std::move(required_for_activation_done_task); |
| 776 required_for_draw_done_task_ = std::move(required_for_draw_done_task); | 775 required_for_draw_done_task_ = std::move(required_for_draw_done_task); |
| 777 all_done_task_ = std::move(all_done_task); | 776 all_done_task_ = std::move(all_done_task); |
| 778 | 777 |
| 779 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; | 778 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; |
| 780 | 779 |
| 781 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", | 780 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", |
| 782 ScheduledTasksStateAsValue()); | 781 ScheduledTasksStateAsValue()); |
| 783 } | 782 } |
| 784 | 783 |
| 785 scoped_refptr<RasterTask> TileManager::CreateRasterTask( | 784 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
| 786 const PrioritizedTile& prioritized_tile) { | 785 const PrioritizedTile& prioritized_tile) { |
| 787 Tile* tile = prioritized_tile.tile(); | 786 Tile* tile = prioritized_tile.tile(); |
| 787 |
| 788 // Get the resource. |
| 788 uint64_t resource_content_id = 0; | 789 uint64_t resource_content_id = 0; |
| 789 Resource* resource = nullptr; | 790 Resource* resource = nullptr; |
| 790 if (use_partial_raster_ && tile->invalidated_id()) { | 791 if (use_partial_raster_ && tile->invalidated_id()) { |
| 791 // TODO(danakj): For resources that are in use, we should still grab them | 792 // TODO(danakj): For resources that are in use, we should still grab them |
| 792 // and copy from them instead of rastering everything. crbug.com/492754 | 793 // and copy from them instead of rastering everything. crbug.com/492754 |
| 793 resource = | 794 resource = |
| 794 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); | 795 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); |
| 795 } | 796 } |
| 796 if (resource) { | 797 if (resource) { |
| 797 resource_content_id = tile->invalidated_id(); | 798 resource_content_id = tile->invalidated_id(); |
| 798 DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); | 799 DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); |
| 799 DCHECK_EQ(tile->desired_texture_size().ToString(), | 800 DCHECK_EQ(tile->desired_texture_size().ToString(), |
| 800 resource->size().ToString()); | 801 resource->size().ToString()); |
| 801 } else { | 802 } else { |
| 802 resource = resource_pool_->AcquireResource(tile->desired_texture_size(), | 803 resource = resource_pool_->AcquireResource(tile->desired_texture_size(), |
| 803 DetermineResourceFormat(tile)); | 804 DetermineResourceFormat(tile)); |
| 804 } | 805 } |
| 805 | 806 |
| 806 // Create and queue all image decode tasks that this tile depends on. | 807 // Create and queue all image decode tasks that this tile depends on. |
| 807 ImageDecodeTask::Vector decode_tasks; | 808 ImageDecodeTask::Vector decode_tasks; |
| 808 std::vector<DrawImage> images; | 809 std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; |
| 810 images.clear(); |
| 809 prioritized_tile.raster_source()->GetDiscardableImagesInRect( | 811 prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
| 810 tile->enclosing_layer_rect(), tile->contents_scale(), &images); | 812 tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
| 811 for (const auto& image : images) { | 813 for (auto it = images.begin(); it != images.end();) { |
| 812 decode_tasks.push_back(image_decode_controller_.GetTaskForImage( | 814 scoped_refptr<ImageDecodeTask> task; |
| 813 image, tile->layer_id(), prepare_tiles_count_)); | 815 bool need_to_unref_when_finished = |
| 816 image_decode_controller_.GetTaskForImageAndRef( |
| 817 *it, prepare_tiles_count_, &task); |
| 818 if (task) |
| 819 decode_tasks.push_back(task); |
| 820 |
| 821 if (need_to_unref_when_finished) |
| 822 ++it; |
| 823 else |
| 824 it = images.erase(it); |
| 814 } | 825 } |
| 815 | 826 |
| 816 return make_scoped_refptr(new RasterTaskImpl( | 827 return make_scoped_refptr(new RasterTaskImpl( |
| 817 resource, prioritized_tile.raster_source(), tile->content_rect(), | 828 resource, prioritized_tile.raster_source(), tile->content_rect(), |
| 818 tile->invalidated_content_rect(), tile->contents_scale(), | 829 tile->invalidated_content_rect(), tile->contents_scale(), |
| 819 prioritized_tile.priority().resolution, tile->layer_id(), | 830 prioritized_tile.priority().resolution, tile->layer_id(), |
| 820 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), | 831 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), |
| 821 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), | 832 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), |
| 822 tile->use_picture_analysis(), | 833 tile->use_picture_analysis(), |
| 823 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 834 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
| 824 tile->id(), resource), | 835 tile->id(), resource), |
| 825 &decode_tasks)); | 836 &decode_tasks)); |
| 826 } | 837 } |
| 827 | 838 |
| 828 void TileManager::OnRasterTaskCompleted( | 839 void TileManager::OnRasterTaskCompleted( |
| 829 Tile::Id tile_id, | 840 Tile::Id tile_id, |
| 830 Resource* resource, | 841 Resource* resource, |
| 831 const DisplayListRasterSource::SolidColorAnalysis& analysis, | 842 const DisplayListRasterSource::SolidColorAnalysis& analysis, |
| 832 bool was_canceled) { | 843 bool was_canceled) { |
| 833 DCHECK(tiles_.find(tile_id) != tiles_.end()); | 844 DCHECK(tiles_.find(tile_id) != tiles_.end()); |
| 834 | 845 |
| 835 Tile* tile = tiles_[tile_id]; | 846 Tile* tile = tiles_[tile_id]; |
| 836 DCHECK(tile->raster_task_.get()); | 847 DCHECK(tile->raster_task_.get()); |
| 837 orphan_tasks_.push_back(tile->raster_task_); | 848 orphan_tasks_.push_back(tile->raster_task_); |
| 838 tile->raster_task_ = nullptr; | 849 tile->raster_task_ = nullptr; |
| 839 | 850 |
| 851 // Unref all the images. |
| 852 auto images_it = scheduled_draw_images_.find(tile->id()); |
| 853 const std::vector<DrawImage>& images = images_it->second; |
| 854 for (const auto& image : images) |
| 855 image_decode_controller_.UnrefImage(image); |
| 856 scheduled_draw_images_.erase(images_it); |
| 857 |
| 840 if (was_canceled) { | 858 if (was_canceled) { |
| 841 ++flush_stats_.canceled_count; | 859 ++flush_stats_.canceled_count; |
| 842 // TODO(ericrk): If more partial raster work is done in the future, it may | 860 // TODO(ericrk): If more partial raster work is done in the future, it may |
| 843 // be worth returning the resource to the pool with its previous ID (not | 861 // be worth returning the resource to the pool with its previous ID (not |
| 844 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method | 862 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method |
| 845 // of achieving this. | 863 // of achieving this. |
| 846 resource_pool_->ReleaseResource(resource, 0 /* content_id */); | 864 resource_pool_->ReleaseResource(resource, 0 /* content_id */); |
| 847 return; | 865 return; |
| 848 } | 866 } |
| 849 | 867 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 int source_frame_number, | 902 int source_frame_number, |
| 885 int flags) { | 903 int flags) { |
| 886 // We need to have a tile task worker pool to do anything meaningful with | 904 // We need to have a tile task worker pool to do anything meaningful with |
| 887 // tiles. | 905 // tiles. |
| 888 DCHECK(tile_task_runner_); | 906 DCHECK(tile_task_runner_); |
| 889 ScopedTilePtr tile( | 907 ScopedTilePtr tile( |
| 890 new Tile(this, info, layer_id, source_frame_number, flags)); | 908 new Tile(this, info, layer_id, source_frame_number, flags)); |
| 891 DCHECK(tiles_.find(tile->id()) == tiles_.end()); | 909 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 892 | 910 |
| 893 tiles_[tile->id()] = tile.get(); | 911 tiles_[tile->id()] = tile.get(); |
| 894 image_decode_controller_.AddLayerUsedCount(tile->layer_id()); | |
| 895 return tile; | 912 return tile; |
| 896 } | 913 } |
| 897 | 914 |
| 898 void TileManager::SetTileTaskRunnerForTesting( | 915 void TileManager::SetTileTaskRunnerForTesting( |
| 899 TileTaskRunner* tile_task_runner) { | 916 TileTaskRunner* tile_task_runner) { |
| 900 tile_task_runner_ = tile_task_runner; | 917 tile_task_runner_ = tile_task_runner; |
| 901 } | 918 } |
| 902 | 919 |
| 903 bool TileManager::AreRequiredTilesReadyToDraw( | 920 bool TileManager::AreRequiredTilesReadyToDraw( |
| 904 RasterTilePriorityQueue::Type type) const { | 921 RasterTilePriorityQueue::Type type) const { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 1017 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 1001 // steady memory state. Keep scheduling tasks until we reach this state. | 1018 // steady memory state. Keep scheduling tasks until we reach this state. |
| 1002 if (!tiles_that_need_to_be_rasterized.empty()) { | 1019 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 1003 ScheduleTasks(tiles_that_need_to_be_rasterized); | 1020 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 1004 return; | 1021 return; |
| 1005 } | 1022 } |
| 1006 | 1023 |
| 1007 FreeResourcesForReleasedTiles(); | 1024 FreeResourcesForReleasedTiles(); |
| 1008 | 1025 |
| 1009 resource_pool_->ReduceResourceUsage(); | 1026 resource_pool_->ReduceResourceUsage(); |
| 1027 image_decode_controller_.ReduceCacheUsage(); |
| 1010 | 1028 |
| 1011 signals_.all_tile_tasks_completed = true; | 1029 signals_.all_tile_tasks_completed = true; |
| 1012 signals_check_notifier_.Schedule(); | 1030 signals_check_notifier_.Schedule(); |
| 1013 | 1031 |
| 1014 // We don't reserve memory for required-for-activation tiles during | 1032 // We don't reserve memory for required-for-activation tiles during |
| 1015 // accelerated gestures, so we just postpone activation when we don't | 1033 // accelerated gestures, so we just postpone activation when we don't |
| 1016 // have these tiles, and activate after the accelerated gesture. | 1034 // have these tiles, and activate after the accelerated gesture. |
| 1017 // Likewise if we don't allow any tiles (as is the case when we're | 1035 // Likewise if we don't allow any tiles (as is the case when we're |
| 1018 // invisible), if we have tiles that aren't ready, then we shouldn't | 1036 // invisible), if we have tiles that aren't ready, then we shouldn't |
| 1019 // activate as activation can cause checkerboards. | 1037 // activate as activation can cause checkerboards. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 void TileManager::Signals::reset() { | 1182 void TileManager::Signals::reset() { |
| 1165 ready_to_activate = false; | 1183 ready_to_activate = false; |
| 1166 did_notify_ready_to_activate = false; | 1184 did_notify_ready_to_activate = false; |
| 1167 ready_to_draw = false; | 1185 ready_to_draw = false; |
| 1168 did_notify_ready_to_draw = false; | 1186 did_notify_ready_to_draw = false; |
| 1169 all_tile_tasks_completed = false; | 1187 all_tile_tasks_completed = false; |
| 1170 did_notify_all_tile_tasks_completed = false; | 1188 did_notify_all_tile_tasks_completed = false; |
| 1171 } | 1189 } |
| 1172 | 1190 |
| 1173 } // namespace cc | 1191 } // namespace cc |
| OLD | NEW |