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 |