| 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 |