| 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/resources/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 const RasterTaskCompletionStats& stats) { | 358 const RasterTaskCompletionStats& stats) { |
| 359 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 359 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 360 state->SetInteger("completed_count", stats.completed_count); | 360 state->SetInteger("completed_count", stats.completed_count); |
| 361 state->SetInteger("canceled_count", stats.canceled_count); | 361 state->SetInteger("canceled_count", stats.canceled_count); |
| 362 return state.PassAs<base::Value>(); | 362 return state.PassAs<base::Value>(); |
| 363 } | 363 } |
| 364 | 364 |
| 365 // static | 365 // static |
| 366 scoped_ptr<TileManager> TileManager::Create( | 366 scoped_ptr<TileManager> TileManager::Create( |
| 367 TileManagerClient* client, | 367 TileManagerClient* client, |
| 368 base::SequencedTaskRunner* task_runner, |
| 368 ResourcePool* resource_pool, | 369 ResourcePool* resource_pool, |
| 369 Rasterizer* rasterizer, | 370 Rasterizer* rasterizer, |
| 370 Rasterizer* gpu_rasterizer, | 371 Rasterizer* gpu_rasterizer, |
| 371 bool use_rasterize_on_demand, | |
| 372 RenderingStatsInstrumentation* rendering_stats_instrumentation) { | 372 RenderingStatsInstrumentation* rendering_stats_instrumentation) { |
| 373 return make_scoped_ptr(new TileManager(client, | 373 return make_scoped_ptr(new TileManager(client, |
| 374 task_runner, |
| 374 resource_pool, | 375 resource_pool, |
| 375 rasterizer, | 376 rasterizer, |
| 376 gpu_rasterizer, | 377 gpu_rasterizer, |
| 377 use_rasterize_on_demand, | |
| 378 rendering_stats_instrumentation)); | 378 rendering_stats_instrumentation)); |
| 379 } | 379 } |
| 380 | 380 |
| 381 TileManager::TileManager( | 381 TileManager::TileManager( |
| 382 TileManagerClient* client, | 382 TileManagerClient* client, |
| 383 base::SequencedTaskRunner* task_runner, |
| 383 ResourcePool* resource_pool, | 384 ResourcePool* resource_pool, |
| 384 Rasterizer* rasterizer, | 385 Rasterizer* rasterizer, |
| 385 Rasterizer* gpu_rasterizer, | 386 Rasterizer* gpu_rasterizer, |
| 386 bool use_rasterize_on_demand, | |
| 387 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 387 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
| 388 : client_(client), | 388 : client_(client), |
| 389 task_runner_(task_runner), |
| 389 resource_pool_(resource_pool), | 390 resource_pool_(resource_pool), |
| 390 prioritized_tiles_dirty_(false), | 391 prioritized_tiles_dirty_(false), |
| 391 all_tiles_that_need_to_be_rasterized_have_memory_(true), | 392 all_tiles_that_need_to_be_rasterized_have_memory_(true), |
| 392 all_tiles_required_for_activation_have_memory_(true), | 393 all_tiles_required_for_activation_have_memory_(true), |
| 393 memory_required_bytes_(0), | 394 memory_required_bytes_(0), |
| 394 memory_nice_to_have_bytes_(0), | 395 memory_nice_to_have_bytes_(0), |
| 395 bytes_releasable_(0), | 396 bytes_releasable_(0), |
| 396 resources_releasable_(0), | 397 resources_releasable_(0), |
| 397 ever_exceeded_memory_budget_(false), | 398 ever_exceeded_memory_budget_(false), |
| 398 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 399 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 399 did_initialize_visible_tile_(false), | 400 did_initialize_visible_tile_(false), |
| 400 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 401 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 401 use_rasterize_on_demand_(use_rasterize_on_demand) { | 402 check_if_ready_to_activate_pending_(false), |
| 403 weak_ptr_factory_(this) { |
| 402 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { | 404 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { |
| 403 rasterizer, // RASTERIZER_TYPE_DEFAULT | 405 rasterizer, // RASTERIZER_TYPE_DEFAULT |
| 404 gpu_rasterizer, // RASTERIZER_TYPE_GPU | 406 gpu_rasterizer, // RASTERIZER_TYPE_GPU |
| 405 }; | 407 }; |
| 406 rasterizer_delegate_ = | 408 rasterizer_delegate_ = |
| 407 RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); | 409 RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); |
| 408 } | 410 } |
| 409 | 411 |
| 410 TileManager::~TileManager() { | 412 TileManager::~TileManager() { |
| 411 // Reset global state and manage. This should cause | 413 // Reset global state and manage. This should cause |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 530 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 529 Tile* tile = it->second; | 531 Tile* tile = it->second; |
| 530 ManagedTileState& mts = tile->managed_state(); | 532 ManagedTileState& mts = tile->managed_state(); |
| 531 ManagedTileState::TileVersion& tile_version = | 533 ManagedTileState::TileVersion& tile_version = |
| 532 mts.tile_versions[mts.raster_mode]; | 534 mts.tile_versions[mts.raster_mode]; |
| 533 | 535 |
| 534 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { | 536 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { |
| 535 // If we can't raster on demand, give up early (and don't activate). | 537 // If we can't raster on demand, give up early (and don't activate). |
| 536 if (!allow_rasterize_on_demand) | 538 if (!allow_rasterize_on_demand) |
| 537 return; | 539 return; |
| 538 if (use_rasterize_on_demand_) | 540 |
| 539 tile_version.set_rasterize_on_demand(); | 541 tile_version.set_rasterize_on_demand(); |
| 542 client_->NotifyTileStateChanged(tile); |
| 540 } | 543 } |
| 541 } | 544 } |
| 542 | 545 |
| 543 client_->NotifyReadyToActivate(); | 546 DCHECK(IsReadyToActivate()); |
| 547 ScheduleCheckIfReadyToActivate(); |
| 544 } | 548 } |
| 545 | 549 |
| 546 void TileManager::DidFinishRunningTasksRequiredForActivation() { | 550 void TileManager::DidFinishRunningTasksRequiredForActivation() { |
| 547 // This is only a true indication that all tiles required for | 551 // This is only a true indication that all tiles required for |
| 548 // activation are initialized when no tiles are OOM. We need to | 552 // activation are initialized when no tiles are OOM. We need to |
| 549 // wait for DidFinishRunningTasks() to be called, try to re-assign | 553 // wait for DidFinishRunningTasks() to be called, try to re-assign |
| 550 // memory and in worst case use on-demand raster when tiles | 554 // memory and in worst case use on-demand raster when tiles |
| 551 // required for activation are OOM. | 555 // required for activation are OOM. |
| 552 if (!all_tiles_required_for_activation_have_memory_) | 556 if (!all_tiles_required_for_activation_have_memory_) |
| 553 return; | 557 return; |
| 554 | 558 |
| 555 client_->NotifyReadyToActivate(); | 559 ScheduleCheckIfReadyToActivate(); |
| 556 } | 560 } |
| 557 | 561 |
| 558 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { | 562 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { |
| 559 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); | 563 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); |
| 560 | 564 |
| 561 // Compute new stats to be return by GetMemoryStats(). | 565 // Compute new stats to be return by GetMemoryStats(). |
| 562 memory_required_bytes_ = 0; | 566 memory_required_bytes_ = 0; |
| 563 memory_nice_to_have_bytes_ = 0; | 567 memory_nice_to_have_bytes_ = 0; |
| 564 | 568 |
| 565 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; | 569 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 DCHECK(!mts.required_for_activation || mts.bin != NEVER_BIN || | 668 DCHECK(!mts.required_for_activation || mts.bin != NEVER_BIN || |
| 665 tree_priority == SMOOTHNESS_TAKES_PRIORITY || | 669 tree_priority == SMOOTHNESS_TAKES_PRIORITY || |
| 666 memory_policy == ALLOW_NOTHING); | 670 memory_policy == ALLOW_NOTHING); |
| 667 | 671 |
| 668 // If the tile is in NEVER_BIN and it does not have an active task, then we | 672 // If the tile is in NEVER_BIN and it does not have an active task, then we |
| 669 // can release the resources early. If it does have the task however, we | 673 // can release the resources early. If it does have the task however, we |
| 670 // should keep it in the prioritized tile set to ensure that AssignGpuMemory | 674 // should keep it in the prioritized tile set to ensure that AssignGpuMemory |
| 671 // can visit it. | 675 // can visit it. |
| 672 if (mts.bin == NEVER_BIN && | 676 if (mts.bin == NEVER_BIN && |
| 673 !mts.tile_versions[mts.raster_mode].raster_task_) { | 677 !mts.tile_versions[mts.raster_mode].raster_task_) { |
| 674 FreeResourcesForTile(tile); | 678 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
| 675 continue; | 679 continue; |
| 676 } | 680 } |
| 677 | 681 |
| 678 // Insert the tile into a priority set. | 682 // Insert the tile into a priority set. |
| 679 tiles->InsertTile(tile, mts.bin); | 683 tiles->InsertTile(tile, mts.bin); |
| 680 } | 684 } |
| 681 } | 685 } |
| 682 | 686 |
| 683 void TileManager::CleanUpLayers() { | 687 void TileManager::CleanUpLayers() { |
| 684 for (size_t i = 0; i < layers_.size(); ++i) { | 688 for (size_t i = 0; i < layers_.size(); ++i) { |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 | 857 |
| 854 ManagedTileState::TileVersion& tile_version = | 858 ManagedTileState::TileVersion& tile_version = |
| 855 mts.tile_versions[mts.raster_mode]; | 859 mts.tile_versions[mts.raster_mode]; |
| 856 | 860 |
| 857 // If this tile doesn't need a resource, then nothing to do. | 861 // If this tile doesn't need a resource, then nothing to do. |
| 858 if (!tile_version.requires_resource()) | 862 if (!tile_version.requires_resource()) |
| 859 continue; | 863 continue; |
| 860 | 864 |
| 861 // If the tile is not needed, free it up. | 865 // If the tile is not needed, free it up. |
| 862 if (mts.bin == NEVER_BIN) { | 866 if (mts.bin == NEVER_BIN) { |
| 863 FreeResourcesForTile(tile); | 867 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
| 864 continue; | 868 continue; |
| 865 } | 869 } |
| 866 | 870 |
| 867 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; | 871 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; |
| 868 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); | 872 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); |
| 869 const size_t tile_bytes_left = | 873 const size_t tile_bytes_left = |
| 870 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; | 874 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; |
| 871 | 875 |
| 872 // Hard-limit is reserved for tiles that would cause a calamity | 876 // Hard-limit is reserved for tiles that would cause a calamity |
| 873 // if they were to go away, so by definition they are the highest | 877 // if they were to go away, so by definition they are the highest |
| (...skipping 21 matching lines...) Expand all Loading... |
| 895 // If we don't have the required version, and it's not in flight | 899 // If we don't have the required version, and it's not in flight |
| 896 // then we'll have to pay to create a new task. | 900 // then we'll have to pay to create a new task. |
| 897 if (!tile_version.resource_ && !tile_version.raster_task_) { | 901 if (!tile_version.resource_ && !tile_version.raster_task_) { |
| 898 tile_bytes += bytes_if_allocated; | 902 tile_bytes += bytes_if_allocated; |
| 899 tile_resources++; | 903 tile_resources++; |
| 900 } | 904 } |
| 901 } | 905 } |
| 902 | 906 |
| 903 // Tile is OOM. | 907 // Tile is OOM. |
| 904 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { | 908 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { |
| 909 bool was_ready_to_draw = tile->IsReadyToDraw(); |
| 910 |
| 905 FreeResourcesForTile(tile); | 911 FreeResourcesForTile(tile); |
| 906 | 912 |
| 907 // This tile was already on screen and now its resources have been | 913 // This tile was already on screen and now its resources have been |
| 908 // released. In order to prevent checkerboarding, set this tile as | 914 // released. In order to prevent checkerboarding, set this tile as |
| 909 // rasterize on demand immediately. | 915 // rasterize on demand immediately. |
| 910 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) | 916 if (mts.visible_and_ready_to_draw) |
| 911 tile_version.set_rasterize_on_demand(); | 917 tile_version.set_rasterize_on_demand(); |
| 912 | 918 |
| 919 if (was_ready_to_draw) |
| 920 client_->NotifyTileStateChanged(tile); |
| 921 |
| 913 oomed_soft = true; | 922 oomed_soft = true; |
| 914 if (tile_uses_hard_limit) { | 923 if (tile_uses_hard_limit) { |
| 915 oomed_hard = true; | 924 oomed_hard = true; |
| 916 bytes_that_exceeded_memory_budget += tile_bytes; | 925 bytes_that_exceeded_memory_budget += tile_bytes; |
| 917 } | 926 } |
| 918 } else { | 927 } else { |
| 919 resources_left -= tile_resources; | 928 resources_left -= tile_resources; |
| 920 hard_bytes_left -= tile_bytes; | 929 hard_bytes_left -= tile_bytes; |
| 921 soft_bytes_left = | 930 soft_bytes_left = |
| 922 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; | 931 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 break; | 1006 break; |
| 998 } | 1007 } |
| 999 } | 1008 } |
| 1000 | 1009 |
| 1001 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 1010 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 1002 if (mode != used_mode) | 1011 if (mode != used_mode) |
| 1003 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); | 1012 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
| 1004 } | 1013 } |
| 1005 } | 1014 } |
| 1006 | 1015 |
| 1016 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
| 1017 Tile* tile) { |
| 1018 bool was_ready_to_draw = tile->IsReadyToDraw(); |
| 1019 FreeResourcesForTile(tile); |
| 1020 if (was_ready_to_draw) |
| 1021 client_->NotifyTileStateChanged(tile); |
| 1022 } |
| 1023 |
| 1007 void TileManager::ScheduleTasks( | 1024 void TileManager::ScheduleTasks( |
| 1008 const TileVector& tiles_that_need_to_be_rasterized) { | 1025 const TileVector& tiles_that_need_to_be_rasterized) { |
| 1009 TRACE_EVENT1("cc", | 1026 TRACE_EVENT1("cc", |
| 1010 "TileManager::ScheduleTasks", | 1027 "TileManager::ScheduleTasks", |
| 1011 "count", | 1028 "count", |
| 1012 tiles_that_need_to_be_rasterized.size()); | 1029 tiles_that_need_to_be_rasterized.size()); |
| 1013 | 1030 |
| 1014 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 1031 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
| 1015 | 1032 |
| 1016 for (size_t i = 0; i < NUM_RASTERIZER_TYPES; ++i) | 1033 for (size_t i = 0; i < NUM_RASTERIZER_TYPES; ++i) |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 tile_version.set_solid_color(analysis.solid_color); | 1210 tile_version.set_solid_color(analysis.solid_color); |
| 1194 resource_pool_->ReleaseResource(resource.Pass()); | 1211 resource_pool_->ReleaseResource(resource.Pass()); |
| 1195 } else { | 1212 } else { |
| 1196 tile_version.set_use_resource(); | 1213 tile_version.set_use_resource(); |
| 1197 tile_version.resource_ = resource.Pass(); | 1214 tile_version.resource_ = resource.Pass(); |
| 1198 | 1215 |
| 1199 bytes_releasable_ += BytesConsumedIfAllocated(tile); | 1216 bytes_releasable_ += BytesConsumedIfAllocated(tile); |
| 1200 ++resources_releasable_; | 1217 ++resources_releasable_; |
| 1201 } | 1218 } |
| 1202 | 1219 |
| 1203 client_->NotifyTileInitialized(tile); | |
| 1204 | |
| 1205 FreeUnusedResourcesForTile(tile); | 1220 FreeUnusedResourcesForTile(tile); |
| 1206 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) | 1221 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) |
| 1207 did_initialize_visible_tile_ = true; | 1222 did_initialize_visible_tile_ = true; |
| 1223 |
| 1224 client_->NotifyTileStateChanged(tile); |
| 1208 } | 1225 } |
| 1209 | 1226 |
| 1210 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, | 1227 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, |
| 1211 const gfx::Size& tile_size, | 1228 const gfx::Size& tile_size, |
| 1212 const gfx::Rect& content_rect, | 1229 const gfx::Rect& content_rect, |
| 1213 const gfx::Rect& opaque_rect, | 1230 const gfx::Rect& opaque_rect, |
| 1214 float contents_scale, | 1231 float contents_scale, |
| 1215 int layer_id, | 1232 int layer_id, |
| 1216 int source_frame_number, | 1233 int source_frame_number, |
| 1217 int flags) { | 1234 int flags) { |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1633 return a_priority.IsHigherPriorityThan(b_priority); | 1650 return a_priority.IsHigherPriorityThan(b_priority); |
| 1634 } | 1651 } |
| 1635 | 1652 |
| 1636 void TileManager::SetRasterizersForTesting(Rasterizer* rasterizer, | 1653 void TileManager::SetRasterizersForTesting(Rasterizer* rasterizer, |
| 1637 Rasterizer* gpu_rasterizer) { | 1654 Rasterizer* gpu_rasterizer) { |
| 1638 Rasterizer* rasterizers[2] = {rasterizer, gpu_rasterizer}; | 1655 Rasterizer* rasterizers[2] = {rasterizer, gpu_rasterizer}; |
| 1639 rasterizer_delegate_ = | 1656 rasterizer_delegate_ = |
| 1640 RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); | 1657 RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); |
| 1641 } | 1658 } |
| 1642 | 1659 |
| 1660 bool TileManager::IsReadyToActivate() const { |
| 1661 for (std::vector<PictureLayerImpl*>::const_iterator it = layers_.begin(); |
| 1662 it != layers_.end(); |
| 1663 ++it) { |
| 1664 if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw()) |
| 1665 return false; |
| 1666 } |
| 1667 |
| 1668 return true; |
| 1669 } |
| 1670 |
| 1671 void TileManager::ScheduleCheckIfReadyToActivate() { |
| 1672 if (check_if_ready_to_activate_pending_) |
| 1673 return; |
| 1674 |
| 1675 task_runner_->PostTask(FROM_HERE, |
| 1676 base::Bind(&TileManager::CheckIfReadyToActivate, |
| 1677 weak_ptr_factory_.GetWeakPtr())); |
| 1678 check_if_ready_to_activate_pending_ = true; |
| 1679 } |
| 1680 |
| 1681 void TileManager::CheckIfReadyToActivate() { |
| 1682 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
| 1683 |
| 1684 DCHECK(check_if_ready_to_activate_pending_); |
| 1685 check_if_ready_to_activate_pending_ = false; |
| 1686 |
| 1687 rasterizer_delegate_->CheckForCompletedTasks(); |
| 1688 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 1689 |
| 1690 if (IsReadyToActivate()) |
| 1691 client_->NotifyReadyToActivate(); |
| 1692 } |
| 1693 |
| 1643 } // namespace cc | 1694 } // namespace cc |
| OLD | NEW |