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/tile_manager.h" | 5 #include "cc/tile_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 bool use_cheapness_estimator) | 180 bool use_cheapness_estimator) |
181 : client_(client), | 181 : client_(client), |
182 resource_pool_(ResourcePool::Create(resource_provider)), | 182 resource_pool_(ResourcePool::Create(resource_provider)), |
183 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 183 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
184 manage_tiles_pending_(false), | 184 manage_tiles_pending_(false), |
185 manage_tiles_call_count_(0), | 185 manage_tiles_call_count_(0), |
186 bytes_pending_set_pixels_(0), | 186 bytes_pending_set_pixels_(0), |
187 has_performed_uploads_since_last_flush_(false), | 187 has_performed_uploads_since_last_flush_(false), |
188 ever_exceeded_memory_budget_(false), | 188 ever_exceeded_memory_budget_(false), |
189 record_rendering_stats_(false), | 189 record_rendering_stats_(false), |
190 use_cheapness_estimator_(use_cheapness_estimator) { | 190 use_cheapness_estimator_(use_cheapness_estimator), |
| 191 allow_cheap_tasks_(true), |
| 192 did_schedule_cheap_tasks_(false) { |
191 for (int i = 0; i < NUM_STATES; ++i) { | 193 for (int i = 0; i < NUM_STATES; ++i) { |
192 for (int j = 0; j < NUM_TREES; ++j) { | 194 for (int j = 0; j < NUM_TREES; ++j) { |
193 for (int k = 0; k < NUM_BINS; ++k) | 195 for (int k = 0; k < NUM_BINS; ++k) |
194 raster_state_count_[i][j][k] = 0; | 196 raster_state_count_[i][j][k] = 0; |
195 } | 197 } |
196 } | 198 } |
197 } | 199 } |
198 | 200 |
199 TileManager::~TileManager() { | 201 TileManager::~TileManager() { |
200 // Reset global state and manage. This should cause | 202 // Reset global state and manage. This should cause |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 managed_tile_state.can_be_freed = true; | 437 managed_tile_state.can_be_freed = true; |
436 managed_tile_state.can_use_gpu_memory = false; | 438 managed_tile_state.can_use_gpu_memory = false; |
437 FreeResourcesForTile(tile); | 439 FreeResourcesForTile(tile); |
438 | 440 |
439 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 441 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); |
440 DidTileRasterStateChange(tile, IDLE_STATE); | 442 DidTileRasterStateChange(tile, IDLE_STATE); |
441 tiles_with_pending_set_pixels_.pop(); | 443 tiles_with_pending_set_pixels_.pop(); |
442 } | 444 } |
443 } | 445 } |
444 | 446 |
| 447 void TileManager::DidCompleteFrame() { |
| 448 allow_cheap_tasks_ = true; |
| 449 did_schedule_cheap_tasks_ = false; |
| 450 } |
| 451 |
445 void TileManager::GetMemoryStats( | 452 void TileManager::GetMemoryStats( |
446 size_t* memoryRequiredBytes, | 453 size_t* memoryRequiredBytes, |
447 size_t* memoryNiceToHaveBytes, | 454 size_t* memoryNiceToHaveBytes, |
448 size_t* memoryUsedBytes) const { | 455 size_t* memoryUsedBytes) const { |
449 *memoryRequiredBytes = 0; | 456 *memoryRequiredBytes = 0; |
450 *memoryNiceToHaveBytes = 0; | 457 *memoryNiceToHaveBytes = 0; |
451 *memoryUsedBytes = 0; | 458 *memoryUsedBytes = 0; |
452 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 459 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
453 const Tile* tile = live_or_allocated_tiles_[i]; | 460 const Tile* tile = live_or_allocated_tiles_[i]; |
454 const ManagedTileState& mts = tile->managed_state(); | 461 const ManagedTileState& mts = tile->managed_state(); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 tiles_that_need_to_be_rasterized_.end()); | 639 tiles_that_need_to_be_rasterized_.end()); |
633 } | 640 } |
634 | 641 |
635 void TileManager::FreeResourcesForTile(Tile* tile) { | 642 void TileManager::FreeResourcesForTile(Tile* tile) { |
636 ManagedTileState& managed_tile_state = tile->managed_state(); | 643 ManagedTileState& managed_tile_state = tile->managed_state(); |
637 DCHECK(managed_tile_state.can_be_freed); | 644 DCHECK(managed_tile_state.can_be_freed); |
638 if (managed_tile_state.resource) | 645 if (managed_tile_state.resource) |
639 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 646 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
640 } | 647 } |
641 | 648 |
642 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 649 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
643 if (raster_worker_pool_->IsBusy()) | 650 if (raster_worker_pool_->IsBusy()) |
644 return false; | 651 return false; |
645 size_t new_bytes_pending = bytes_pending_set_pixels_; | 652 size_t new_bytes_pending = bytes_pending_set_pixels_; |
646 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 653 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
647 return new_bytes_pending <= kMaxPendingUploadBytes && | 654 return new_bytes_pending <= kMaxPendingUploadBytes && |
648 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; | 655 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; |
649 } | 656 } |
650 | 657 |
651 void TileManager::DispatchMoreTasks() { | 658 void TileManager::DispatchMoreTasks() { |
652 // Because tiles in the image decoding list have higher priorities, we | 659 // Because tiles in the image decoding list have higher priorities, we |
653 // need to process those tiles first before we start to handle the tiles | 660 // need to process those tiles first before we start to handle the tiles |
654 // in the need_to_be_rasterized queue. | 661 // in the need_to_be_rasterized queue. |
655 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 662 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
656 it != tiles_with_image_decoding_tasks_.end(); ) { | 663 it != tiles_with_image_decoding_tasks_.end(); ) { |
657 DispatchImageDecodeTasksForTile(*it); | 664 DispatchImageDecodeTasksForTile(*it); |
658 ManagedTileState& managed_state = (*it)->managed_state(); | 665 ManagedTileState& managed_state = (*it)->managed_state(); |
659 if (managed_state.pending_pixel_refs.empty()) { | 666 if (managed_state.pending_pixel_refs.empty()) { |
660 if (!CanDispatchRasterTask(*it)) | 667 if (!CanDispatchRasterTask(*it)) |
661 return; | 668 break; |
662 DispatchOneRasterTask(*it); | 669 DispatchOneRasterTask(*it); |
663 tiles_with_image_decoding_tasks_.erase(it++); | 670 tiles_with_image_decoding_tasks_.erase(it++); |
664 } else { | 671 } else { |
665 ++it; | 672 ++it; |
666 } | 673 } |
667 } | 674 } |
668 | 675 |
669 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 676 // Process all tiles in the need_to_be_rasterized queue. If a tile has |
670 // image decoding tasks, put it to the back of the image decoding list. | 677 // image decoding tasks, put it to the back of the image decoding list. |
671 while (!tiles_that_need_to_be_rasterized_.empty()) { | 678 while (!tiles_that_need_to_be_rasterized_.empty()) { |
672 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 679 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
673 DispatchImageDecodeTasksForTile(tile); | 680 DispatchImageDecodeTasksForTile(tile); |
674 ManagedTileState& managed_state = tile->managed_state(); | 681 ManagedTileState& managed_state = tile->managed_state(); |
675 if (!managed_state.pending_pixel_refs.empty()) { | 682 if (!managed_state.pending_pixel_refs.empty()) { |
676 tiles_with_image_decoding_tasks_.push_back(tile); | 683 tiles_with_image_decoding_tasks_.push_back(tile); |
677 } else { | 684 } else { |
678 if (!CanDispatchRasterTask(tile)) | 685 if (!CanDispatchRasterTask(tile)) |
679 return; | 686 break; |
680 DispatchOneRasterTask(tile); | 687 DispatchOneRasterTask(tile); |
681 } | 688 } |
682 tiles_that_need_to_be_rasterized_.pop_back(); | 689 tiles_that_need_to_be_rasterized_.pop_back(); |
683 } | 690 } |
| 691 |
| 692 if (did_schedule_cheap_tasks_) |
| 693 allow_cheap_tasks_ = false; |
684 } | 694 } |
685 | 695 |
686 void TileManager::GatherPixelRefsForTile(Tile* tile) { | 696 void TileManager::GatherPixelRefsForTile(Tile* tile) { |
687 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); | 697 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); |
688 ManagedTileState& managed_state = tile->managed_state(); | 698 ManagedTileState& managed_state = tile->managed_state(); |
689 if (managed_state.need_to_gather_pixel_refs) { | 699 if (managed_state.need_to_gather_pixel_refs) { |
690 base::TimeTicks gather_begin_time; | 700 base::TimeTicks gather_begin_time; |
691 if (record_rendering_stats_) | 701 if (record_rendering_stats_) |
692 gather_begin_time = base::TimeTicks::Now(); | 702 gather_begin_time = base::TimeTicks::Now(); |
693 tile->picture_pile()->GatherPixelRefs( | 703 tile->picture_pile()->GatherPixelRefs( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 | 739 |
730 void TileManager::DispatchOneImageDecodeTask( | 740 void TileManager::DispatchOneImageDecodeTask( |
731 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | 741 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
732 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | 742 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); |
733 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | 743 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
734 DCHECK(pending_decode_tasks_.end() == | 744 DCHECK(pending_decode_tasks_.end() == |
735 pending_decode_tasks_.find(pixel_ref_id)); | 745 pending_decode_tasks_.find(pixel_ref_id)); |
736 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | 746 pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
737 | 747 |
738 raster_worker_pool_->PostTaskAndReply( | 748 raster_worker_pool_->PostTaskAndReply( |
739 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), | 749 base::Bind(&TileManager::PerformImageDecode, pixel_ref), |
740 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 750 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
741 base::Unretained(this), | 751 base::Unretained(this), |
742 tile, | 752 tile, |
743 pixel_ref_id)); | 753 pixel_ref_id)); |
744 } | 754 } |
745 | 755 |
746 void TileManager::OnImageDecodeTaskCompleted( | 756 void TileManager::OnImageDecodeTaskCompleted( |
747 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 757 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
748 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 758 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
749 pending_decode_tasks_.erase(pixel_ref_id); | 759 pending_decode_tasks_.erase(pixel_ref_id); |
(...skipping 25 matching lines...) Expand all Loading... |
775 | 785 |
776 DidTileRasterStateChange(tile, RASTER_STATE); | 786 DidTileRasterStateChange(tile, RASTER_STATE); |
777 return resource.Pass(); | 787 return resource.Pass(); |
778 } | 788 } |
779 | 789 |
780 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 790 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
781 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 791 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
782 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 792 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
783 ResourceProvider::ResourceId resource_id = resource->id(); | 793 ResourceProvider::ResourceId resource_id = resource->id(); |
784 | 794 |
| 795 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && |
| 796 tile->picture_pile()->IsCheapInRect(tile->content_rect_, |
| 797 tile->contents_scale()); |
785 raster_worker_pool_->PostRasterTaskAndReply( | 798 raster_worker_pool_->PostRasterTaskAndReply( |
786 tile->picture_pile(), | 799 tile->picture_pile(), |
| 800 is_cheap, |
787 base::Bind(&TileManager::PerformRaster, | 801 base::Bind(&TileManager::PerformRaster, |
788 resource_pool_->resource_provider()->mapPixelBuffer( | 802 resource_pool_->resource_provider()->mapPixelBuffer( |
789 resource_id), | 803 resource_id), |
790 tile->content_rect_, | 804 tile->content_rect_, |
791 tile->contents_scale(), | 805 tile->contents_scale(), |
792 use_cheapness_estimator_, | 806 use_cheapness_estimator_, |
793 GetRasterTaskMetadata(tile->managed_state())), | 807 GetRasterTaskMetadata(tile->managed_state())), |
794 base::Bind(&TileManager::OnRasterTaskCompleted, | 808 base::Bind(&TileManager::OnRasterTaskCompleted, |
795 base::Unretained(this), | 809 base::Unretained(this), |
796 tile, | 810 tile, |
797 base::Passed(&resource), | 811 base::Passed(&resource), |
798 manage_tiles_call_count_)); | 812 manage_tiles_call_count_)); |
799 } | 813 did_schedule_cheap_tasks_ |= is_cheap; |
800 | |
801 void TileManager::PerformOneRaster(Tile* tile) { | |
802 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
803 ResourceProvider::ResourceId resource_id = resource->id(); | |
804 | |
805 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | |
806 resource_id), | |
807 tile->content_rect_, | |
808 tile->contents_scale(), | |
809 use_cheapness_estimator_, | |
810 GetRasterTaskMetadata(tile->managed_state()), | |
811 tile->picture_pile(), | |
812 &rendering_stats_); | |
813 | |
814 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | |
815 } | 814 } |
816 | 815 |
817 void TileManager::OnRasterCompleted( | 816 void TileManager::OnRasterCompleted( |
818 scoped_refptr<Tile> tile, | 817 scoped_refptr<Tile> tile, |
819 scoped_ptr<ResourcePool::Resource> resource, | 818 scoped_ptr<ResourcePool::Resource> resource, |
820 int manage_tiles_call_count_when_dispatched) { | 819 int manage_tiles_call_count_when_dispatched) { |
821 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 820 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); |
822 | 821 |
823 // Release raster resources. | 822 // Release raster resources. |
824 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 823 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 base::TimeTicks end_time = base::TimeTicks::Now(); | 944 base::TimeTicks end_time = base::TimeTicks::Now(); |
946 base::TimeDelta duration = end_time - begin_time; | 945 base::TimeDelta duration = end_time - begin_time; |
947 stats->totalRasterizeTime += duration; | 946 stats->totalRasterizeTime += duration; |
948 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 947 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
949 duration.InMilliseconds(), | 948 duration.InMilliseconds(), |
950 0, | 949 0, |
951 10, | 950 10, |
952 10); | 951 10); |
953 | 952 |
954 if (use_cheapness_estimator) { | 953 if (use_cheapness_estimator) { |
955 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal
e); | 954 bool is_predicted_cheap = picture_pile->IsCheapInRect(rect, contents_scale
); |
956 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 955 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
957 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 956 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
958 } | 957 } |
959 } | 958 } |
960 } | 959 } |
961 | 960 |
962 // static | 961 // static |
963 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 962 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
964 bool is_actually_cheap) { | 963 bool is_actually_cheap) { |
965 if (is_predicted_cheap && !is_actually_cheap) | 964 if (is_predicted_cheap && !is_actually_cheap) |
966 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 965 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
967 else if (!is_predicted_cheap && is_actually_cheap) | 966 else if (!is_predicted_cheap && is_actually_cheap) |
968 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 967 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
969 | 968 |
970 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 969 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
971 is_predicted_cheap == is_actually_cheap); | 970 is_predicted_cheap == is_actually_cheap); |
972 } | 971 } |
973 | 972 |
974 // static | 973 // static |
975 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 974 void TileManager::PerformImageDecode(skia::LazyPixelRef* pixel_ref, |
976 RenderingStats* stats) { | 975 RenderingStats* stats) { |
977 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 976 TRACE_EVENT0("cc", "TileManager::PerformImageDecode"); |
978 base::TimeTicks decode_begin_time; | 977 base::TimeTicks decode_begin_time; |
979 if (stats) | 978 if (stats) |
980 decode_begin_time = base::TimeTicks::Now(); | 979 decode_begin_time = base::TimeTicks::Now(); |
981 pixel_ref->Decode(); | 980 pixel_ref->Decode(); |
982 if (stats) { | 981 if (stats) { |
983 stats->totalDeferredImageDecodeCount++; | 982 stats->totalDeferredImageDecodeCount++; |
984 stats->totalDeferredImageDecodeTime += | 983 stats->totalDeferredImageDecodeTime += |
985 base::TimeTicks::Now() - decode_begin_time; | 984 base::TimeTicks::Now() - decode_begin_time; |
986 } | 985 } |
987 } | 986 } |
988 | 987 |
989 } // namespace cc | 988 } // namespace cc |
OLD | NEW |