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, | |
369 ResourcePool* resource_pool, | 368 ResourcePool* resource_pool, |
370 Rasterizer* rasterizer, | 369 Rasterizer* rasterizer, |
| 370 bool use_rasterize_on_demand, |
371 RenderingStatsInstrumentation* rendering_stats_instrumentation) { | 371 RenderingStatsInstrumentation* rendering_stats_instrumentation) { |
372 return make_scoped_ptr(new TileManager(client, | 372 return make_scoped_ptr(new TileManager(client, |
373 task_runner, | |
374 resource_pool, | 373 resource_pool, |
375 rasterizer, | 374 rasterizer, |
| 375 use_rasterize_on_demand, |
376 rendering_stats_instrumentation)); | 376 rendering_stats_instrumentation)); |
377 } | 377 } |
378 | 378 |
379 TileManager::TileManager( | 379 TileManager::TileManager( |
380 TileManagerClient* client, | 380 TileManagerClient* client, |
381 base::SequencedTaskRunner* task_runner, | |
382 ResourcePool* resource_pool, | 381 ResourcePool* resource_pool, |
383 Rasterizer* rasterizer, | 382 Rasterizer* rasterizer, |
| 383 bool use_rasterize_on_demand, |
384 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 384 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
385 : client_(client), | 385 : client_(client), |
386 task_runner_(task_runner), | |
387 resource_pool_(resource_pool), | 386 resource_pool_(resource_pool), |
388 rasterizer_(rasterizer), | 387 rasterizer_(rasterizer), |
389 prioritized_tiles_dirty_(false), | 388 prioritized_tiles_dirty_(false), |
390 all_tiles_that_need_to_be_rasterized_have_memory_(true), | 389 all_tiles_that_need_to_be_rasterized_have_memory_(true), |
391 all_tiles_required_for_activation_have_memory_(true), | 390 all_tiles_required_for_activation_have_memory_(true), |
392 memory_required_bytes_(0), | 391 memory_required_bytes_(0), |
393 memory_nice_to_have_bytes_(0), | 392 memory_nice_to_have_bytes_(0), |
394 bytes_releasable_(0), | 393 bytes_releasable_(0), |
395 resources_releasable_(0), | 394 resources_releasable_(0), |
396 ever_exceeded_memory_budget_(false), | 395 ever_exceeded_memory_budget_(false), |
397 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 396 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
398 did_initialize_visible_tile_(false), | 397 did_initialize_visible_tile_(false), |
399 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 398 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
400 check_if_ready_to_activate_pending_(false), | 399 use_rasterize_on_demand_(use_rasterize_on_demand) { |
401 weak_ptr_factory_(this) { | |
402 rasterizer_->SetClient(this); | 400 rasterizer_->SetClient(this); |
403 } | 401 } |
404 | 402 |
405 TileManager::~TileManager() { | 403 TileManager::~TileManager() { |
406 // Reset global state and manage. This should cause | 404 // Reset global state and manage. This should cause |
407 // our memory usage to drop to zero. | 405 // our memory usage to drop to zero. |
408 global_state_ = GlobalStateThatImpactsTilePriority(); | 406 global_state_ = GlobalStateThatImpactsTilePriority(); |
409 | 407 |
410 CleanUpReleasedTiles(); | 408 CleanUpReleasedTiles(); |
411 DCHECK_EQ(0u, tiles_.size()); | 409 DCHECK_EQ(0u, tiles_.size()); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 521 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
524 Tile* tile = it->second; | 522 Tile* tile = it->second; |
525 ManagedTileState& mts = tile->managed_state(); | 523 ManagedTileState& mts = tile->managed_state(); |
526 ManagedTileState::TileVersion& tile_version = | 524 ManagedTileState::TileVersion& tile_version = |
527 mts.tile_versions[mts.raster_mode]; | 525 mts.tile_versions[mts.raster_mode]; |
528 | 526 |
529 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { | 527 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { |
530 // If we can't raster on demand, give up early (and don't activate). | 528 // If we can't raster on demand, give up early (and don't activate). |
531 if (!allow_rasterize_on_demand) | 529 if (!allow_rasterize_on_demand) |
532 return; | 530 return; |
533 | 531 if (use_rasterize_on_demand_) |
534 tile_version.set_rasterize_on_demand(); | 532 tile_version.set_rasterize_on_demand(); |
535 client_->NotifyTileStateChanged(tile); | |
536 } | 533 } |
537 } | 534 } |
538 | 535 |
539 DCHECK(IsReadyToActivate()); | 536 client_->NotifyReadyToActivate(); |
540 ScheduleCheckIfReadyToActivate(); | |
541 } | 537 } |
542 | 538 |
543 void TileManager::DidFinishRunningTasksRequiredForActivation() { | 539 void TileManager::DidFinishRunningTasksRequiredForActivation() { |
544 // This is only a true indication that all tiles required for | 540 // This is only a true indication that all tiles required for |
545 // activation are initialized when no tiles are OOM. We need to | 541 // activation are initialized when no tiles are OOM. We need to |
546 // wait for DidFinishRunningTasks() to be called, try to re-assign | 542 // wait for DidFinishRunningTasks() to be called, try to re-assign |
547 // memory and in worst case use on-demand raster when tiles | 543 // memory and in worst case use on-demand raster when tiles |
548 // required for activation are OOM. | 544 // required for activation are OOM. |
549 if (!all_tiles_required_for_activation_have_memory_) | 545 if (!all_tiles_required_for_activation_have_memory_) |
550 return; | 546 return; |
551 | 547 |
552 ScheduleCheckIfReadyToActivate(); | 548 client_->NotifyReadyToActivate(); |
553 } | 549 } |
554 | 550 |
555 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { | 551 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { |
556 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); | 552 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); |
557 | 553 |
558 // Compute new stats to be return by GetMemoryStats(). | 554 // Compute new stats to be return by GetMemoryStats(). |
559 memory_required_bytes_ = 0; | 555 memory_required_bytes_ = 0; |
560 memory_nice_to_have_bytes_ = 0; | 556 memory_nice_to_have_bytes_ = 0; |
561 | 557 |
562 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; | 558 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 DCHECK(!mts.required_for_activation || mts.bin != NEVER_BIN || | 657 DCHECK(!mts.required_for_activation || mts.bin != NEVER_BIN || |
662 tree_priority == SMOOTHNESS_TAKES_PRIORITY || | 658 tree_priority == SMOOTHNESS_TAKES_PRIORITY || |
663 memory_policy == ALLOW_NOTHING); | 659 memory_policy == ALLOW_NOTHING); |
664 | 660 |
665 // If the tile is in NEVER_BIN and it does not have an active task, then we | 661 // 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 | 662 // 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 | 663 // should keep it in the prioritized tile set to ensure that AssignGpuMemory |
668 // can visit it. | 664 // can visit it. |
669 if (mts.bin == NEVER_BIN && | 665 if (mts.bin == NEVER_BIN && |
670 !mts.tile_versions[mts.raster_mode].raster_task_) { | 666 !mts.tile_versions[mts.raster_mode].raster_task_) { |
671 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 667 FreeResourcesForTile(tile); |
672 continue; | 668 continue; |
673 } | 669 } |
674 | 670 |
675 // Insert the tile into a priority set. | 671 // Insert the tile into a priority set. |
676 tiles->InsertTile(tile, mts.bin); | 672 tiles->InsertTile(tile, mts.bin); |
677 } | 673 } |
678 } | 674 } |
679 | 675 |
680 void TileManager::CleanUpLayers() { | 676 void TileManager::CleanUpLayers() { |
681 for (size_t i = 0; i < layers_.size(); ++i) { | 677 for (size_t i = 0; i < layers_.size(); ++i) { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 | 846 |
851 ManagedTileState::TileVersion& tile_version = | 847 ManagedTileState::TileVersion& tile_version = |
852 mts.tile_versions[mts.raster_mode]; | 848 mts.tile_versions[mts.raster_mode]; |
853 | 849 |
854 // If this tile doesn't need a resource, then nothing to do. | 850 // If this tile doesn't need a resource, then nothing to do. |
855 if (!tile_version.requires_resource()) | 851 if (!tile_version.requires_resource()) |
856 continue; | 852 continue; |
857 | 853 |
858 // If the tile is not needed, free it up. | 854 // If the tile is not needed, free it up. |
859 if (mts.bin == NEVER_BIN) { | 855 if (mts.bin == NEVER_BIN) { |
860 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 856 FreeResourcesForTile(tile); |
861 continue; | 857 continue; |
862 } | 858 } |
863 | 859 |
864 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; | 860 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN; |
865 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); | 861 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); |
866 const size_t tile_bytes_left = | 862 const size_t tile_bytes_left = |
867 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; | 863 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; |
868 | 864 |
869 // Hard-limit is reserved for tiles that would cause a calamity | 865 // Hard-limit is reserved for tiles that would cause a calamity |
870 // if they were to go away, so by definition they are the highest | 866 // if they were to go away, so by definition they are the highest |
(...skipping 21 matching lines...) Expand all Loading... |
892 // If we don't have the required version, and it's not in flight | 888 // If we don't have the required version, and it's not in flight |
893 // then we'll have to pay to create a new task. | 889 // then we'll have to pay to create a new task. |
894 if (!tile_version.resource_ && !tile_version.raster_task_) { | 890 if (!tile_version.resource_ && !tile_version.raster_task_) { |
895 tile_bytes += bytes_if_allocated; | 891 tile_bytes += bytes_if_allocated; |
896 tile_resources++; | 892 tile_resources++; |
897 } | 893 } |
898 } | 894 } |
899 | 895 |
900 // Tile is OOM. | 896 // Tile is OOM. |
901 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { | 897 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { |
902 bool was_ready_to_draw = tile->IsReadyToDraw(); | |
903 | |
904 FreeResourcesForTile(tile); | 898 FreeResourcesForTile(tile); |
905 | 899 |
906 // This tile was already on screen and now its resources have been | 900 // This tile was already on screen and now its resources have been |
907 // released. In order to prevent checkerboarding, set this tile as | 901 // released. In order to prevent checkerboarding, set this tile as |
908 // rasterize on demand immediately. | 902 // rasterize on demand immediately. |
909 if (mts.visible_and_ready_to_draw) | 903 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) |
910 tile_version.set_rasterize_on_demand(); | 904 tile_version.set_rasterize_on_demand(); |
911 | 905 |
912 if (was_ready_to_draw) | |
913 client_->NotifyTileStateChanged(tile); | |
914 | |
915 oomed_soft = true; | 906 oomed_soft = true; |
916 if (tile_uses_hard_limit) { | 907 if (tile_uses_hard_limit) { |
917 oomed_hard = true; | 908 oomed_hard = true; |
918 bytes_that_exceeded_memory_budget += tile_bytes; | 909 bytes_that_exceeded_memory_budget += tile_bytes; |
919 } | 910 } |
920 } else { | 911 } else { |
921 resources_left -= tile_resources; | 912 resources_left -= tile_resources; |
922 hard_bytes_left -= tile_bytes; | 913 hard_bytes_left -= tile_bytes; |
923 soft_bytes_left = | 914 soft_bytes_left = |
924 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; | 915 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 break; | 990 break; |
1000 } | 991 } |
1001 } | 992 } |
1002 | 993 |
1003 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 994 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
1004 if (mode != used_mode) | 995 if (mode != used_mode) |
1005 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); | 996 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
1006 } | 997 } |
1007 } | 998 } |
1008 | 999 |
1009 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | |
1010 Tile* tile) { | |
1011 bool was_ready_to_draw = tile->IsReadyToDraw(); | |
1012 FreeResourcesForTile(tile); | |
1013 if (was_ready_to_draw) | |
1014 client_->NotifyTileStateChanged(tile); | |
1015 } | |
1016 | |
1017 void TileManager::ScheduleTasks( | 1000 void TileManager::ScheduleTasks( |
1018 const TileVector& tiles_that_need_to_be_rasterized) { | 1001 const TileVector& tiles_that_need_to_be_rasterized) { |
1019 TRACE_EVENT1("cc", | 1002 TRACE_EVENT1("cc", |
1020 "TileManager::ScheduleTasks", | 1003 "TileManager::ScheduleTasks", |
1021 "count", | 1004 "count", |
1022 tiles_that_need_to_be_rasterized.size()); | 1005 tiles_that_need_to_be_rasterized.size()); |
1023 | 1006 |
1024 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 1007 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
1025 | 1008 |
1026 raster_queue_.Reset(); | 1009 raster_queue_.Reset(); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 tile_version.set_solid_color(analysis.solid_color); | 1182 tile_version.set_solid_color(analysis.solid_color); |
1200 resource_pool_->ReleaseResource(resource.Pass()); | 1183 resource_pool_->ReleaseResource(resource.Pass()); |
1201 } else { | 1184 } else { |
1202 tile_version.set_use_resource(); | 1185 tile_version.set_use_resource(); |
1203 tile_version.resource_ = resource.Pass(); | 1186 tile_version.resource_ = resource.Pass(); |
1204 | 1187 |
1205 bytes_releasable_ += BytesConsumedIfAllocated(tile); | 1188 bytes_releasable_ += BytesConsumedIfAllocated(tile); |
1206 ++resources_releasable_; | 1189 ++resources_releasable_; |
1207 } | 1190 } |
1208 | 1191 |
| 1192 client_->NotifyTileInitialized(tile); |
| 1193 |
1209 FreeUnusedResourcesForTile(tile); | 1194 FreeUnusedResourcesForTile(tile); |
1210 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) | 1195 if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f) |
1211 did_initialize_visible_tile_ = true; | 1196 did_initialize_visible_tile_ = true; |
1212 | |
1213 client_->NotifyTileStateChanged(tile); | |
1214 } | 1197 } |
1215 | 1198 |
1216 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, | 1199 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, |
1217 const gfx::Size& tile_size, | 1200 const gfx::Size& tile_size, |
1218 const gfx::Rect& content_rect, | 1201 const gfx::Rect& content_rect, |
1219 const gfx::Rect& opaque_rect, | 1202 const gfx::Rect& opaque_rect, |
1220 float contents_scale, | 1203 float contents_scale, |
1221 int layer_id, | 1204 int layer_id, |
1222 int source_frame_number, | 1205 int source_frame_number, |
1223 int flags) { | 1206 int flags) { |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1637 (a_priority.resolution == NON_IDEAL_RESOLUTION); | 1620 (a_priority.resolution == NON_IDEAL_RESOLUTION); |
1638 } | 1621 } |
1639 return a_priority.IsHigherPriorityThan(b_priority); | 1622 return a_priority.IsHigherPriorityThan(b_priority); |
1640 } | 1623 } |
1641 | 1624 |
1642 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { | 1625 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) { |
1643 rasterizer_ = rasterizer; | 1626 rasterizer_ = rasterizer; |
1644 rasterizer_->SetClient(this); | 1627 rasterizer_->SetClient(this); |
1645 } | 1628 } |
1646 | 1629 |
1647 bool TileManager::IsReadyToActivate() const { | |
1648 for (std::vector<PictureLayerImpl*>::const_iterator it = layers_.begin(); | |
1649 it != layers_.end(); | |
1650 ++it) { | |
1651 if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw()) | |
1652 return false; | |
1653 } | |
1654 | |
1655 return true; | |
1656 } | |
1657 | |
1658 void TileManager::ScheduleCheckIfReadyToActivate() { | |
1659 if (check_if_ready_to_activate_pending_) | |
1660 return; | |
1661 | |
1662 task_runner_->PostTask(FROM_HERE, | |
1663 base::Bind(&TileManager::CheckIfReadyToActivate, | |
1664 weak_ptr_factory_.GetWeakPtr())); | |
1665 check_if_ready_to_activate_pending_ = true; | |
1666 } | |
1667 | |
1668 void TileManager::CheckIfReadyToActivate() { | |
1669 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | |
1670 | |
1671 DCHECK(check_if_ready_to_activate_pending_); | |
1672 check_if_ready_to_activate_pending_ = false; | |
1673 | |
1674 rasterizer_->CheckForCompletedTasks(); | |
1675 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | |
1676 | |
1677 if (IsReadyToActivate()) | |
1678 client_->NotifyReadyToActivate(); | |
1679 } | |
1680 | |
1681 } // namespace cc | 1630 } // namespace cc |
OLD | NEW |