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

Side by Side Diff: cc/tile_manager.cc

Issue 12217105: cc: Check for completed raster tasks at interval. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Post task to impl thread when worker pool becomes idle. 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 12 matching lines...) Expand all
23 23
24 // If we raster too fast we become upload bound, and pending 24 // If we raster too fast we become upload bound, and pending
25 // uploads consume memory. For maximum upload throughput, we would 25 // uploads consume memory. For maximum upload throughput, we would
26 // want to allow for upload_throughput * pipeline_time of pending 26 // want to allow for upload_throughput * pipeline_time of pending
27 // uploads, after which we are just wasting memory. Since we don't 27 // uploads, after which we are just wasting memory. Since we don't
28 // know our upload throughput yet, this just caps our memory usage. 28 // know our upload throughput yet, this just caps our memory usage.
29 #if defined(OS_ANDROID) 29 #if defined(OS_ANDROID)
30 // For reference, the Nexus10 can upload 1MB in about 2.5ms. 30 // For reference, the Nexus10 can upload 1MB in about 2.5ms.
31 // Assuming a three frame deep pipeline this implies ~20MB. 31 // Assuming a three frame deep pipeline this implies ~20MB.
32 const int kMaxPendingUploadBytes = 20 * 1024 * 1024; 32 const int kMaxPendingUploadBytes = 20 * 1024 * 1024;
33 const int kMaxPendingRasterBytes = 2 * 1024 * 1024;
33 #else 34 #else
34 const int kMaxPendingUploadBytes = 100 * 1024 * 1024; 35 const int kMaxPendingUploadBytes = 100 * 1024 * 1024;
36 const int kMaxPendingRasterBytes = 10 * 1024 * 1024;
35 #endif 37 #endif
36 38
37 // Determine bin based on three categories of tiles: things we need now, 39 // Determine bin based on three categories of tiles: things we need now,
38 // things we need soon, and eventually. 40 // things we need soon, and eventually.
39 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { 41 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) {
40 if (!prio.is_live) 42 if (!prio.is_live)
41 return NEVER_BIN; 43 return NEVER_BIN;
42 44
43 // The amount of time for which we want to have prepainting coverage. 45 // The amount of time for which we want to have prepainting coverage.
44 const double prepainting_window_time_seconds = 1.0; 46 const double prepainting_window_time_seconds = 1.0;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 return state.PassAs<base::Value>(); 164 return state.PassAs<base::Value>();
163 } 165 }
164 166
165 TileManager::TileManager( 167 TileManager::TileManager(
166 TileManagerClient* client, 168 TileManagerClient* client,
167 ResourceProvider* resource_provider, 169 ResourceProvider* resource_provider,
168 size_t num_raster_threads, 170 size_t num_raster_threads,
169 bool use_cheapness_estimator) 171 bool use_cheapness_estimator)
170 : client_(client), 172 : client_(client),
171 resource_pool_(ResourcePool::Create(resource_provider)), 173 resource_pool_(ResourcePool::Create(resource_provider)),
172 raster_worker_pool_(RasterWorkerPool::Create(num_raster_threads)), 174 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)),
173 manage_tiles_pending_(false), 175 manage_tiles_pending_(false),
174 manage_tiles_call_count_(0), 176 manage_tiles_call_count_(0),
177 ever_exceeded_memory_budget_(false),
178 bytes_pending_raster_(0),
175 bytes_pending_set_pixels_(0), 179 bytes_pending_set_pixels_(0),
176 ever_exceeded_memory_budget_(false),
177 record_rendering_stats_(false), 180 record_rendering_stats_(false),
178 use_cheapness_estimator_(use_cheapness_estimator) { 181 use_cheapness_estimator_(use_cheapness_estimator) {
179 for (int i = 0; i < NUM_STATES; ++i) { 182 for (int i = 0; i < NUM_STATES; ++i) {
180 for (int j = 0; j < NUM_TREES; ++j) { 183 for (int j = 0; j < NUM_TREES; ++j) {
181 for (int k = 0; k < NUM_BINS; ++k) 184 for (int k = 0; k < NUM_BINS; ++k)
182 raster_state_count_[i][j][k] = 0; 185 raster_state_count_[i][j][k] = 0;
183 } 186 }
184 } 187 }
185 } 188 }
186 189
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // Assign gpu memory and determine what tiles need to be rasterized. 391 // Assign gpu memory and determine what tiles need to be rasterized.
389 AssignGpuMemoryToTiles(); 392 AssignGpuMemoryToTiles();
390 393
391 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", 394 TRACE_EVENT_INSTANT1("cc", "DidManage", "state",
392 ValueToString(BasicStateAsValue())); 395 ValueToString(BasicStateAsValue()));
393 396
394 // Finally, kick the rasterizer. 397 // Finally, kick the rasterizer.
395 DispatchMoreTasks(); 398 DispatchMoreTasks();
396 } 399 }
397 400
401 void TileManager::CheckForCompletedRasterTasks() {
402 int pending_upload_count = tiles_with_pending_set_pixels_.size();
403
404 // Check for completed tasks and dispatch replies.
405 raster_worker_pool_->CheckForCompletedTasks();
406
407 // Flush if we began new uploads.
408 if (tiles_with_pending_set_pixels_.size() != pending_upload_count)
409 resource_pool_->resource_provider()->shallowFlushIfSupported();
410
411 DispatchMoreTasks();
412
413 // Schedule another check if we still have pending raster tasks.
414 if (bytes_pending_raster_)
415 client_->ScheduleCheckForCompletedRasterTasks();
416 }
417
398 void TileManager::CheckForCompletedTileUploads() { 418 void TileManager::CheckForCompletedTileUploads() {
399 while (!tiles_with_pending_set_pixels_.empty()) { 419 while (!tiles_with_pending_set_pixels_.empty()) {
400 Tile* tile = tiles_with_pending_set_pixels_.front(); 420 Tile* tile = tiles_with_pending_set_pixels_.front();
401 DCHECK(tile->managed_state().resource); 421 DCHECK(tile->managed_state().resource);
402 422
403 // Set pixel tasks complete in the order they are posted. 423 // Set pixel tasks complete in the order they are posted.
404 if (!resource_pool_->resource_provider()->didSetPixelsComplete( 424 if (!resource_pool_->resource_provider()->didSetPixelsComplete(
405 tile->managed_state().resource->id())) { 425 tile->managed_state().resource->id())) {
406 break; 426 break;
407 } 427 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 case IDLE_STATE: 554 case IDLE_STATE:
535 break; 555 break;
536 default: 556 default:
537 NOTREACHED(); 557 NOTREACHED();
538 } 558 }
539 } 559 }
540 560
541 return false; 561 return false;
542 } 562 }
543 563
564 void TileManager::OnIdle() {
565 client_->DidDetectIdleRaster();
566 }
567
544 void TileManager::AssignGpuMemoryToTiles() { 568 void TileManager::AssignGpuMemoryToTiles() {
545 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 569 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
546 // Some memory cannot be released. Figure out which. 570 // Some memory cannot be released. Figure out which.
547 size_t unreleasable_bytes = 0; 571 size_t unreleasable_bytes = 0;
548 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 572 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
549 Tile* tile = *it; 573 Tile* tile = *it;
550 if (!tile->managed_state().can_be_freed) 574 if (!tile->managed_state().can_be_freed)
551 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 575 unreleasable_bytes += tile->bytes_consumed_if_allocated();
552 } 576 }
553 577
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 } 649 }
626 650
627 void TileManager::FreeResourcesForTile(Tile* tile) { 651 void TileManager::FreeResourcesForTile(Tile* tile) {
628 ManagedTileState& managed_tile_state = tile->managed_state(); 652 ManagedTileState& managed_tile_state = tile->managed_state();
629 DCHECK(managed_tile_state.can_be_freed); 653 DCHECK(managed_tile_state.can_be_freed);
630 if (managed_tile_state.resource) 654 if (managed_tile_state.resource)
631 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); 655 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass());
632 } 656 }
633 657
634 bool TileManager::CanDispatchRasterTask(Tile* tile) { 658 bool TileManager::CanDispatchRasterTask(Tile* tile) {
635 if (raster_worker_pool_->IsBusy()) 659 size_t new_raster_bytes_pending = bytes_pending_raster_;
660 new_raster_bytes_pending += tile->bytes_consumed_if_allocated();
661 if (new_raster_bytes_pending > kMaxPendingRasterBytes)
636 return false; 662 return false;
637 size_t new_bytes_pending = bytes_pending_set_pixels_; 663
638 new_bytes_pending += tile->bytes_consumed_if_allocated(); 664 size_t new_upload_bytes_pending = bytes_pending_raster_ +
639 return new_bytes_pending <= kMaxPendingUploadBytes; 665 bytes_pending_set_pixels_;
666 new_upload_bytes_pending += tile->bytes_consumed_if_allocated();
667 if (new_upload_bytes_pending > kMaxPendingUploadBytes)
668 return false;
669
670 return true;
640 } 671 }
641 672
642 void TileManager::DispatchMoreTasks() { 673 void TileManager::DispatchMoreTasks() {
643 // Because tiles in the image decoding list have higher priorities, we 674 // Because tiles in the image decoding list have higher priorities, we
644 // need to process those tiles first before we start to handle the tiles 675 // need to process those tiles first before we start to handle the tiles
645 // in the need_to_be_rasterized queue. 676 // in the need_to_be_rasterized queue.
646 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); 677 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin();
647 it != tiles_with_image_decoding_tasks_.end(); ) { 678 it != tiles_with_image_decoding_tasks_.end(); ) {
648 DispatchImageDecodeTasksForTile(*it); 679 DispatchImageDecodeTasksForTile(*it);
649 ManagedTileState& managed_state = (*it)->managed_state(); 680 ManagedTileState& managed_state = (*it)->managed_state();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 if (pending_decode_tasks_.end() != pending_decode_tasks_.find( 734 if (pending_decode_tasks_.end() != pending_decode_tasks_.find(
704 (*it)->getGenerationID())) { 735 (*it)->getGenerationID())) {
705 ++it; 736 ++it;
706 continue; 737 continue;
707 } 738 }
708 // TODO(qinmin): passing correct image size to PrepareToDecode(). 739 // TODO(qinmin): passing correct image size to PrepareToDecode().
709 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { 740 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
710 rendering_stats_.totalDeferredImageCacheHitCount++; 741 rendering_stats_.totalDeferredImageCacheHitCount++;
711 pending_pixel_refs.erase(it++); 742 pending_pixel_refs.erase(it++);
712 } else { 743 } else {
713 if (raster_worker_pool_->IsBusy()) 744 if (!CanDispatchRasterTask(tile))
714 return; 745 return;
715 DispatchOneImageDecodeTask(tile, *it); 746 DispatchOneImageDecodeTask(tile, *it);
716 ++it; 747 ++it;
717 } 748 }
718 } 749 }
719 } 750 }
720 751
721 void TileManager::DispatchOneImageDecodeTask( 752 void TileManager::DispatchOneImageDecodeTask(
722 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { 753 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) {
723 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); 754 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask");
724 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); 755 uint32_t pixel_ref_id = pixel_ref->getGenerationID();
725 DCHECK(pending_decode_tasks_.end() == 756 DCHECK(pending_decode_tasks_.end() ==
726 pending_decode_tasks_.find(pixel_ref_id)); 757 pending_decode_tasks_.find(pixel_ref_id));
727 pending_decode_tasks_[pixel_ref_id] = pixel_ref; 758 pending_decode_tasks_[pixel_ref_id] = pixel_ref;
728 759
729 raster_worker_pool_->PostTaskAndReply( 760 raster_worker_pool_->PostTaskAndReply(
730 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), 761 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref),
731 base::Bind(&TileManager::OnImageDecodeTaskCompleted, 762 base::Bind(&TileManager::OnImageDecodeTaskCompleted,
732 base::Unretained(this), 763 base::Unretained(this),
733 tile, 764 tile,
734 pixel_ref_id)); 765 pixel_ref_id));
766
767 client_->ScheduleCheckForCompletedRasterTasks();
735 } 768 }
736 769
737 void TileManager::OnImageDecodeTaskCompleted( 770 void TileManager::OnImageDecodeTaskCompleted(
738 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { 771 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) {
739 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); 772 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted");
740 pending_decode_tasks_.erase(pixel_ref_id); 773 pending_decode_tasks_.erase(pixel_ref_id);
741 774
742 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); 775 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin();
743 it != tiles_with_image_decoding_tasks_.end(); ++it) { 776 it != tiles_with_image_decoding_tasks_.end(); ++it) {
744 std::list<skia::LazyPixelRef*>& pixel_refs = 777 std::list<skia::LazyPixelRef*>& pixel_refs =
745 (*it)->managed_state().pending_pixel_refs; 778 (*it)->managed_state().pending_pixel_refs;
746 for (std::list<skia::LazyPixelRef*>::iterator pixel_it = 779 for (std::list<skia::LazyPixelRef*>::iterator pixel_it =
747 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) { 780 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) {
748 if (pixel_ref_id == (*pixel_it)->getGenerationID()) { 781 if (pixel_ref_id == (*pixel_it)->getGenerationID()) {
749 pixel_refs.erase(pixel_it); 782 pixel_refs.erase(pixel_it);
750 break; 783 break;
751 } 784 }
752 } 785 }
753 } 786 }
754
755 DispatchMoreTasks();
756 } 787 }
757 788
758 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( 789 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster(
759 Tile* tile) { 790 Tile* tile) {
760 ManagedTileState& managed_tile_state = tile->managed_state(); 791 ManagedTileState& managed_tile_state = tile->managed_state();
761 DCHECK(managed_tile_state.can_use_gpu_memory); 792 DCHECK(managed_tile_state.can_use_gpu_memory);
762 scoped_ptr<ResourcePool::Resource> resource = 793 scoped_ptr<ResourcePool::Resource> resource =
763 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); 794 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_);
764 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); 795 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id());
765 796
(...skipping 15 matching lines...) Expand all
781 resource_pool_->resource_provider()->mapPixelBuffer( 812 resource_pool_->resource_provider()->mapPixelBuffer(
782 resource_id), 813 resource_id),
783 tile->content_rect_, 814 tile->content_rect_,
784 tile->contents_scale(), 815 tile->contents_scale(),
785 use_cheapness_estimator_), 816 use_cheapness_estimator_),
786 base::Bind(&TileManager::OnRasterTaskCompleted, 817 base::Bind(&TileManager::OnRasterTaskCompleted,
787 base::Unretained(this), 818 base::Unretained(this),
788 tile, 819 tile,
789 base::Passed(&resource), 820 base::Passed(&resource),
790 manage_tiles_call_count_)); 821 manage_tiles_call_count_));
822
823 bytes_pending_raster_ += tile->bytes_consumed_if_allocated();
824 client_->ScheduleCheckForCompletedRasterTasks();
791 } 825 }
792 826
793 void TileManager::PerformOneRaster(Tile* tile) { 827 void TileManager::PerformOneRaster(Tile* tile) {
794 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); 828 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile);
795 ResourceProvider::ResourceId resource_id = resource->id(); 829 ResourceProvider::ResourceId resource_id = resource->id();
796 830
797 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( 831 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer(
798 resource_id), 832 resource_id),
799 tile->content_rect_, 833 tile->content_rect_,
800 tile->contents_scale(), 834 tile->contents_scale(),
(...skipping 30 matching lines...) Expand all
831 // The component order may be bgra if we're uploading bgra pixels to rgba 865 // The component order may be bgra if we're uploading bgra pixels to rgba
832 // texture. Mark contents as swizzled if image component order is 866 // texture. Mark contents as swizzled if image component order is
833 // different than texture format. 867 // different than texture format.
834 managed_tile_state.contents_swizzled = 868 managed_tile_state.contents_swizzled =
835 !PlatformColor::sameComponentOrder(tile->format_); 869 !PlatformColor::sameComponentOrder(tile->format_);
836 870
837 // Tile resources can't be freed until upload has completed. 871 // Tile resources can't be freed until upload has completed.
838 managed_tile_state.can_be_freed = false; 872 managed_tile_state.can_be_freed = false;
839 873
840 resource_pool_->resource_provider()->beginSetPixels(resource->id()); 874 resource_pool_->resource_provider()->beginSetPixels(resource->id());
841 resource_pool_->resource_provider()->shallowFlushIfSupported();
842 managed_tile_state.resource = resource.Pass(); 875 managed_tile_state.resource = resource.Pass();
843 876
844 bytes_pending_set_pixels_ += tile->bytes_consumed_if_allocated(); 877 bytes_pending_set_pixels_ += tile->bytes_consumed_if_allocated();
845 DidTileRasterStateChange(tile, SET_PIXELS_STATE); 878 DidTileRasterStateChange(tile, SET_PIXELS_STATE);
846 tiles_with_pending_set_pixels_.push(tile); 879 tiles_with_pending_set_pixels_.push(tile);
847 } else { 880 } else {
848 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); 881 resource_pool_->resource_provider()->releasePixelBuffer(resource->id());
849 resource_pool_->ReleaseResource(resource.Pass()); 882 resource_pool_->ReleaseResource(resource.Pass());
850 managed_tile_state.resource_is_being_initialized = false; 883 managed_tile_state.resource_is_being_initialized = false;
851 DidTileRasterStateChange(tile, IDLE_STATE); 884 DidTileRasterStateChange(tile, IDLE_STATE);
852 } 885 }
853 } 886 }
854 887
855 void TileManager::OnRasterTaskCompleted( 888 void TileManager::OnRasterTaskCompleted(
856 scoped_refptr<Tile> tile, 889 scoped_refptr<Tile> tile,
857 scoped_ptr<ResourcePool::Resource> resource, 890 scoped_ptr<ResourcePool::Resource> resource,
858 int manage_tiles_call_count_when_dispatched) { 891 int manage_tiles_call_count_when_dispatched) {
892 bytes_pending_raster_ -= tile->bytes_consumed_if_allocated();
859 OnRasterCompleted(tile, resource.Pass(), 893 OnRasterCompleted(tile, resource.Pass(),
860 manage_tiles_call_count_when_dispatched); 894 manage_tiles_call_count_when_dispatched);
861 DispatchMoreTasks();
862 } 895 }
863 896
864 void TileManager::DidFinishTileInitialization(Tile* tile) { 897 void TileManager::DidFinishTileInitialization(Tile* tile) {
865 ManagedTileState& managed_tile_state = tile->managed_state(); 898 ManagedTileState& managed_tile_state = tile->managed_state();
866 DCHECK(managed_tile_state.resource); 899 DCHECK(managed_tile_state.resource);
867 managed_tile_state.resource_is_being_initialized = false; 900 managed_tile_state.resource_is_being_initialized = false;
868 managed_tile_state.can_be_freed = true; 901 managed_tile_state.can_be_freed = true;
869 } 902 }
870 903
871 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { 904 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 decode_begin_time = base::TimeTicks::Now(); 997 decode_begin_time = base::TimeTicks::Now();
965 pixel_ref->Decode(); 998 pixel_ref->Decode();
966 if (stats) { 999 if (stats) {
967 stats->totalDeferredImageDecodeCount++; 1000 stats->totalDeferredImageDecodeCount++;
968 stats->totalDeferredImageDecodeTime += 1001 stats->totalDeferredImageDecodeTime +=
969 base::TimeTicks::Now() - decode_begin_time; 1002 base::TimeTicks::Now() - decode_begin_time;
970 } 1003 }
971 } 1004 }
972 1005
973 } // namespace cc 1006 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tile_manager.h ('k') | cc/worker_pool.h » ('j') | cc/worker_pool.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698