Chromium Code Reviews| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 | 665 |
| 662 mts.visible_and_ready_to_draw = | 666 mts.visible_and_ready_to_draw = |
| 663 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN; | 667 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN; |
| 664 | 668 |
| 665 // If the tile is in NEVER_BIN and it does not have an active task, then we | 669 // If the tile is in NEVER_BIN and it does not have an active task, then we |
| 666 // can release the resources early. If it does have the task however, we | 670 // can release the resources early. If it does have the task however, we |
| 667 // should keep it in the prioritized tile set to ensure that AssignGpuMemory | 671 // should keep it in the prioritized tile set to ensure that AssignGpuMemory |
| 668 // can visit it. | 672 // can visit it. |
| 669 if (mts.bin == NEVER_BIN && | 673 if (mts.bin == NEVER_BIN && |
| 670 !mts.tile_versions[mts.raster_mode].raster_task_) { | 674 !mts.tile_versions[mts.raster_mode].raster_task_) { |
| 671 FreeResourcesForTile(tile); | 675 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
|
vmpstr
2014/05/16 17:09:06
yay 56 character function names :P
| |
| 672 continue; | 676 continue; |
| 673 } | 677 } |
| 674 | 678 |
| 675 // Insert the tile into a priority set. | 679 // Insert the tile into a priority set. |
| 676 tiles->InsertTile(tile, mts.bin); | 680 tiles->InsertTile(tile, mts.bin); |
| 677 } | 681 } |
| 678 } | 682 } |
| 679 | 683 |
| 680 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { | 684 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { |
| 681 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 685 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 | 839 |
| 836 ManagedTileState::TileVersion& tile_version = | 840 ManagedTileState::TileVersion& tile_version = |
| 837 mts.tile_versions[mts.raster_mode]; | 841 mts.tile_versions[mts.raster_mode]; |
| 838 | 842 |
| 839 // If this tile doesn't need a resource, then nothing to do. | 843 // If this tile doesn't need a resource, then nothing to do. |
| 840 if (!tile_version.requires_resource()) | 844 if (!tile_version.requires_resource()) |
| 841 continue; | 845 continue; |
| 842 | 846 |
| 843 // If the tile is not needed, free it up. | 847 // If the tile is not needed, free it up. |
| 844 if (mts.bin == NEVER_BIN) { | 848 if (mts.bin == NEVER_BIN) { |
| 845 FreeResourcesForTile(tile); | 849 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
| 846 continue; | 850 continue; |
| 847 } | 851 } |
| 848 | 852 |
| 849 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; | 853 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; |
| 850 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); | 854 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); |
| 851 const size_t tile_bytes_left = | 855 const size_t tile_bytes_left = |
| 852 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; | 856 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; |
| 853 | 857 |
| 854 // Hard-limit is reserved for tiles that would cause a calamity | 858 // Hard-limit is reserved for tiles that would cause a calamity |
| 855 // if they were to go away, so by definition they are the highest | 859 // if they were to go away, so by definition they are the highest |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 877 // If we don't have the required version, and it's not in flight | 881 // If we don't have the required version, and it's not in flight |
| 878 // then we'll have to pay to create a new task. | 882 // then we'll have to pay to create a new task. |
| 879 if (!tile_version.resource_ && !tile_version.raster_task_) { | 883 if (!tile_version.resource_ && !tile_version.raster_task_) { |
| 880 tile_bytes += bytes_if_allocated; | 884 tile_bytes += bytes_if_allocated; |
| 881 tile_resources++; | 885 tile_resources++; |
| 882 } | 886 } |
| 883 } | 887 } |
| 884 | 888 |
| 885 // Tile is OOM. | 889 // Tile is OOM. |
| 886 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { | 890 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { |
| 891 bool was_ready_to_draw = tile->IsReadyToDraw(); | |
| 892 | |
| 887 FreeResourcesForTile(tile); | 893 FreeResourcesForTile(tile); |
| 888 | 894 |
| 889 // This tile was already on screen and now its resources have been | 895 // This tile was already on screen and now its resources have been |
| 890 // released. In order to prevent checkerboarding, set this tile as | 896 // released. In order to prevent checkerboarding, set this tile as |
| 891 // rasterize on demand immediately. | 897 // rasterize on demand immediately. |
| 892 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) | 898 if (mts.visible_and_ready_to_draw) |
| 893 tile_version.set_rasterize_on_demand(); | 899 tile_version.set_rasterize_on_demand(); |
| 894 | 900 |
| 901 if (was_ready_to_draw) | |
| 902 client_->NotifyTileStateChanged(tile); | |
| 903 | |
| 895 oomed_soft = true; | 904 oomed_soft = true; |
| 896 if (tile_uses_hard_limit) { | 905 if (tile_uses_hard_limit) { |
| 897 oomed_hard = true; | 906 oomed_hard = true; |
| 898 bytes_that_exceeded_memory_budget += tile_bytes; | 907 bytes_that_exceeded_memory_budget += tile_bytes; |
| 899 } | 908 } |
| 900 } else { | 909 } else { |
| 901 resources_left -= tile_resources; | 910 resources_left -= tile_resources; |
| 902 hard_bytes_left -= tile_bytes; | 911 hard_bytes_left -= tile_bytes; |
| 903 soft_bytes_left = | 912 soft_bytes_left = |
| 904 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; | 913 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 979 break; | 988 break; |
| 980 } | 989 } |
| 981 } | 990 } |
| 982 | 991 |
| 983 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 992 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 984 if (mode != used_mode) | 993 if (mode != used_mode) |
| 985 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); | 994 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
| 986 } | 995 } |
| 987 } | 996 } |
| 988 | 997 |
| 998 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | |
| 999 Tile* tile) { | |
| 1000 bool was_ready_to_draw = tile->IsReadyToDraw(); | |
| 1001 FreeResourcesForTile(tile); | |
| 1002 if (was_ready_to_draw) | |
| 1003 client_->NotifyTileStateChanged(tile); | |
| 1004 } | |
| 1005 | |
| 989 void TileManager::ScheduleTasks( | 1006 void TileManager::ScheduleTasks( |
| 990 const TileVector& tiles_that_need_to_be_rasterized) { | 1007 const TileVector& tiles_that_need_to_be_rasterized) { |
| 991 TRACE_EVENT1("cc", | 1008 TRACE_EVENT1("cc", |
| 992 "TileManager::ScheduleTasks", | 1009 "TileManager::ScheduleTasks", |
| 993 "count", | 1010 "count", |
| 994 tiles_that_need_to_be_rasterized.size()); | 1011 tiles_that_need_to_be_rasterized.size()); |
| 995 | 1012 |
| 996 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 1013 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
| 997 | 1014 |
| 998 for (size_t i = 0; i < NUM_RASTERIZER_TYPES; ++i) | 1015 for (size_t i = 0; i < NUM_RASTERIZER_TYPES; ++i) |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1175 tile_version.set_solid_color(analysis.solid_color); | 1192 tile_version.set_solid_color(analysis.solid_color); |
| 1176 resource_pool_->ReleaseResource(resource.Pass()); | 1193 resource_pool_->ReleaseResource(resource.Pass()); |
| 1177 } else { | 1194 } else { |
| 1178 tile_version.set_use_resource(); | 1195 tile_version.set_use_resource(); |
| 1179 tile_version.resource_ = resource.Pass(); | 1196 tile_version.resource_ = resource.Pass(); |
| 1180 | 1197 |
| 1181 bytes_releasable_ += BytesConsumedIfAllocated(tile); | 1198 bytes_releasable_ += BytesConsumedIfAllocated(tile); |
| 1182 ++resources_releasable_; | 1199 ++resources_releasable_; |
| 1183 } | 1200 } |
| 1184 | 1201 |
| 1185 client_->NotifyTileInitialized(tile); | |
| 1186 | |
| 1187 FreeUnusedResourcesForTile(tile); | 1202 FreeUnusedResourcesForTile(tile); |
| 1188 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) | 1203 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) |
| 1189 did_initialize_visible_tile_ = true; | 1204 did_initialize_visible_tile_ = true; |
| 1205 | |
| 1206 client_->NotifyTileStateChanged(tile); | |
| 1190 } | 1207 } |
| 1191 | 1208 |
| 1192 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, | 1209 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, |
| 1193 const gfx::Size& tile_size, | 1210 const gfx::Size& tile_size, |
| 1194 const gfx::Rect& content_rect, | 1211 const gfx::Rect& content_rect, |
| 1195 const gfx::Rect& opaque_rect, | 1212 const gfx::Rect& opaque_rect, |
| 1196 float contents_scale, | 1213 float contents_scale, |
| 1197 int layer_id, | 1214 int layer_id, |
| 1198 int source_frame_number, | 1215 int source_frame_number, |
| 1199 int flags) { | 1216 int flags) { |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1615 return a_priority.IsHigherPriorityThan(b_priority); | 1632 return a_priority.IsHigherPriorityThan(b_priority); |
| 1616 } | 1633 } |
| 1617 | 1634 |
| 1618 void TileManager::SetRasterizersForTesting(Rasterizer* rasterizer, | 1635 void TileManager::SetRasterizersForTesting(Rasterizer* rasterizer, |
| 1619 Rasterizer* gpu_rasterizer) { | 1636 Rasterizer* gpu_rasterizer) { |
| 1620 Rasterizer* rasterizers[2] = {rasterizer, gpu_rasterizer}; | 1637 Rasterizer* rasterizers[2] = {rasterizer, gpu_rasterizer}; |
| 1621 rasterizer_delegate_ = | 1638 rasterizer_delegate_ = |
| 1622 RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); | 1639 RasterizerDelegate::Create(this, rasterizers, arraysize(rasterizers)); |
| 1623 } | 1640 } |
| 1624 | 1641 |
| 1642 bool TileManager::IsReadyToActivate() const { | |
| 1643 for (std::vector<PictureLayerImpl*>::const_iterator it = layers_.begin(); | |
| 1644 it != layers_.end(); | |
| 1645 ++it) { | |
| 1646 if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw()) | |
| 1647 return false; | |
| 1648 } | |
| 1649 | |
| 1650 return true; | |
| 1651 } | |
| 1652 | |
| 1653 void TileManager::ScheduleCheckIfReadyToActivate() { | |
| 1654 if (check_if_ready_to_activate_pending_) | |
| 1655 return; | |
| 1656 | |
| 1657 task_runner_->PostTask(FROM_HERE, | |
| 1658 base::Bind(&TileManager::CheckIfReadyToActivate, | |
| 1659 weak_ptr_factory_.GetWeakPtr())); | |
| 1660 check_if_ready_to_activate_pending_ = true; | |
| 1661 } | |
| 1662 | |
| 1663 void TileManager::CheckIfReadyToActivate() { | |
| 1664 DCHECK(check_if_ready_to_activate_pending_); | |
| 1665 check_if_ready_to_activate_pending_ = false; | |
| 1666 | |
| 1667 rasterizer_delegate_->CheckForCompletedTasks(); | |
| 1668 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | |
| 1669 | |
| 1670 if (IsReadyToActivate()) | |
| 1671 client_->NotifyReadyToActivate(); | |
| 1672 } | |
| 1673 | |
| 1625 } // namespace cc | 1674 } // namespace cc |
| OLD | NEW |