Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: cc/tile_manager.cc

Issue 12194015: cc: Rasterize cheap tiles immediately (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fix picture pile reference management. Post a task for running cheap tasks. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« cc/tile_manager.h ('K') | « cc/tile_manager.h ('k') | cc/worker_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698