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 |