| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 TileManagerClient* client, | 116 TileManagerClient* client, |
| 117 ResourceProvider* resource_provider, | 117 ResourceProvider* resource_provider, |
| 118 size_t num_raster_threads, | 118 size_t num_raster_threads, |
| 119 bool record_rendering_stats, | 119 bool record_rendering_stats, |
| 120 bool use_cheapness_estimator) | 120 bool use_cheapness_estimator) |
| 121 : client_(client), | 121 : client_(client), |
| 122 resource_pool_(ResourcePool::Create(resource_provider)), | 122 resource_pool_(ResourcePool::Create(resource_provider)), |
| 123 raster_worker_pool_(RasterWorkerPool::Create(num_raster_threads, record_re
ndering_stats)), | 123 raster_worker_pool_(RasterWorkerPool::Create(num_raster_threads, record_re
ndering_stats)), |
| 124 manage_tiles_pending_(false), | 124 manage_tiles_pending_(false), |
| 125 manage_tiles_call_count_(0), | 125 manage_tiles_call_count_(0), |
| 126 bytes_pending_set_pixels_(0), | 126 bytes_pending_upload_(0), |
| 127 ever_exceeded_memory_budget_(false), | 127 ever_exceeded_memory_budget_(false), |
| 128 record_rendering_stats_(record_rendering_stats), | 128 record_rendering_stats_(record_rendering_stats), |
| 129 use_cheapness_estimator_(use_cheapness_estimator) { | 129 use_cheapness_estimator_(use_cheapness_estimator) { |
| 130 for (int i = 0; i < NUM_STATES; ++i) { | 130 for (int i = 0; i < NUM_STATES; ++i) { |
| 131 for (int j = 0; j < NUM_TREES; ++j) { | 131 for (int j = 0; j < NUM_TREES; ++j) { |
| 132 for (int k = 0; k < NUM_BINS; ++k) | 132 for (int k = 0; k < NUM_BINS; ++k) |
| 133 raster_state_count_[i][j][k] = 0; | 133 raster_state_count_[i][j][k] = 0; |
| 134 } | 134 } |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 TileManager::~TileManager() { | 138 TileManager::~TileManager() { |
| 139 // Reset global state and manage. This should cause | 139 // Reset global state and manage. This should cause |
| 140 // our memory usage to drop to zero. | 140 // our memory usage to drop to zero. |
| 141 global_state_ = GlobalStateThatImpactsTilePriority(); | 141 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 142 AssignGpuMemoryToTiles(); | 142 AssignGpuMemoryToTiles(); |
| 143 // This should finish all pending tasks and release any uninitialized | 143 // This should finish all pending tasks and release any uninitialized |
| 144 // resources. | 144 // resources. |
| 145 raster_worker_pool_.reset(); | 145 raster_worker_pool_.reset(); |
| 146 CheckForCompletedTileUploads(); | 146 CheckForCompletedTileUploads(); |
| 147 DCHECK(tiles_with_pending_set_pixels_.size() == 0); | 147 DCHECK(tiles_with_pending_upload_.size() == 0); |
| 148 DCHECK(tiles_.size() == 0); | 148 DCHECK(tiles_.size() == 0); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void TileManager::SetGlobalState( | 151 void TileManager::SetGlobalState( |
| 152 const GlobalStateThatImpactsTilePriority& global_state) { | 152 const GlobalStateThatImpactsTilePriority& global_state) { |
| 153 global_state_ = global_state; | 153 global_state_ = global_state; |
| 154 resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); | 154 resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); |
| 155 ScheduleManageTiles(); | 155 ScheduleManageTiles(); |
| 156 } | 156 } |
| 157 | 157 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 // Assign gpu memory and determine what tiles need to be rasterized. | 307 // Assign gpu memory and determine what tiles need to be rasterized. |
| 308 AssignGpuMemoryToTiles(); | 308 AssignGpuMemoryToTiles(); |
| 309 | 309 |
| 310 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", ValueToString(AsValue())); | 310 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", ValueToString(AsValue())); |
| 311 | 311 |
| 312 // Finally, kick the rasterizer. | 312 // Finally, kick the rasterizer. |
| 313 DispatchMoreTasks(); | 313 DispatchMoreTasks(); |
| 314 } | 314 } |
| 315 | 315 |
| 316 void TileManager::CheckForCompletedTileUploads() { | 316 void TileManager::CheckForCompletedTileUploads() { |
| 317 while (!tiles_with_pending_set_pixels_.empty()) { | 317 while (!tiles_with_pending_upload_.empty()) { |
| 318 Tile* tile = tiles_with_pending_set_pixels_.front(); | 318 Tile* tile = tiles_with_pending_upload_.front(); |
| 319 DCHECK(tile->managed_state().resource); | 319 DCHECK(tile->managed_state().resource); |
| 320 | 320 |
| 321 // Set pixel tasks complete in the order they are posted. | 321 // Set pixel tasks complete in the order they are posted. |
| 322 if (!resource_pool_->resource_provider()->didSetPixelsComplete( | 322 if (!resource_pool_->resource_provider()->didSetPixelsComplete( |
| 323 tile->managed_state().resource->id())) { | 323 tile->managed_state().resource->id())) { |
| 324 break; | 324 break; |
| 325 } | 325 } |
| 326 | 326 |
| 327 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0 && | |
| 328 tile->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) | |
| 329 client_->DidUploadVisibleHighResolutionTile(); | |
| 330 | |
| 331 // It's now safe to release the pixel buffer. | 327 // It's now safe to release the pixel buffer. |
| 332 resource_pool_->resource_provider()->releasePixelBuffer( | 328 resource_pool_->resource_provider()->releasePixelBuffer( |
| 333 tile->managed_state().resource->id()); | 329 tile->managed_state().resource->id()); |
| 334 | 330 |
| 335 DidFinishTileInitialization(tile); | 331 DidCompleteTileUpload(tile); |
| 336 | 332 |
| 337 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 333 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); |
| 338 DidTileRasterStateChange(tile, IDLE_STATE); | 334 tiles_with_pending_upload_.pop(); |
| 339 tiles_with_pending_set_pixels_.pop(); | |
| 340 } | 335 } |
| 341 | 336 |
| 342 DispatchMoreTasks(); | 337 DispatchMoreTasks(); |
| 343 } | 338 } |
| 344 | 339 |
| 340 void TileManager::DidCompleteTileUpload(Tile* tile) { |
| 341 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0 && |
| 342 tile->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) |
| 343 client_->DidUploadVisibleHighResolutionTile(); |
| 344 |
| 345 DidFinishTileInitialization(tile); |
| 346 DidTileRasterStateChange(tile, IDLE_STATE); |
| 347 } |
| 348 |
| 345 void TileManager::GetMemoryStats( | 349 void TileManager::GetMemoryStats( |
| 346 size_t* memoryRequiredBytes, | 350 size_t* memoryRequiredBytes, |
| 347 size_t* memoryNiceToHaveBytes, | 351 size_t* memoryNiceToHaveBytes, |
| 348 size_t* memoryUsedBytes) const { | 352 size_t* memoryUsedBytes) const { |
| 349 *memoryRequiredBytes = 0; | 353 *memoryRequiredBytes = 0; |
| 350 *memoryNiceToHaveBytes = 0; | 354 *memoryNiceToHaveBytes = 0; |
| 351 *memoryUsedBytes = 0; | 355 *memoryUsedBytes = 0; |
| 352 for(size_t i = 0; i < tiles_.size(); i++) { | 356 for(size_t i = 0; i < tiles_.size(); i++) { |
| 353 const Tile* tile = tiles_[i]; | 357 const Tile* tile = tiles_[i]; |
| 354 const ManagedTileState& mts = tile->managed_state(); | 358 const ManagedTileState& mts = tile->managed_state(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 | 404 |
| 401 bool TileManager::HasPendingWorkScheduled(WhichTree tree) const { | 405 bool TileManager::HasPendingWorkScheduled(WhichTree tree) const { |
| 402 // Always true when ManageTiles() call is pending. | 406 // Always true when ManageTiles() call is pending. |
| 403 if (manage_tiles_pending_) | 407 if (manage_tiles_pending_) |
| 404 return true; | 408 return true; |
| 405 | 409 |
| 406 for (int i = 0; i < NUM_STATES; ++i) { | 410 for (int i = 0; i < NUM_STATES; ++i) { |
| 407 switch (i) { | 411 switch (i) { |
| 408 case WAITING_FOR_RASTER_STATE: | 412 case WAITING_FOR_RASTER_STATE: |
| 409 case RASTER_STATE: | 413 case RASTER_STATE: |
| 410 case SET_PIXELS_STATE: | 414 case UPLOAD_STATE: |
| 411 for (int j = 0; j < NEVER_BIN; ++j) { | 415 for (int j = 0; j < NEVER_BIN; ++j) { |
| 412 if (raster_state_count_[i][tree][j]) | 416 if (raster_state_count_[i][tree][j]) |
| 413 return true; | 417 return true; |
| 414 } | 418 } |
| 415 break; | 419 break; |
| 416 case IDLE_STATE: | 420 case IDLE_STATE: |
| 417 break; | 421 break; |
| 418 default: | 422 default: |
| 419 NOTREACHED(); | 423 NOTREACHED(); |
| 420 } | 424 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 void TileManager::FreeResourcesForTile(Tile* tile) { | 511 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 508 ManagedTileState& managed_tile_state = tile->managed_state(); | 512 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 509 DCHECK(managed_tile_state.can_be_freed); | 513 DCHECK(managed_tile_state.can_be_freed); |
| 510 if (managed_tile_state.resource) | 514 if (managed_tile_state.resource) |
| 511 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 515 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
| 512 } | 516 } |
| 513 | 517 |
| 514 bool TileManager::CanDispatchRasterTask(Tile* tile) const { | 518 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
| 515 if (raster_worker_pool_->IsBusy()) | 519 if (raster_worker_pool_->IsBusy()) |
| 516 return false; | 520 return false; |
| 517 size_t new_bytes_pending = bytes_pending_set_pixels_; | 521 size_t new_bytes_pending = bytes_pending_upload_; |
| 518 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 522 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
| 519 return new_bytes_pending <= kMaxPendingUploadBytes; | 523 return new_bytes_pending <= kMaxPendingUploadBytes; |
| 520 } | 524 } |
| 521 | 525 |
| 522 bool TileManager::CanPerformCheapRaster(Tile* tile) const { | 526 bool TileManager::CanPerformCheapRaster(Tile* tile) const { |
| 523 if (!use_cheapness_estimator_ || !client_->CanDoAnotherCheapRaster()) | 527 if (!use_cheapness_estimator_ || !client_->CanDoAnotherCheapRaster()) |
| 524 return false; | 528 return false; |
| 525 ManagedTileState& managed_state = tile->managed_state(); | 529 ManagedTileState& managed_state = tile->managed_state(); |
| 526 DCHECK(managed_state.pending_pixel_refs.empty()); | 530 DCHECK(managed_state.pending_pixel_refs.empty()); |
| 527 size_t new_bytes_pending = bytes_pending_set_pixels_; | |
| 528 new_bytes_pending += tile->bytes_consumed_if_allocated(); | |
| 529 if (new_bytes_pending > kMaxPendingUploadBytes) | |
| 530 return false; | |
| 531 return tile->picture_pile()->IsCheapInRect(tile->content_rect_, | 531 return tile->picture_pile()->IsCheapInRect(tile->content_rect_, |
| 532 tile->contents_scale()); | 532 tile->contents_scale()); |
| 533 } | 533 } |
| 534 | 534 |
| 535 void TileManager::DispatchMoreTasks() { | 535 void TileManager::DispatchMoreTasks() { |
| 536 // Because tiles in the image decoding list have higher priorities, we | 536 // Because tiles in the image decoding list have higher priorities, we |
| 537 // need to process those tiles first before we start to handle the tiles | 537 // need to process those tiles first before we start to handle the tiles |
| 538 // in the need_to_be_rasterized queue. | 538 // in the need_to_be_rasterized queue. |
| 539 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 539 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| 540 it != tiles_with_image_decoding_tasks_.end(); ) { | 540 it != tiles_with_image_decoding_tasks_.end(); ) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 694 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
| 695 ResourceProvider::ResourceId resource_id = resource->id(); | 695 ResourceProvider::ResourceId resource_id = resource->id(); |
| 696 | 696 |
| 697 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | 697 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( |
| 698 resource_id), | 698 resource_id), |
| 699 tile->content_rect_, | 699 tile->content_rect_, |
| 700 tile->contents_scale(), | 700 tile->contents_scale(), |
| 701 use_cheapness_estimator_, | 701 use_cheapness_estimator_, |
| 702 tile->picture_pile(), | 702 tile->picture_pile(), |
| 703 &rendering_stats_); | 703 &rendering_stats_); |
| 704 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | 704 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_, |
| 705 TILE_UPLOAD_SYNC); |
| 705 client_->DidPerformCheapRaster(); | 706 client_->DidPerformCheapRaster(); |
| 706 } | 707 } |
| 707 | 708 |
| 708 void TileManager::OnRasterCompleted( | 709 void TileManager::OnRasterCompleted( |
| 709 scoped_refptr<Tile> tile, | 710 scoped_refptr<Tile> tile, |
| 710 scoped_ptr<ResourcePool::Resource> resource, | 711 scoped_ptr<ResourcePool::Resource> resource, |
| 711 int manage_tiles_call_count_when_dispatched) { | 712 int manage_tiles_call_count_when_dispatched, |
| 713 TileUploadMethod upload_method) { |
| 712 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 714 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); |
| 713 | 715 |
| 714 // Release raster resources. | 716 // Release raster resources. |
| 715 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 717 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
| 716 | 718 |
| 717 ManagedTileState& managed_tile_state = tile->managed_state(); | 719 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 718 managed_tile_state.can_be_freed = true; | 720 managed_tile_state.can_be_freed = true; |
| 719 | 721 |
| 720 // Tile can be freed after the completion of the raster task. Call | 722 // Tile can be freed after the completion of the raster task. Call |
| 721 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 723 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority |
| 722 // tiles if ManageTiles() was called since task was dispatched. The result | 724 // tiles if ManageTiles() was called since task was dispatched. The result |
| 723 // of this could be that this tile is no longer allowed to use gpu | 725 // of this could be that this tile is no longer allowed to use gpu |
| 724 // memory and in that case we need to abort initialization and free all | 726 // memory and in that case we need to abort initialization and free all |
| 725 // associated resources before calling DispatchMoreTasks(). | 727 // associated resources before calling DispatchMoreTasks(). |
| 726 if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_) | 728 if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_) |
| 727 AssignGpuMemoryToTiles(); | 729 AssignGpuMemoryToTiles(); |
| 728 | 730 |
| 729 // Finish resource initialization if |can_use_gpu_memory| is true. | 731 // Finish resource initialization if |can_use_gpu_memory| is true. |
| 730 if (managed_tile_state.can_use_gpu_memory) { | 732 if (managed_tile_state.can_use_gpu_memory) { |
| 731 // The component order may be bgra if we're uploading bgra pixels to rgba | 733 // The component order may be bgra if we're uploading bgra pixels to rgba |
| 732 // texture. Mark contents as swizzled if image component order is | 734 // texture. Mark contents as swizzled if image component order is |
| 733 // different than texture format. | 735 // different than texture format. |
| 734 managed_tile_state.contents_swizzled = | 736 managed_tile_state.contents_swizzled = |
| 735 !PlatformColor::sameComponentOrder(tile->format_); | 737 !PlatformColor::sameComponentOrder(tile->format_); |
| 736 | 738 |
| 737 // Tile resources can't be freed until upload has completed. | 739 if (upload_method == TILE_UPLOAD_ASYNC) { |
| 738 managed_tile_state.can_be_freed = false; | 740 // Tile resources can't be freed until upload has completed. |
| 741 managed_tile_state.can_be_freed = false; |
| 739 | 742 |
| 740 resource_pool_->resource_provider()->beginSetPixels(resource->id()); | 743 resource_pool_->resource_provider()->beginSetPixels(resource->id()); |
| 741 resource_pool_->resource_provider()->shallowFlushIfSupported(); | 744 resource_pool_->resource_provider()->shallowFlushIfSupported(); |
| 742 managed_tile_state.resource = resource.Pass(); | 745 managed_tile_state.resource = resource.Pass(); |
| 743 | 746 |
| 744 bytes_pending_set_pixels_ += tile->bytes_consumed_if_allocated(); | 747 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); |
| 745 DidTileRasterStateChange(tile, SET_PIXELS_STATE); | 748 DidTileRasterStateChange(tile, UPLOAD_STATE); |
| 746 tiles_with_pending_set_pixels_.push(tile); | 749 tiles_with_pending_upload_.push(tile); |
| 750 } else { |
| 751 DCHECK(upload_method == TILE_UPLOAD_SYNC); |
| 752 resource_pool_->resource_provider()->setPixelsFromBuffer(resource->id()); |
| 753 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
| 754 managed_tile_state.resource = resource.Pass(); |
| 755 DidCompleteTileUpload(tile); |
| 756 } |
| 747 } else { | 757 } else { |
| 748 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); | 758 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
| 749 resource_pool_->ReleaseResource(resource.Pass()); | 759 resource_pool_->ReleaseResource(resource.Pass()); |
| 750 managed_tile_state.resource_is_being_initialized = false; | 760 managed_tile_state.resource_is_being_initialized = false; |
| 751 DidTileRasterStateChange(tile, IDLE_STATE); | 761 DidTileRasterStateChange(tile, IDLE_STATE); |
| 752 } | 762 } |
| 753 } | 763 } |
| 754 | 764 |
| 755 void TileManager::OnRasterTaskCompleted( | 765 void TileManager::OnRasterTaskCompleted( |
| 756 scoped_refptr<Tile> tile, | 766 scoped_refptr<Tile> tile, |
| 757 scoped_ptr<ResourcePool::Resource> resource, | 767 scoped_ptr<ResourcePool::Resource> resource, |
| 758 int manage_tiles_call_count_when_dispatched) { | 768 int manage_tiles_call_count_when_dispatched) { |
| 759 OnRasterCompleted(tile, resource.Pass(), | 769 OnRasterCompleted(tile, resource.Pass(), |
| 760 manage_tiles_call_count_when_dispatched); | 770 manage_tiles_call_count_when_dispatched, |
| 771 TILE_UPLOAD_ASYNC); |
| 761 DispatchMoreTasks(); | 772 DispatchMoreTasks(); |
| 762 } | 773 } |
| 763 | 774 |
| 764 void TileManager::DidFinishTileInitialization(Tile* tile) { | 775 void TileManager::DidFinishTileInitialization(Tile* tile) { |
| 765 ManagedTileState& managed_tile_state = tile->managed_state(); | 776 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 766 DCHECK(managed_tile_state.resource); | 777 DCHECK(managed_tile_state.resource); |
| 767 managed_tile_state.resource_is_being_initialized = false; | 778 managed_tile_state.resource_is_being_initialized = false; |
| 768 managed_tile_state.can_be_freed = true; | 779 managed_tile_state.can_be_freed = true; |
| 769 } | 780 } |
| 770 | 781 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 decode_begin_time = base::TimeTicks::Now(); | 875 decode_begin_time = base::TimeTicks::Now(); |
| 865 pixel_ref->Decode(); | 876 pixel_ref->Decode(); |
| 866 if (stats) { | 877 if (stats) { |
| 867 stats->totalDeferredImageDecodeCount++; | 878 stats->totalDeferredImageDecodeCount++; |
| 868 stats->totalDeferredImageDecodeTime += | 879 stats->totalDeferredImageDecodeTime += |
| 869 base::TimeTicks::Now() - decode_begin_time; | 880 base::TimeTicks::Now() - decode_begin_time; |
| 870 } | 881 } |
| 871 } | 882 } |
| 872 | 883 |
| 873 } // namespace cc | 884 } // namespace cc |
| OLD | NEW |