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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 bool use_cheapness_estimator) | 187 bool use_cheapness_estimator) |
188 : client_(client), | 188 : client_(client), |
189 resource_pool_(ResourcePool::Create(resource_provider)), | 189 resource_pool_(ResourcePool::Create(resource_provider)), |
190 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 190 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
191 manage_tiles_pending_(false), | 191 manage_tiles_pending_(false), |
192 manage_tiles_call_count_(0), | 192 manage_tiles_call_count_(0), |
193 bytes_pending_set_pixels_(0), | 193 bytes_pending_set_pixels_(0), |
194 has_performed_uploads_since_last_flush_(false), | 194 has_performed_uploads_since_last_flush_(false), |
195 ever_exceeded_memory_budget_(false), | 195 ever_exceeded_memory_budget_(false), |
196 record_rendering_stats_(false), | 196 record_rendering_stats_(false), |
197 use_cheapness_estimator_(use_cheapness_estimator) { | 197 use_cheapness_estimator_(use_cheapness_estimator), |
198 allow_cheap_tasks_(true), | |
199 did_schedule_cheap_tasks_(false) { | |
198 for (int i = 0; i < NUM_STATES; ++i) { | 200 for (int i = 0; i < NUM_STATES; ++i) { |
199 for (int j = 0; j < NUM_TREES; ++j) { | 201 for (int j = 0; j < NUM_TREES; ++j) { |
200 for (int k = 0; k < NUM_BINS; ++k) | 202 for (int k = 0; k < NUM_BINS; ++k) |
201 raster_state_count_[i][j][k] = 0; | 203 raster_state_count_[i][j][k] = 0; |
202 } | 204 } |
203 } | 205 } |
204 } | 206 } |
205 | 207 |
206 TileManager::~TileManager() { | 208 TileManager::~TileManager() { |
207 // Reset global state and manage. This should cause | 209 // Reset global state and manage. This should cause |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 managed_tile_state.can_be_freed = true; | 449 managed_tile_state.can_be_freed = true; |
448 managed_tile_state.can_use_gpu_memory = false; | 450 managed_tile_state.can_use_gpu_memory = false; |
449 FreeResourcesForTile(tile); | 451 FreeResourcesForTile(tile); |
450 | 452 |
451 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 453 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); |
452 DidTileRasterStateChange(tile, IDLE_STATE); | 454 DidTileRasterStateChange(tile, IDLE_STATE); |
453 tiles_with_pending_set_pixels_.pop(); | 455 tiles_with_pending_set_pixels_.pop(); |
454 } | 456 } |
455 } | 457 } |
456 | 458 |
459 void TileManager::DidCompleteFrame() { | |
460 allow_cheap_tasks_ = true; | |
461 did_schedule_cheap_tasks_ = false; | |
462 } | |
463 | |
457 void TileManager::GetMemoryStats( | 464 void TileManager::GetMemoryStats( |
458 size_t* memoryRequiredBytes, | 465 size_t* memoryRequiredBytes, |
459 size_t* memoryNiceToHaveBytes, | 466 size_t* memoryNiceToHaveBytes, |
460 size_t* memoryUsedBytes) const { | 467 size_t* memoryUsedBytes) const { |
461 *memoryRequiredBytes = 0; | 468 *memoryRequiredBytes = 0; |
462 *memoryNiceToHaveBytes = 0; | 469 *memoryNiceToHaveBytes = 0; |
463 *memoryUsedBytes = 0; | 470 *memoryUsedBytes = 0; |
464 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 471 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
465 const Tile* tile = live_or_allocated_tiles_[i]; | 472 const Tile* tile = live_or_allocated_tiles_[i]; |
466 const ManagedTileState& mts = tile->managed_state(); | 473 const ManagedTileState& mts = tile->managed_state(); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
644 tiles_that_need_to_be_rasterized_.end()); | 651 tiles_that_need_to_be_rasterized_.end()); |
645 } | 652 } |
646 | 653 |
647 void TileManager::FreeResourcesForTile(Tile* tile) { | 654 void TileManager::FreeResourcesForTile(Tile* tile) { |
648 ManagedTileState& managed_tile_state = tile->managed_state(); | 655 ManagedTileState& managed_tile_state = tile->managed_state(); |
649 DCHECK(managed_tile_state.can_be_freed); | 656 DCHECK(managed_tile_state.can_be_freed); |
650 if (managed_tile_state.resource) | 657 if (managed_tile_state.resource) |
651 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 658 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
652 } | 659 } |
653 | 660 |
654 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 661 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
655 if (raster_worker_pool_->IsBusy()) | 662 if (raster_worker_pool_->IsBusy()) |
656 return false; | 663 return false; |
657 size_t new_bytes_pending = bytes_pending_set_pixels_; | 664 size_t new_bytes_pending = bytes_pending_set_pixels_; |
658 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 665 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
659 return new_bytes_pending <= kMaxPendingUploadBytes && | 666 return new_bytes_pending <= kMaxPendingUploadBytes && |
660 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; | 667 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; |
661 } | 668 } |
662 | 669 |
663 void TileManager::DispatchMoreTasks() { | 670 void TileManager::DispatchMoreTasks() { |
664 // Because tiles in the image decoding list have higher priorities, we | 671 // Because tiles in the image decoding list have higher priorities, we |
665 // need to process those tiles first before we start to handle the tiles | 672 // need to process those tiles first before we start to handle the tiles |
666 // in the need_to_be_rasterized queue. | 673 // in the need_to_be_rasterized queue. |
667 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 674 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
668 it != tiles_with_image_decoding_tasks_.end(); ) { | 675 it != tiles_with_image_decoding_tasks_.end(); ) { |
669 DispatchImageDecodeTasksForTile(*it); | 676 DispatchImageDecodeTasksForTile(*it); |
670 ManagedTileState& managed_state = (*it)->managed_state(); | 677 ManagedTileState& managed_state = (*it)->managed_state(); |
671 if (managed_state.pending_pixel_refs.empty()) { | 678 if (managed_state.pending_pixel_refs.empty()) { |
672 if (!CanDispatchRasterTask(*it)) | 679 if (!CanDispatchRasterTask(*it)) |
673 return; | 680 break; |
reveman
2013/02/19 18:05:23
hm, this makes us enter the loop below in cases wh
Sami
2013/02/19 22:24:38
You're right. We only need to make sure the allow_
| |
674 DispatchOneRasterTask(*it); | 681 DispatchOneRasterTask(*it); |
675 tiles_with_image_decoding_tasks_.erase(it++); | 682 tiles_with_image_decoding_tasks_.erase(it++); |
676 } else { | 683 } else { |
677 ++it; | 684 ++it; |
678 } | 685 } |
679 } | 686 } |
680 | 687 |
681 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 688 // Process all tiles in the need_to_be_rasterized queue. If a tile has |
682 // image decoding tasks, put it to the back of the image decoding list. | 689 // image decoding tasks, put it to the back of the image decoding list. |
683 while (!tiles_that_need_to_be_rasterized_.empty()) { | 690 while (!tiles_that_need_to_be_rasterized_.empty()) { |
684 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 691 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
685 DispatchImageDecodeTasksForTile(tile); | 692 DispatchImageDecodeTasksForTile(tile); |
686 ManagedTileState& managed_state = tile->managed_state(); | 693 ManagedTileState& managed_state = tile->managed_state(); |
687 if (!managed_state.pending_pixel_refs.empty()) { | 694 if (!managed_state.pending_pixel_refs.empty()) { |
688 tiles_with_image_decoding_tasks_.push_back(tile); | 695 tiles_with_image_decoding_tasks_.push_back(tile); |
689 } else { | 696 } else { |
690 if (!CanDispatchRasterTask(tile)) | 697 if (!CanDispatchRasterTask(tile)) |
691 return; | 698 break; |
692 DispatchOneRasterTask(tile); | 699 DispatchOneRasterTask(tile); |
693 } | 700 } |
694 tiles_that_need_to_be_rasterized_.pop_back(); | 701 tiles_that_need_to_be_rasterized_.pop_back(); |
695 } | 702 } |
703 | |
704 if (did_schedule_cheap_tasks_) | |
705 allow_cheap_tasks_ = false; | |
696 } | 706 } |
697 | 707 |
698 void TileManager::GatherPixelRefsForTile(Tile* tile) { | 708 void TileManager::GatherPixelRefsForTile(Tile* tile) { |
699 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); | 709 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); |
700 ManagedTileState& managed_state = tile->managed_state(); | 710 ManagedTileState& managed_state = tile->managed_state(); |
701 if (managed_state.need_to_gather_pixel_refs) { | 711 if (managed_state.need_to_gather_pixel_refs) { |
702 base::TimeTicks gather_begin_time; | 712 base::TimeTicks gather_begin_time; |
703 if (record_rendering_stats_) | 713 if (record_rendering_stats_) |
704 gather_begin_time = base::TimeTicks::HighResNow(); | 714 gather_begin_time = base::TimeTicks::HighResNow(); |
705 tile->picture_pile()->GatherPixelRefs( | 715 tile->picture_pile()->GatherPixelRefs( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
741 | 751 |
742 void TileManager::DispatchOneImageDecodeTask( | 752 void TileManager::DispatchOneImageDecodeTask( |
743 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | 753 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
744 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | 754 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); |
745 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | 755 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
746 DCHECK(pending_decode_tasks_.end() == | 756 DCHECK(pending_decode_tasks_.end() == |
747 pending_decode_tasks_.find(pixel_ref_id)); | 757 pending_decode_tasks_.find(pixel_ref_id)); |
748 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | 758 pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
749 | 759 |
750 raster_worker_pool_->PostTaskAndReply( | 760 raster_worker_pool_->PostTaskAndReply( |
751 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), | 761 base::Bind(&TileManager::PerformImageDecode, pixel_ref), |
752 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 762 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
753 base::Unretained(this), | 763 base::Unretained(this), |
754 tile, | 764 tile, |
755 pixel_ref_id)); | 765 pixel_ref_id)); |
756 } | 766 } |
757 | 767 |
758 void TileManager::OnImageDecodeTaskCompleted( | 768 void TileManager::OnImageDecodeTaskCompleted( |
759 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 769 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
760 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 770 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
761 pending_decode_tasks_.erase(pixel_ref_id); | 771 pending_decode_tasks_.erase(pixel_ref_id); |
(...skipping 25 matching lines...) Expand all Loading... | |
787 | 797 |
788 DidTileRasterStateChange(tile, RASTER_STATE); | 798 DidTileRasterStateChange(tile, RASTER_STATE); |
789 return resource.Pass(); | 799 return resource.Pass(); |
790 } | 800 } |
791 | 801 |
792 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 802 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
793 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 803 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
794 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 804 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
795 ResourceProvider::ResourceId resource_id = resource->id(); | 805 ResourceProvider::ResourceId resource_id = resource->id(); |
796 | 806 |
807 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && | |
808 tile->picture_pile()->IsCheapInRect(tile->content_rect_, | |
809 tile->contents_scale()); | |
797 raster_worker_pool_->PostRasterTaskAndReply( | 810 raster_worker_pool_->PostRasterTaskAndReply( |
798 tile->picture_pile(), | 811 tile->picture_pile(), |
812 is_cheap, | |
799 base::Bind(&TileManager::PerformRaster, | 813 base::Bind(&TileManager::PerformRaster, |
800 resource_pool_->resource_provider()->mapPixelBuffer( | 814 resource_pool_->resource_provider()->mapPixelBuffer( |
801 resource_id), | 815 resource_id), |
802 tile->content_rect_, | 816 tile->content_rect_, |
803 tile->contents_scale(), | 817 tile->contents_scale(), |
804 use_cheapness_estimator_, | 818 use_cheapness_estimator_, |
805 GetRasterTaskMetadata(tile->managed_state())), | 819 GetRasterTaskMetadata(tile->managed_state())), |
806 base::Bind(&TileManager::OnRasterTaskCompleted, | 820 base::Bind(&TileManager::OnRasterTaskCompleted, |
807 base::Unretained(this), | 821 base::Unretained(this), |
808 tile, | 822 tile, |
809 base::Passed(&resource), | 823 base::Passed(&resource), |
810 manage_tiles_call_count_)); | 824 manage_tiles_call_count_)); |
811 } | 825 did_schedule_cheap_tasks_ |= is_cheap; |
812 | |
813 void TileManager::PerformOneRaster(Tile* tile) { | |
814 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
815 ResourceProvider::ResourceId resource_id = resource->id(); | |
816 | |
817 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | |
818 resource_id), | |
819 tile->content_rect_, | |
820 tile->contents_scale(), | |
821 use_cheapness_estimator_, | |
822 GetRasterTaskMetadata(tile->managed_state()), | |
823 tile->picture_pile(), | |
824 &rendering_stats_); | |
825 | |
826 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | |
827 } | 826 } |
828 | 827 |
829 void TileManager::OnRasterCompleted( | 828 void TileManager::OnRasterCompleted( |
830 scoped_refptr<Tile> tile, | 829 scoped_refptr<Tile> tile, |
831 scoped_ptr<ResourcePool::Resource> resource, | 830 scoped_ptr<ResourcePool::Resource> resource, |
832 int manage_tiles_call_count_when_dispatched) { | 831 int manage_tiles_call_count_when_dispatched) { |
833 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 832 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); |
834 | 833 |
835 // Release raster resources. | 834 // Release raster resources. |
836 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 835 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) | 959 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) |
961 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 960 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
962 | 961 |
963 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 962 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
964 duration.InMilliseconds(), | 963 duration.InMilliseconds(), |
965 0, | 964 0, |
966 10, | 965 10, |
967 10); | 966 10); |
968 | 967 |
969 if (use_cheapness_estimator) { | 968 if (use_cheapness_estimator) { |
970 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal e); | 969 bool is_predicted_cheap = picture_pile->IsCheapInRect(rect, contents_scale ); |
reveman
2013/02/19 18:05:23
nit: make this line <= 80 characters long
Sami
2013/02/19 22:24:38
Whoops, done.
| |
971 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 970 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
972 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 971 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
973 } | 972 } |
974 } | 973 } |
975 } | 974 } |
976 | 975 |
977 // static | 976 // static |
978 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 977 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
979 bool is_actually_cheap) { | 978 bool is_actually_cheap) { |
980 if (is_predicted_cheap && !is_actually_cheap) | 979 if (is_predicted_cheap && !is_actually_cheap) |
981 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 980 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
982 else if (!is_predicted_cheap && is_actually_cheap) | 981 else if (!is_predicted_cheap && is_actually_cheap) |
983 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 982 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
984 | 983 |
985 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 984 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
986 is_predicted_cheap == is_actually_cheap); | 985 is_predicted_cheap == is_actually_cheap); |
987 } | 986 } |
988 | 987 |
989 // static | 988 // static |
990 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 989 void TileManager::PerformImageDecode(skia::LazyPixelRef* pixel_ref, |
991 RenderingStats* stats) { | 990 RenderingStats* stats) { |
992 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 991 TRACE_EVENT0("cc", "TileManager::PerformImageDecode"); |
993 base::TimeTicks decode_begin_time; | 992 base::TimeTicks decode_begin_time; |
994 if (stats) | 993 if (stats) |
995 decode_begin_time = base::TimeTicks::HighResNow(); | 994 decode_begin_time = base::TimeTicks::HighResNow(); |
996 pixel_ref->Decode(); | 995 pixel_ref->Decode(); |
997 if (stats) { | 996 if (stats) { |
998 stats->totalDeferredImageDecodeCount++; | 997 stats->totalDeferredImageDecodeCount++; |
999 stats->totalDeferredImageDecodeTime += | 998 stats->totalDeferredImageDecodeTime += |
1000 base::TimeTicks::HighResNow() - decode_begin_time; | 999 base::TimeTicks::HighResNow() - decode_begin_time; |
1001 } | 1000 } |
1002 } | 1001 } |
1003 | 1002 |
1004 } // namespace cc | 1003 } // namespace cc |
OLD | NEW |