Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(572)

Side by Side Diff: cc/tiles/tile_manager.cc

Issue 2339703005: cc: Add ImageManager to keep all the image locking in the same place. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« cc/tiles/image_manager.cc ('K') | « cc/tiles/tile_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« cc/tiles/image_manager.cc ('K') | « cc/tiles/tile_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698