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