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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 | 354 |
355 FreeResourcesForReleasedTiles(); | 355 FreeResourcesForReleasedTiles(); |
356 CleanUpReleasedTiles(); | 356 CleanUpReleasedTiles(); |
357 | 357 |
358 tile_task_manager_ = nullptr; | 358 tile_task_manager_ = nullptr; |
359 resource_pool_ = nullptr; | 359 resource_pool_ = nullptr; |
360 more_tiles_need_prepare_check_notifier_.Cancel(); | 360 more_tiles_need_prepare_check_notifier_.Cancel(); |
361 signals_check_notifier_.Cancel(); | 361 signals_check_notifier_.Cancel(); |
362 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | 362 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); |
363 | 363 |
364 for (auto& draw_image_pair : locked_images_) | 364 image_manager_.UnrefImages(locked_images_); |
365 image_decode_controller_->UnrefImage(draw_image_pair.first); | |
366 locked_images_.clear(); | 365 locked_images_.clear(); |
| 366 locked_image_tasks_.clear(); |
367 } | 367 } |
368 | 368 |
369 void TileManager::SetResources(ResourcePool* resource_pool, | 369 void TileManager::SetResources(ResourcePool* resource_pool, |
370 ImageDecodeController* image_decode_controller, | 370 ImageDecodeController* image_decode_controller, |
371 TileTaskManager* tile_task_manager, | 371 TileTaskManager* tile_task_manager, |
372 RasterBufferProvider* raster_buffer_provider, | 372 RasterBufferProvider* raster_buffer_provider, |
373 size_t scheduled_raster_task_limit, | 373 size_t scheduled_raster_task_limit, |
374 bool use_gpu_rasterization) { | 374 bool use_gpu_rasterization) { |
375 DCHECK(!tile_task_manager_); | 375 DCHECK(!tile_task_manager_); |
376 DCHECK(tile_task_manager); | 376 DCHECK(tile_task_manager); |
377 | 377 |
378 use_gpu_rasterization_ = use_gpu_rasterization; | 378 use_gpu_rasterization_ = use_gpu_rasterization; |
379 scheduled_raster_task_limit_ = scheduled_raster_task_limit; | 379 scheduled_raster_task_limit_ = scheduled_raster_task_limit; |
380 resource_pool_ = resource_pool; | 380 resource_pool_ = resource_pool; |
381 image_decode_controller_ = image_decode_controller; | 381 image_manager_.SetImageDecodeController(image_decode_controller); |
382 tile_task_manager_ = tile_task_manager; | 382 tile_task_manager_ = tile_task_manager; |
383 raster_buffer_provider_ = raster_buffer_provider; | 383 raster_buffer_provider_ = raster_buffer_provider; |
384 } | 384 } |
385 | 385 |
386 void TileManager::Release(Tile* tile) { | 386 void TileManager::Release(Tile* tile) { |
387 released_tiles_.push_back(tile); | 387 released_tiles_.push_back(tile); |
388 } | 388 } |
389 | 389 |
390 void TileManager::FreeResourcesForReleasedTiles() { | 390 void TileManager::FreeResourcesForReleasedTiles() { |
391 for (auto* tile : released_tiles_) | 391 for (auto* tile : released_tiles_) |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 // it has a priority bin of NOW for another reason (low resolution tiles). | 829 // it has a priority bin of NOW for another reason (low resolution tiles). |
830 bool use_foreground_category = | 830 bool use_foreground_category = |
831 tile->required_for_draw() || tile->required_for_activation() || | 831 tile->required_for_draw() || tile->required_for_activation() || |
832 prioritized_tile.priority().priority_bin == TilePriority::NOW; | 832 prioritized_tile.priority().priority_bin == TilePriority::NOW; |
833 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, | 833 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++, |
834 use_foreground_category); | 834 use_foreground_category); |
835 } | 835 } |
836 | 836 |
837 const std::vector<PrioritizedTile>& tiles_to_process_for_images = | 837 const std::vector<PrioritizedTile>& tiles_to_process_for_images = |
838 work_to_schedule.tiles_to_process_for_images; | 838 work_to_schedule.tiles_to_process_for_images; |
839 std::vector<std::pair<DrawImage, scoped_refptr<TileTask>>> new_locked_images; | 839 std::vector<DrawImage> new_locked_images; |
| 840 std::vector<scoped_refptr<TileTask>> new_locked_image_tasks; |
840 for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) { | 841 for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) { |
841 Tile* tile = prioritized_tile.tile(); | 842 Tile* tile = prioritized_tile.tile(); |
842 | 843 |
843 std::vector<DrawImage> images; | 844 std::vector<DrawImage> images; |
844 prioritized_tile.raster_source()->GetDiscardableImagesInRect( | 845 prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
845 tile->enclosing_layer_rect(), tile->contents_scale(), &images); | 846 tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
846 ImageDecodeController::TracingInfo tracing_info( | 847 ImageDecodeController::TracingInfo tracing_info( |
847 prepare_tiles_count_, prioritized_tile.priority().priority_bin); | 848 prepare_tiles_count_, prioritized_tile.priority().priority_bin); |
848 for (DrawImage& draw_image : images) { | 849 image_manager_.GetTasksForImagesAndRef(&images, &new_locked_image_tasks, |
849 scoped_refptr<TileTask> task; | 850 tracing_info); |
850 bool need_to_unref_when_finished = | 851 new_locked_images.insert(new_locked_images.end(), images.begin(), |
851 image_decode_controller_->GetTaskForImageAndRef(draw_image, | 852 images.end()); |
852 tracing_info, &task); | |
853 // We only care about images that need to be locked (ie they need to be | |
854 // unreffed later). | |
855 if (!need_to_unref_when_finished) | |
856 continue; | |
857 new_locked_images.emplace_back(draw_image, task); | |
858 | |
859 // If there's no actual task associated with this image, then we're done. | |
860 if (!task) | |
861 continue; | |
862 | |
863 auto decode_it = std::find_if(graph_.nodes.begin(), graph_.nodes.end(), | |
864 [&task](const TaskGraph::Node& node) { | |
865 return node.task == task.get(); | |
866 }); | |
867 // If this task is already in the graph, then we don't have to insert it. | |
868 if (decode_it != graph_.nodes.end()) | |
869 continue; | |
870 | |
871 InsertNodeForDecodeTask(&graph_, task.get(), false, priority++); | |
872 all_count++; | |
873 graph_.edges.push_back(TaskGraph::Edge(task.get(), all_done_task.get())); | |
874 } | |
875 } | 853 } |
876 | 854 |
877 for (auto& draw_image_pair : locked_images_) | 855 for (auto& task : new_locked_image_tasks) { |
878 image_decode_controller_->UnrefImage(draw_image_pair.first); | 856 auto decode_it = std::find_if(graph_.nodes.begin(), graph_.nodes.end(), |
| 857 [&task](const TaskGraph::Node& node) { |
| 858 return node.task == task.get(); |
| 859 }); |
| 860 // If this task is already in the graph, then we don't have to insert it. |
| 861 if (decode_it != graph_.nodes.end()) |
| 862 continue; |
| 863 |
| 864 InsertNodeForDecodeTask(&graph_, task.get(), false, priority++); |
| 865 all_count++; |
| 866 graph_.edges.push_back(TaskGraph::Edge(task.get(), all_done_task.get())); |
| 867 } |
| 868 |
| 869 image_manager_.UnrefImages(locked_images_); |
879 // The old locked images have to stay around until past the ScheduleTasks call | 870 // The old locked images have to stay around until past the ScheduleTasks call |
880 // below, so we do a swap instead of a move. | 871 // below, so we do a swap instead of a move. |
881 locked_images_.swap(new_locked_images); | 872 locked_images_.swap(new_locked_images); |
| 873 locked_image_tasks_.swap(new_locked_image_tasks); |
882 | 874 |
883 // We must reduce the amount of unused resources before calling | 875 // We must reduce the amount of unused resources before calling |
884 // ScheduleTasks to prevent usage from rising above limits. | 876 // ScheduleTasks to prevent usage from rising above limits. |
885 resource_pool_->ReduceResourceUsage(); | 877 resource_pool_->ReduceResourceUsage(); |
886 image_decode_controller_->ReduceCacheUsage(); | 878 image_manager_.ReduceMemoryUsage(); |
887 | 879 |
888 // Insert nodes for our task completion tasks. We enqueue these using | 880 // Insert nodes for our task completion tasks. We enqueue these using |
889 // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and | 881 // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and |
890 // we'd like to run these tasks as soon as possible. | 882 // we'd like to run these tasks as soon as possible. |
891 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), | 883 InsertNodeForTask(&graph_, required_for_activation_done_task.get(), |
892 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 884 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
893 kRequiredForActivationDoneTaskPriority, | 885 kRequiredForActivationDoneTaskPriority, |
894 required_for_activate_count); | 886 required_for_activate_count); |
895 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), | 887 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), |
896 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, | 888 TASK_CATEGORY_NONCONCURRENT_FOREGROUND, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 TileTask::Vector decode_tasks; | 948 TileTask::Vector decode_tasks; |
957 std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; | 949 std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; |
958 images.clear(); | 950 images.clear(); |
959 if (!playback_settings.skip_images) { | 951 if (!playback_settings.skip_images) { |
960 prioritized_tile.raster_source()->GetDiscardableImagesInRect( | 952 prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
961 tile->enclosing_layer_rect(), tile->contents_scale(), &images); | 953 tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
962 } | 954 } |
963 | 955 |
964 // We can skip the image hijack canvas if we have no images. | 956 // We can skip the image hijack canvas if we have no images. |
965 playback_settings.use_image_hijack_canvas = !images.empty(); | 957 playback_settings.use_image_hijack_canvas = !images.empty(); |
| 958 |
| 959 // Get the tasks for the required images. |
966 ImageDecodeController::TracingInfo tracing_info( | 960 ImageDecodeController::TracingInfo tracing_info( |
967 prepare_tiles_count_, prioritized_tile.priority().priority_bin); | 961 prepare_tiles_count_, prioritized_tile.priority().priority_bin); |
968 for (auto it = images.begin(); it != images.end();) { | 962 image_manager_.GetTasksForImagesAndRef(&images, &decode_tasks, tracing_info); |
969 scoped_refptr<TileTask> task; | |
970 bool need_to_unref_when_finished = | |
971 image_decode_controller_->GetTaskForImageAndRef(*it, tracing_info, | |
972 &task); | |
973 if (task) | |
974 decode_tasks.push_back(task); | |
975 | 963 |
976 if (need_to_unref_when_finished) | |
977 ++it; | |
978 else | |
979 it = images.erase(it); | |
980 } | |
981 bool supports_concurrent_execution = !use_gpu_rasterization_; | 964 bool supports_concurrent_execution = !use_gpu_rasterization_; |
982 std::unique_ptr<RasterBuffer> raster_buffer = | 965 std::unique_ptr<RasterBuffer> raster_buffer = |
983 raster_buffer_provider_->AcquireBufferForRaster( | 966 raster_buffer_provider_->AcquireBufferForRaster( |
984 resource, resource_content_id, tile->invalidated_id()); | 967 resource, resource_content_id, tile->invalidated_id()); |
985 return make_scoped_refptr(new RasterTaskImpl( | 968 return make_scoped_refptr(new RasterTaskImpl( |
986 this, tile, resource, prioritized_tile.raster_source(), playback_settings, | 969 this, tile, resource, prioritized_tile.raster_source(), playback_settings, |
987 prioritized_tile.priority().resolution, invalidated_rect, | 970 prioritized_tile.priority().resolution, invalidated_rect, |
988 prepare_tiles_count_, std::move(raster_buffer), &decode_tasks, | 971 prepare_tiles_count_, std::move(raster_buffer), &decode_tasks, |
989 supports_concurrent_execution)); | 972 supports_concurrent_execution)); |
990 } | 973 } |
991 | 974 |
992 void TileManager::OnRasterTaskCompleted( | 975 void TileManager::OnRasterTaskCompleted( |
993 std::unique_ptr<RasterBuffer> raster_buffer, | 976 std::unique_ptr<RasterBuffer> raster_buffer, |
994 Tile* tile, | 977 Tile* tile, |
995 Resource* resource, | 978 Resource* resource, |
996 bool was_canceled) { | 979 bool was_canceled) { |
997 DCHECK(tile); | 980 DCHECK(tile); |
998 DCHECK(tiles_.find(tile->id()) != tiles_.end()); | 981 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
999 raster_buffer_provider_->ReleaseBufferForRaster(std::move(raster_buffer)); | 982 raster_buffer_provider_->ReleaseBufferForRaster(std::move(raster_buffer)); |
1000 | 983 |
1001 TileDrawInfo& draw_info = tile->draw_info(); | 984 TileDrawInfo& draw_info = tile->draw_info(); |
1002 DCHECK(tile->raster_task_.get()); | 985 DCHECK(tile->raster_task_.get()); |
1003 orphan_tasks_.push_back(tile->raster_task_); | 986 orphan_tasks_.push_back(tile->raster_task_); |
1004 tile->raster_task_ = nullptr; | 987 tile->raster_task_ = nullptr; |
1005 | 988 |
1006 // Unref all the images. | 989 // Unref all the images. |
1007 auto images_it = scheduled_draw_images_.find(tile->id()); | 990 auto images_it = scheduled_draw_images_.find(tile->id()); |
1008 const std::vector<DrawImage>& images = images_it->second; | 991 const std::vector<DrawImage>& images = images_it->second; |
1009 for (const auto& image : images) | 992 image_manager_.UnrefImages(images); |
1010 image_decode_controller_->UnrefImage(image); | |
1011 scheduled_draw_images_.erase(images_it); | 993 scheduled_draw_images_.erase(images_it); |
1012 | 994 |
1013 if (was_canceled) { | 995 if (was_canceled) { |
1014 ++flush_stats_.canceled_count; | 996 ++flush_stats_.canceled_count; |
1015 resource_pool_->ReleaseResource(resource); | 997 resource_pool_->ReleaseResource(resource); |
1016 return; | 998 return; |
1017 } | 999 } |
1018 | 1000 |
1019 resource_pool_->OnContentReplaced(resource->id(), tile->id()); | 1001 resource_pool_->OnContentReplaced(resource->id(), tile->id()); |
1020 ++flush_stats_.completed_count; | 1002 ++flush_stats_.completed_count; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 1132 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
1151 // steady memory state. Keep scheduling tasks until we reach this state. | 1133 // steady memory state. Keep scheduling tasks until we reach this state. |
1152 if (!work_to_schedule.tiles_to_raster.empty()) { | 1134 if (!work_to_schedule.tiles_to_raster.empty()) { |
1153 ScheduleTasks(work_to_schedule); | 1135 ScheduleTasks(work_to_schedule); |
1154 return; | 1136 return; |
1155 } | 1137 } |
1156 | 1138 |
1157 // If we're not in SMOOTHNESS_TAKES_PRIORITY mode, we should unlock all | 1139 // If we're not in SMOOTHNESS_TAKES_PRIORITY mode, we should unlock all |
1158 // images since we're technically going idle here at least for this frame. | 1140 // images since we're technically going idle here at least for this frame. |
1159 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) { | 1141 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) { |
1160 for (auto& draw_image_pair : locked_images_) | 1142 image_manager_.UnrefImages(locked_images_); |
1161 image_decode_controller_->UnrefImage(draw_image_pair.first); | |
1162 locked_images_.clear(); | 1143 locked_images_.clear(); |
| 1144 locked_image_tasks_.clear(); |
1163 } | 1145 } |
1164 | 1146 |
1165 FreeResourcesForReleasedTiles(); | 1147 FreeResourcesForReleasedTiles(); |
1166 | 1148 |
1167 resource_pool_->ReduceResourceUsage(); | 1149 resource_pool_->ReduceResourceUsage(); |
1168 image_decode_controller_->ReduceCacheUsage(); | 1150 image_manager_.ReduceMemoryUsage(); |
1169 | 1151 |
1170 signals_.all_tile_tasks_completed = true; | 1152 signals_.all_tile_tasks_completed = true; |
1171 signals_check_notifier_.Schedule(); | 1153 signals_check_notifier_.Schedule(); |
1172 | 1154 |
1173 // We don't reserve memory for required-for-activation tiles during | 1155 // We don't reserve memory for required-for-activation tiles during |
1174 // accelerated gestures, so we just postpone activation when we don't | 1156 // accelerated gestures, so we just postpone activation when we don't |
1175 // have these tiles, and activate after the accelerated gesture. | 1157 // have these tiles, and activate after the accelerated gesture. |
1176 // Likewise if we don't allow any tiles (as is the case when we're | 1158 // Likewise if we don't allow any tiles (as is the case when we're |
1177 // invisible), if we have tiles that aren't ready, then we shouldn't | 1159 // invisible), if we have tiles that aren't ready, then we shouldn't |
1178 // activate as activation can cause checkerboards. | 1160 // activate as activation can cause checkerboards. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 all_tile_tasks_completed = false; | 1314 all_tile_tasks_completed = false; |
1333 did_notify_all_tile_tasks_completed = false; | 1315 did_notify_all_tile_tasks_completed = false; |
1334 } | 1316 } |
1335 | 1317 |
1336 TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule() = default; | 1318 TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule() = default; |
1337 TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule( | 1319 TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule( |
1338 PrioritizedWorkToSchedule&& other) = default; | 1320 PrioritizedWorkToSchedule&& other) = default; |
1339 TileManager::PrioritizedWorkToSchedule::~PrioritizedWorkToSchedule() = default; | 1321 TileManager::PrioritizedWorkToSchedule::~PrioritizedWorkToSchedule() = default; |
1340 | 1322 |
1341 } // namespace cc | 1323 } // namespace cc |
OLD | NEW |