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 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 managed_tile_state.can_be_freed = true; | 428 managed_tile_state.can_be_freed = true; |
429 managed_tile_state.can_use_gpu_memory = false; | 429 managed_tile_state.can_use_gpu_memory = false; |
430 FreeResourcesForTile(tile); | 430 FreeResourcesForTile(tile); |
431 | 431 |
432 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 432 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); |
433 DidTileRasterStateChange(tile, IDLE_STATE); | 433 DidTileRasterStateChange(tile, IDLE_STATE); |
434 tiles_with_pending_set_pixels_.pop(); | 434 tiles_with_pending_set_pixels_.pop(); |
435 } | 435 } |
436 } | 436 } |
437 | 437 |
438 void TileManager::DidCompleteFrame() { | |
439 raster_worker_pool_->SetCheapTasksAllowed(true); | |
440 } | |
441 | |
438 void TileManager::GetMemoryStats( | 442 void TileManager::GetMemoryStats( |
439 size_t* memoryRequiredBytes, | 443 size_t* memoryRequiredBytes, |
440 size_t* memoryNiceToHaveBytes, | 444 size_t* memoryNiceToHaveBytes, |
441 size_t* memoryUsedBytes) const { | 445 size_t* memoryUsedBytes) const { |
442 *memoryRequiredBytes = 0; | 446 *memoryRequiredBytes = 0; |
443 *memoryNiceToHaveBytes = 0; | 447 *memoryNiceToHaveBytes = 0; |
444 *memoryUsedBytes = 0; | 448 *memoryUsedBytes = 0; |
445 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 449 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
446 const Tile* tile = live_or_allocated_tiles_[i]; | 450 const Tile* tile = live_or_allocated_tiles_[i]; |
447 const ManagedTileState& mts = tile->managed_state(); | 451 const ManagedTileState& mts = tile->managed_state(); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
613 tiles_that_need_to_be_rasterized_.end()); | 617 tiles_that_need_to_be_rasterized_.end()); |
614 } | 618 } |
615 | 619 |
616 void TileManager::FreeResourcesForTile(Tile* tile) { | 620 void TileManager::FreeResourcesForTile(Tile* tile) { |
617 ManagedTileState& managed_tile_state = tile->managed_state(); | 621 ManagedTileState& managed_tile_state = tile->managed_state(); |
618 DCHECK(managed_tile_state.can_be_freed); | 622 DCHECK(managed_tile_state.can_be_freed); |
619 if (managed_tile_state.resource) | 623 if (managed_tile_state.resource) |
620 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 624 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
621 } | 625 } |
622 | 626 |
623 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 627 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
624 if (raster_worker_pool_->IsBusy()) | 628 if (raster_worker_pool_->IsBusy()) |
625 return false; | 629 return false; |
626 size_t new_bytes_pending = bytes_pending_set_pixels_; | 630 size_t new_bytes_pending = bytes_pending_set_pixels_; |
627 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 631 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
628 return new_bytes_pending <= kMaxPendingUploadBytes; | 632 return new_bytes_pending <= kMaxPendingUploadBytes; |
629 } | 633 } |
630 | 634 |
631 void TileManager::DispatchMoreTasks() { | 635 void TileManager::DispatchMoreTasks() { |
632 // Because tiles in the image decoding list have higher priorities, we | 636 // Because tiles in the image decoding list have higher priorities, we |
633 // need to process those tiles first before we start to handle the tiles | 637 // need to process those tiles first before we start to handle the tiles |
634 // in the need_to_be_rasterized queue. | 638 // in the need_to_be_rasterized queue. |
635 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 639 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
636 it != tiles_with_image_decoding_tasks_.end(); ) { | 640 it != tiles_with_image_decoding_tasks_.end(); ) { |
637 DispatchImageDecodeTasksForTile(*it); | 641 DispatchImageDecodeTasksForTile(*it); |
638 ManagedTileState& managed_state = (*it)->managed_state(); | 642 ManagedTileState& managed_state = (*it)->managed_state(); |
639 if (managed_state.pending_pixel_refs.empty()) { | 643 if (managed_state.pending_pixel_refs.empty()) { |
640 if (!CanDispatchRasterTask(*it)) | 644 if (!CanDispatchRasterTask(*it)) |
641 return; | 645 break; |
642 DispatchOneRasterTask(*it); | 646 DispatchOneRasterTask(*it); |
643 tiles_with_image_decoding_tasks_.erase(it++); | 647 tiles_with_image_decoding_tasks_.erase(it++); |
644 } else { | 648 } else { |
645 ++it; | 649 ++it; |
646 } | 650 } |
647 } | 651 } |
648 | 652 |
649 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 653 // Process all tiles in the need_to_be_rasterized queue. If a tile has |
650 // image decoding tasks, put it to the back of the image decoding list. | 654 // image decoding tasks, put it to the back of the image decoding list. |
651 while (!tiles_that_need_to_be_rasterized_.empty()) { | 655 while (!tiles_that_need_to_be_rasterized_.empty()) { |
652 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 656 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
653 DispatchImageDecodeTasksForTile(tile); | 657 DispatchImageDecodeTasksForTile(tile); |
654 ManagedTileState& managed_state = tile->managed_state(); | 658 ManagedTileState& managed_state = tile->managed_state(); |
655 if (!managed_state.pending_pixel_refs.empty()) { | 659 if (!managed_state.pending_pixel_refs.empty()) { |
656 tiles_with_image_decoding_tasks_.push_back(tile); | 660 tiles_with_image_decoding_tasks_.push_back(tile); |
657 } else { | 661 } else { |
658 if (!CanDispatchRasterTask(tile)) | 662 if (!CanDispatchRasterTask(tile)) |
659 return; | 663 break; |
660 DispatchOneRasterTask(tile); | 664 DispatchOneRasterTask(tile); |
661 } | 665 } |
662 tiles_that_need_to_be_rasterized_.pop_back(); | 666 tiles_that_need_to_be_rasterized_.pop_back(); |
663 } | 667 } |
668 | |
669 if (raster_worker_pool_->RunCheapTasks()) | |
reveman
2013/02/13 22:17:36
this can be handled internally in the worker pool
| |
670 raster_worker_pool_->SetCheapTasksAllowed(false); | |
664 } | 671 } |
665 | 672 |
666 void TileManager::GatherPixelRefsForTile(Tile* tile) { | 673 void TileManager::GatherPixelRefsForTile(Tile* tile) { |
667 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); | 674 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); |
668 ManagedTileState& managed_state = tile->managed_state(); | 675 ManagedTileState& managed_state = tile->managed_state(); |
669 if (managed_state.need_to_gather_pixel_refs) { | 676 if (managed_state.need_to_gather_pixel_refs) { |
670 base::TimeTicks gather_begin_time; | 677 base::TimeTicks gather_begin_time; |
671 if (record_rendering_stats_) | 678 if (record_rendering_stats_) |
672 gather_begin_time = base::TimeTicks::Now(); | 679 gather_begin_time = base::TimeTicks::Now(); |
673 tile->picture_pile()->GatherPixelRefs( | 680 tile->picture_pile()->GatherPixelRefs( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 | 716 |
710 void TileManager::DispatchOneImageDecodeTask( | 717 void TileManager::DispatchOneImageDecodeTask( |
711 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | 718 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
712 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | 719 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); |
713 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | 720 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
714 DCHECK(pending_decode_tasks_.end() == | 721 DCHECK(pending_decode_tasks_.end() == |
715 pending_decode_tasks_.find(pixel_ref_id)); | 722 pending_decode_tasks_.find(pixel_ref_id)); |
716 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | 723 pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
717 | 724 |
718 raster_worker_pool_->PostTaskAndReply( | 725 raster_worker_pool_->PostTaskAndReply( |
719 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), | 726 base::Bind(&TileManager::PerformImageDecode, pixel_ref), |
720 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 727 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
721 base::Unretained(this), | 728 base::Unretained(this), |
722 tile, | 729 tile, |
723 pixel_ref_id)); | 730 pixel_ref_id)); |
724 } | 731 } |
725 | 732 |
726 void TileManager::OnImageDecodeTaskCompleted( | 733 void TileManager::OnImageDecodeTaskCompleted( |
727 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 734 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
728 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 735 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
729 pending_decode_tasks_.erase(pixel_ref_id); | 736 pending_decode_tasks_.erase(pixel_ref_id); |
(...skipping 27 matching lines...) Expand all Loading... | |
757 | 764 |
758 DidTileRasterStateChange(tile, RASTER_STATE); | 765 DidTileRasterStateChange(tile, RASTER_STATE); |
759 return resource.Pass(); | 766 return resource.Pass(); |
760 } | 767 } |
761 | 768 |
762 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 769 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
763 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 770 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
764 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 771 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
765 ResourceProvider::ResourceId resource_id = resource->id(); | 772 ResourceProvider::ResourceId resource_id = resource->id(); |
766 | 773 |
774 bool is_cheap = use_cheapness_estimator_ && | |
775 tile->picture_pile()->IsCheapInRect(tile->content_rect_, | |
776 tile->contents_scale()); | |
767 raster_worker_pool_->PostRasterTaskAndReply( | 777 raster_worker_pool_->PostRasterTaskAndReply( |
768 tile->picture_pile(), | 778 tile->picture_pile(), |
779 is_cheap, | |
769 base::Bind(&TileManager::PerformRaster, | 780 base::Bind(&TileManager::PerformRaster, |
770 resource_pool_->resource_provider()->mapPixelBuffer( | 781 resource_pool_->resource_provider()->mapPixelBuffer( |
771 resource_id), | 782 resource_id), |
772 tile->content_rect_, | 783 tile->content_rect_, |
773 tile->contents_scale(), | 784 tile->contents_scale(), |
774 use_cheapness_estimator_), | 785 use_cheapness_estimator_), |
775 base::Bind(&TileManager::OnRasterTaskCompleted, | 786 base::Bind(&TileManager::OnRasterTaskCompleted, |
776 base::Unretained(this), | 787 base::Unretained(this), |
777 tile, | 788 tile, |
778 base::Passed(&resource), | 789 base::Passed(&resource), |
779 manage_tiles_call_count_)); | 790 manage_tiles_call_count_)); |
780 } | 791 } |
781 | 792 |
782 void TileManager::PerformOneRaster(Tile* tile) { | |
783 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
784 ResourceProvider::ResourceId resource_id = resource->id(); | |
785 | |
786 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | |
787 resource_id), | |
788 tile->content_rect_, | |
789 tile->contents_scale(), | |
790 use_cheapness_estimator_, | |
791 tile->picture_pile(), | |
792 &rendering_stats_); | |
793 | |
794 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | |
795 } | |
796 | |
797 void TileManager::OnRasterCompleted( | 793 void TileManager::OnRasterCompleted( |
798 scoped_refptr<Tile> tile, | 794 scoped_refptr<Tile> tile, |
799 scoped_ptr<ResourcePool::Resource> resource, | 795 scoped_ptr<ResourcePool::Resource> resource, |
800 int manage_tiles_call_count_when_dispatched) { | 796 int manage_tiles_call_count_when_dispatched) { |
801 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 797 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); |
802 | 798 |
803 // Release raster resources. | 799 // Release raster resources. |
804 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 800 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
805 | 801 |
806 ManagedTileState& managed_tile_state = tile->managed_state(); | 802 ManagedTileState& managed_tile_state = tile->managed_state(); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 base::TimeTicks end_time = base::TimeTicks::Now(); | 914 base::TimeTicks end_time = base::TimeTicks::Now(); |
919 base::TimeDelta duration = end_time - begin_time; | 915 base::TimeDelta duration = end_time - begin_time; |
920 stats->totalRasterizeTime += duration; | 916 stats->totalRasterizeTime += duration; |
921 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 917 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
922 duration.InMilliseconds(), | 918 duration.InMilliseconds(), |
923 0, | 919 0, |
924 10, | 920 10, |
925 10); | 921 10); |
926 | 922 |
927 if (use_cheapness_estimator) { | 923 if (use_cheapness_estimator) { |
928 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal e); | 924 bool is_predicted_cheap = picture_pile->IsCheapInRect(rect, contents_scale ); |
929 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 925 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
930 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 926 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
931 } | 927 } |
932 } | 928 } |
933 } | 929 } |
934 | 930 |
935 // static | 931 // static |
936 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 932 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
937 bool is_actually_cheap) { | 933 bool is_actually_cheap) { |
938 if (is_predicted_cheap && !is_actually_cheap) | 934 if (is_predicted_cheap && !is_actually_cheap) |
939 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 935 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
940 else if (!is_predicted_cheap && is_actually_cheap) | 936 else if (!is_predicted_cheap && is_actually_cheap) |
941 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 937 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
942 | 938 |
943 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 939 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
944 is_predicted_cheap == is_actually_cheap); | 940 is_predicted_cheap == is_actually_cheap); |
945 } | 941 } |
946 | 942 |
947 // static | 943 // static |
948 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 944 void TileManager::PerformImageDecode(skia::LazyPixelRef* pixel_ref, |
949 RenderingStats* stats) { | 945 RenderingStats* stats) { |
950 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 946 TRACE_EVENT0("cc", "TileManager::PerformImageDecode"); |
951 base::TimeTicks decode_begin_time; | 947 base::TimeTicks decode_begin_time; |
952 if (stats) | 948 if (stats) |
953 decode_begin_time = base::TimeTicks::Now(); | 949 decode_begin_time = base::TimeTicks::Now(); |
954 pixel_ref->Decode(); | 950 pixel_ref->Decode(); |
955 if (stats) { | 951 if (stats) { |
956 stats->totalDeferredImageDecodeCount++; | 952 stats->totalDeferredImageDecodeCount++; |
957 stats->totalDeferredImageDecodeTime += | 953 stats->totalDeferredImageDecodeTime += |
958 base::TimeTicks::Now() - decode_begin_time; | 954 base::TimeTicks::Now() - decode_begin_time; |
959 } | 955 } |
960 } | 956 } |
961 | 957 |
962 } // namespace cc | 958 } // namespace cc |
OLD | NEW |