| 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 TileTaskRunner* tile_task_runner, | 335 TileTaskRunner* tile_task_runner, |
| 336 size_t scheduled_raster_task_limit, | 336 size_t scheduled_raster_task_limit, |
| 337 bool use_gpu_rasterization) { | 337 bool use_gpu_rasterization) { |
| 338 DCHECK(!tile_task_runner_); | 338 DCHECK(!tile_task_runner_); |
| 339 DCHECK(tile_task_runner); | 339 DCHECK(tile_task_runner); |
| 340 | 340 |
| 341 use_gpu_rasterization_ = use_gpu_rasterization; | 341 use_gpu_rasterization_ = use_gpu_rasterization; |
| 342 scheduled_raster_task_limit_ = scheduled_raster_task_limit; | 342 scheduled_raster_task_limit_ = scheduled_raster_task_limit; |
| 343 resource_pool_ = resource_pool; | 343 resource_pool_ = resource_pool; |
| 344 tile_task_runner_ = tile_task_runner; | 344 tile_task_runner_ = tile_task_runner; |
| 345 image_decode_controller_.SetIsUsingGpuRasterization(use_gpu_rasterization_); |
| 345 } | 346 } |
| 346 | 347 |
| 347 void TileManager::Release(Tile* tile) { | 348 void TileManager::Release(Tile* tile) { |
| 348 released_tiles_.push_back(tile); | 349 released_tiles_.push_back(tile); |
| 349 } | 350 } |
| 350 | 351 |
| 351 void TileManager::FreeResourcesForReleasedTiles() { | 352 void TileManager::FreeResourcesForReleasedTiles() { |
| 352 for (auto* tile : released_tiles_) | 353 for (auto* tile : released_tiles_) |
| 353 FreeResourcesForTile(tile); | 354 FreeResourcesForTile(tile); |
| 354 } | 355 } |
| 355 | 356 |
| 356 void TileManager::CleanUpReleasedTiles() { | 357 void TileManager::CleanUpReleasedTiles() { |
| 357 std::vector<Tile*> tiles_to_retain; | 358 std::vector<Tile*> tiles_to_retain; |
| 358 for (auto* tile : released_tiles_) { | 359 for (auto* tile : released_tiles_) { |
| 359 if (tile->HasRasterTask()) { | 360 if (tile->HasRasterTask()) { |
| 360 tiles_to_retain.push_back(tile); | 361 tiles_to_retain.push_back(tile); |
| 361 continue; | 362 continue; |
| 362 } | 363 } |
| 363 | 364 |
| 364 DCHECK(!tile->draw_info().has_resource()); | 365 DCHECK(!tile->draw_info().has_resource()); |
| 365 DCHECK(tiles_.find(tile->id()) != tiles_.end()); | 366 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 366 tiles_.erase(tile->id()); | 367 tiles_.erase(tile->id()); |
| 367 | 368 |
| 368 image_decode_controller_.SubtractLayerUsedCount(tile->layer_id()); | |
| 369 delete tile; | 369 delete tile; |
| 370 } | 370 } |
| 371 released_tiles_.swap(tiles_to_retain); | 371 released_tiles_.swap(tiles_to_retain); |
| 372 } | 372 } |
| 373 | 373 |
| 374 void TileManager::DidFinishRunningTileTasksRequiredForActivation() { | 374 void TileManager::DidFinishRunningTileTasksRequiredForActivation() { |
| 375 TRACE_EVENT0("cc", | 375 TRACE_EVENT0("cc", |
| 376 "TileManager::DidFinishRunningTileTasksRequiredForActivation"); | 376 "TileManager::DidFinishRunningTileTasksRequiredForActivation"); |
| 377 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", | 377 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", |
| 378 ScheduledTasksStateAsValue()); | 378 ScheduledTasksStateAsValue()); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 CreateTaskSetFinishedTask(&TileManager::DidFinishRunningAllTileTasks); | 745 CreateTaskSetFinishedTask(&TileManager::DidFinishRunningAllTileTasks); |
| 746 | 746 |
| 747 // Build a new task queue containing all task currently needed. Tasks | 747 // Build a new task queue containing all task currently needed. Tasks |
| 748 // are added in order of priority, highest priority task first. | 748 // are added in order of priority, highest priority task first. |
| 749 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { | 749 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { |
| 750 Tile* tile = prioritized_tile.tile(); | 750 Tile* tile = prioritized_tile.tile(); |
| 751 | 751 |
| 752 DCHECK(tile->draw_info().requires_resource()); | 752 DCHECK(tile->draw_info().requires_resource()); |
| 753 DCHECK(!tile->draw_info().resource_); | 753 DCHECK(!tile->draw_info().resource_); |
| 754 | 754 |
| 755 if (!tile->raster_task_) { | 755 if (!tile->raster_task_) |
| 756 tile->raster_task_ = CreateRasterTask(prioritized_tile); | 756 tile->raster_task_ = CreateRasterTask(prioritized_tile); |
| 757 } | |
| 758 | 757 |
| 759 RasterTask* task = tile->raster_task_.get(); | 758 RasterTask* task = tile->raster_task_.get(); |
| 760 DCHECK(!task->HasCompleted()); | 759 DCHECK(!task->HasCompleted()); |
| 761 | 760 |
| 762 if (!tile->raster_task_.get()) | |
| 763 tile->raster_task_ = CreateRasterTask(prioritized_tile); | |
| 764 | |
| 765 if (tile->required_for_activation()) { | 761 if (tile->required_for_activation()) { |
| 766 required_for_activate_count++; | 762 required_for_activate_count++; |
| 767 graph_.edges.push_back( | 763 graph_.edges.push_back( |
| 768 TaskGraph::Edge(task, required_for_activation_done_task.get())); | 764 TaskGraph::Edge(task, required_for_activation_done_task.get())); |
| 769 } | 765 } |
| 770 if (tile->required_for_draw()) { | 766 if (tile->required_for_draw()) { |
| 771 required_for_draw_count++; | 767 required_for_draw_count++; |
| 772 graph_.edges.push_back( | 768 graph_.edges.push_back( |
| 773 TaskGraph::Edge(task, required_for_draw_done_task.get())); | 769 TaskGraph::Edge(task, required_for_draw_done_task.get())); |
| 774 } | 770 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 790 required_for_activate_count); | 786 required_for_activate_count); |
| 791 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), | 787 InsertNodeForTask(&graph_, required_for_draw_done_task.get(), |
| 792 TASK_CATEGORY_FOREGROUND, kRequiredForDrawDoneTaskPriority, | 788 TASK_CATEGORY_FOREGROUND, kRequiredForDrawDoneTaskPriority, |
| 793 required_for_draw_count); | 789 required_for_draw_count); |
| 794 InsertNodeForTask(&graph_, all_done_task.get(), TASK_CATEGORY_FOREGROUND, | 790 InsertNodeForTask(&graph_, all_done_task.get(), TASK_CATEGORY_FOREGROUND, |
| 795 kAllDoneTaskPriority, all_count); | 791 kAllDoneTaskPriority, all_count); |
| 796 | 792 |
| 797 // We must reduce the amount of unused resoruces before calling | 793 // We must reduce the amount of unused resoruces before calling |
| 798 // ScheduleTasks to prevent usage from rising above limits. | 794 // ScheduleTasks to prevent usage from rising above limits. |
| 799 resource_pool_->ReduceResourceUsage(); | 795 resource_pool_->ReduceResourceUsage(); |
| 796 image_decode_controller_.ReduceCacheUsage(); |
| 800 | 797 |
| 801 // Schedule running of |raster_queue_|. This replaces any previously | 798 // Schedule running of |raster_queue_|. This replaces any previously |
| 802 // scheduled tasks and effectively cancels all tasks not present | 799 // scheduled tasks and effectively cancels all tasks not present |
| 803 // in |raster_queue_|. | 800 // in |raster_queue_|. |
| 804 tile_task_runner_->ScheduleTasks(&graph_); | 801 tile_task_runner_->ScheduleTasks(&graph_); |
| 805 | 802 |
| 806 // It's now safe to clean up orphan tasks as raster worker pool is not | 803 // It's now safe to clean up orphan tasks as raster worker pool is not |
| 807 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has | 804 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has |
| 808 // been called. | 805 // been called. |
| 809 orphan_tasks_.clear(); | 806 orphan_tasks_.clear(); |
| 810 | 807 |
| 811 // It's also now safe to replace our *_done_task_ tasks. | 808 // It's also now safe to replace our *_done_task_ tasks. |
| 812 required_for_activation_done_task_ = | 809 required_for_activation_done_task_ = |
| 813 std::move(required_for_activation_done_task); | 810 std::move(required_for_activation_done_task); |
| 814 required_for_draw_done_task_ = std::move(required_for_draw_done_task); | 811 required_for_draw_done_task_ = std::move(required_for_draw_done_task); |
| 815 all_done_task_ = std::move(all_done_task); | 812 all_done_task_ = std::move(all_done_task); |
| 816 | 813 |
| 817 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; | 814 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; |
| 818 | 815 |
| 819 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", | 816 TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state", |
| 820 ScheduledTasksStateAsValue()); | 817 ScheduledTasksStateAsValue()); |
| 821 } | 818 } |
| 822 | 819 |
| 823 scoped_refptr<RasterTask> TileManager::CreateRasterTask( | 820 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
| 824 const PrioritizedTile& prioritized_tile) { | 821 const PrioritizedTile& prioritized_tile) { |
| 825 Tile* tile = prioritized_tile.tile(); | 822 Tile* tile = prioritized_tile.tile(); |
| 823 |
| 824 // Get the resource. |
| 826 uint64_t resource_content_id = 0; | 825 uint64_t resource_content_id = 0; |
| 827 Resource* resource = nullptr; | 826 Resource* resource = nullptr; |
| 828 if (use_partial_raster_ && tile->invalidated_id()) { | 827 if (use_partial_raster_ && tile->invalidated_id()) { |
| 829 // TODO(danakj): For resources that are in use, we should still grab them | 828 // TODO(danakj): For resources that are in use, we should still grab them |
| 830 // and copy from them instead of rastering everything. crbug.com/492754 | 829 // and copy from them instead of rastering everything. crbug.com/492754 |
| 831 resource = | 830 resource = |
| 832 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); | 831 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); |
| 833 } | 832 } |
| 834 if (resource) { | 833 if (resource) { |
| 835 resource_content_id = tile->invalidated_id(); | 834 resource_content_id = tile->invalidated_id(); |
| 836 DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); | 835 DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); |
| 837 DCHECK_EQ(tile->desired_texture_size().ToString(), | 836 DCHECK_EQ(tile->desired_texture_size().ToString(), |
| 838 resource->size().ToString()); | 837 resource->size().ToString()); |
| 839 } else { | 838 } else { |
| 840 resource = resource_pool_->AcquireResource(tile->desired_texture_size(), | 839 resource = resource_pool_->AcquireResource(tile->desired_texture_size(), |
| 841 DetermineResourceFormat(tile)); | 840 DetermineResourceFormat(tile)); |
| 842 } | 841 } |
| 843 | 842 |
| 844 // Create and queue all image decode tasks that this tile depends on. | 843 // Create and queue all image decode tasks that this tile depends on. |
| 845 ImageDecodeTask::Vector decode_tasks; | 844 ImageDecodeTask::Vector decode_tasks; |
| 846 std::vector<DrawImage> images; | 845 std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; |
| 846 images.clear(); |
| 847 prioritized_tile.raster_source()->GetDiscardableImagesInRect( | 847 prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
| 848 tile->enclosing_layer_rect(), tile->contents_scale(), &images); | 848 tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
| 849 for (const auto& image : images) { | 849 for (auto it = images.begin(); it != images.end();) { |
| 850 decode_tasks.push_back(image_decode_controller_.GetTaskForImage( | 850 scoped_refptr<ImageDecodeTask> task; |
| 851 image, tile->layer_id(), prepare_tiles_count_)); | 851 bool need_to_unref_when_finished = |
| 852 image_decode_controller_.GetTaskForImageAndRef( |
| 853 *it, prepare_tiles_count_, &task); |
| 854 if (task) |
| 855 decode_tasks.push_back(task); |
| 856 |
| 857 if (need_to_unref_when_finished) |
| 858 ++it; |
| 859 else |
| 860 it = images.erase(it); |
| 852 } | 861 } |
| 853 | 862 |
| 854 return make_scoped_refptr(new RasterTaskImpl( | 863 return make_scoped_refptr(new RasterTaskImpl( |
| 855 resource, prioritized_tile.raster_source(), tile->content_rect(), | 864 resource, prioritized_tile.raster_source(), tile->content_rect(), |
| 856 tile->invalidated_content_rect(), tile->contents_scale(), | 865 tile->invalidated_content_rect(), tile->contents_scale(), |
| 857 prioritized_tile.priority().resolution, tile->layer_id(), | 866 prioritized_tile.priority().resolution, tile->layer_id(), |
| 858 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), | 867 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), |
| 859 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), | 868 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), |
| 860 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 869 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
| 861 tile->id(), resource), | 870 tile->id(), resource), |
| 862 &decode_tasks)); | 871 &decode_tasks)); |
| 863 } | 872 } |
| 864 | 873 |
| 865 void TileManager::OnRasterTaskCompleted( | 874 void TileManager::OnRasterTaskCompleted( |
| 866 Tile::Id tile_id, | 875 Tile::Id tile_id, |
| 867 Resource* resource, | 876 Resource* resource, |
| 868 bool was_canceled) { | 877 bool was_canceled) { |
| 869 DCHECK(tiles_.find(tile_id) != tiles_.end()); | 878 DCHECK(tiles_.find(tile_id) != tiles_.end()); |
| 870 | 879 |
| 871 Tile* tile = tiles_[tile_id]; | 880 Tile* tile = tiles_[tile_id]; |
| 872 TileDrawInfo& draw_info = tile->draw_info(); | 881 TileDrawInfo& draw_info = tile->draw_info(); |
| 873 DCHECK(tile->raster_task_.get()); | 882 DCHECK(tile->raster_task_.get()); |
| 874 orphan_tasks_.push_back(tile->raster_task_); | 883 orphan_tasks_.push_back(tile->raster_task_); |
| 875 tile->raster_task_ = nullptr; | 884 tile->raster_task_ = nullptr; |
| 876 | 885 |
| 886 // Unref all the images. |
| 887 auto images_it = scheduled_draw_images_.find(tile->id()); |
| 888 const std::vector<DrawImage>& images = images_it->second; |
| 889 for (const auto& image : images) |
| 890 image_decode_controller_.UnrefImage(image); |
| 891 scheduled_draw_images_.erase(images_it); |
| 892 |
| 877 if (was_canceled) { | 893 if (was_canceled) { |
| 878 ++flush_stats_.canceled_count; | 894 ++flush_stats_.canceled_count; |
| 879 // TODO(ericrk): If more partial raster work is done in the future, it may | 895 // TODO(ericrk): If more partial raster work is done in the future, it may |
| 880 // be worth returning the resource to the pool with its previous ID (not | 896 // be worth returning the resource to the pool with its previous ID (not |
| 881 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method | 897 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method |
| 882 // of achieving this. | 898 // of achieving this. |
| 883 resource_pool_->ReleaseResource(resource, 0 /* content_id */); | 899 resource_pool_->ReleaseResource(resource, 0 /* content_id */); |
| 884 return; | 900 return; |
| 885 } | 901 } |
| 886 | 902 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 901 int source_frame_number, | 917 int source_frame_number, |
| 902 int flags) { | 918 int flags) { |
| 903 // We need to have a tile task worker pool to do anything meaningful with | 919 // We need to have a tile task worker pool to do anything meaningful with |
| 904 // tiles. | 920 // tiles. |
| 905 DCHECK(tile_task_runner_); | 921 DCHECK(tile_task_runner_); |
| 906 ScopedTilePtr tile( | 922 ScopedTilePtr tile( |
| 907 new Tile(this, info, layer_id, source_frame_number, flags)); | 923 new Tile(this, info, layer_id, source_frame_number, flags)); |
| 908 DCHECK(tiles_.find(tile->id()) == tiles_.end()); | 924 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 909 | 925 |
| 910 tiles_[tile->id()] = tile.get(); | 926 tiles_[tile->id()] = tile.get(); |
| 911 image_decode_controller_.AddLayerUsedCount(tile->layer_id()); | |
| 912 return tile; | 927 return tile; |
| 913 } | 928 } |
| 914 | 929 |
| 915 void TileManager::SetTileTaskRunnerForTesting( | 930 void TileManager::SetTileTaskRunnerForTesting( |
| 916 TileTaskRunner* tile_task_runner) { | 931 TileTaskRunner* tile_task_runner) { |
| 917 tile_task_runner_ = tile_task_runner; | 932 tile_task_runner_ = tile_task_runner; |
| 918 } | 933 } |
| 919 | 934 |
| 920 bool TileManager::AreRequiredTilesReadyToDraw( | 935 bool TileManager::AreRequiredTilesReadyToDraw( |
| 921 RasterTilePriorityQueue::Type type) const { | 936 RasterTilePriorityQueue::Type type) const { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 1032 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 1018 // steady memory state. Keep scheduling tasks until we reach this state. | 1033 // steady memory state. Keep scheduling tasks until we reach this state. |
| 1019 if (!tiles_that_need_to_be_rasterized.empty()) { | 1034 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 1020 ScheduleTasks(tiles_that_need_to_be_rasterized); | 1035 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 1021 return; | 1036 return; |
| 1022 } | 1037 } |
| 1023 | 1038 |
| 1024 FreeResourcesForReleasedTiles(); | 1039 FreeResourcesForReleasedTiles(); |
| 1025 | 1040 |
| 1026 resource_pool_->ReduceResourceUsage(); | 1041 resource_pool_->ReduceResourceUsage(); |
| 1042 image_decode_controller_.ReduceCacheUsage(); |
| 1027 | 1043 |
| 1028 signals_.all_tile_tasks_completed = true; | 1044 signals_.all_tile_tasks_completed = true; |
| 1029 signals_check_notifier_.Schedule(); | 1045 signals_check_notifier_.Schedule(); |
| 1030 | 1046 |
| 1031 // We don't reserve memory for required-for-activation tiles during | 1047 // We don't reserve memory for required-for-activation tiles during |
| 1032 // accelerated gestures, so we just postpone activation when we don't | 1048 // accelerated gestures, so we just postpone activation when we don't |
| 1033 // have these tiles, and activate after the accelerated gesture. | 1049 // have these tiles, and activate after the accelerated gesture. |
| 1034 // Likewise if we don't allow any tiles (as is the case when we're | 1050 // Likewise if we don't allow any tiles (as is the case when we're |
| 1035 // invisible), if we have tiles that aren't ready, then we shouldn't | 1051 // invisible), if we have tiles that aren't ready, then we shouldn't |
| 1036 // activate as activation can cause checkerboards. | 1052 // activate as activation can cause checkerboards. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 void TileManager::Signals::reset() { | 1197 void TileManager::Signals::reset() { |
| 1182 ready_to_activate = false; | 1198 ready_to_activate = false; |
| 1183 did_notify_ready_to_activate = false; | 1199 did_notify_ready_to_activate = false; |
| 1184 ready_to_draw = false; | 1200 ready_to_draw = false; |
| 1185 did_notify_ready_to_draw = false; | 1201 did_notify_ready_to_draw = false; |
| 1186 all_tile_tasks_completed = false; | 1202 all_tile_tasks_completed = false; |
| 1187 did_notify_all_tile_tasks_completed = false; | 1203 did_notify_all_tile_tasks_completed = false; |
| 1188 } | 1204 } |
| 1189 | 1205 |
| 1190 } // namespace cc | 1206 } // namespace cc |
| OLD | NEW |