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

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: rebase and address review feedback 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
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 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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698