Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: cc/resources/tile_manager.cc

Issue 287643004: Re-land: cc: Examine layers to determine if we're ready to activate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: init check_if_ready_to_activate_pending_ properly Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698