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 |