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

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

Issue 523243002: cc: Generalize raster task notifications (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Renaming Created 6 years, 3 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
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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/debug/trace_event_argument.h" 12 #include "base/debug/trace_event_argument.h"
13 #include "base/debug/trace_event_synthetic_delay.h"
13 #include "base/json/json_writer.h" 14 #include "base/json/json_writer.h"
15 #include "base/lazy_instance.h"
14 #include "base/logging.h" 16 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
16 #include "cc/debug/devtools_instrumentation.h" 18 #include "cc/debug/devtools_instrumentation.h"
17 #include "cc/debug/frame_viewer_instrumentation.h" 19 #include "cc/debug/frame_viewer_instrumentation.h"
18 #include "cc/debug/traced_value.h" 20 #include "cc/debug/traced_value.h"
19 #include "cc/layers/picture_layer_impl.h" 21 #include "cc/layers/picture_layer_impl.h"
20 #include "cc/resources/rasterizer.h" 22 #include "cc/resources/rasterizer.h"
21 #include "cc/resources/tile.h" 23 #include "cc/resources/tile.h"
22 #include "skia/ext/paint_simplifier.h" 24 #include "skia/ext/paint_simplifier.h"
23 #include "third_party/skia/include/core/SkBitmap.h" 25 #include "third_party/skia/include/core/SkBitmap.h"
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 all_tiles_required_for_activation_have_memory_(true), 377 all_tiles_required_for_activation_have_memory_(true),
376 bytes_releasable_(0), 378 bytes_releasable_(0),
377 resources_releasable_(0), 379 resources_releasable_(0),
378 ever_exceeded_memory_budget_(false), 380 ever_exceeded_memory_budget_(false),
379 rendering_stats_instrumentation_(rendering_stats_instrumentation), 381 rendering_stats_instrumentation_(rendering_stats_instrumentation),
380 did_initialize_visible_tile_(false), 382 did_initialize_visible_tile_(false),
381 did_check_for_completed_tasks_since_last_schedule_tasks_(true), 383 did_check_for_completed_tasks_since_last_schedule_tasks_(true),
382 ready_to_activate_check_notifier_( 384 ready_to_activate_check_notifier_(
383 task_runner_.get(), 385 task_runner_.get(),
384 base::Bind(&TileManager::CheckIfReadyToActivate, 386 base::Bind(&TileManager::CheckIfReadyToActivate,
385 base::Unretained(this))) { 387 base::Unretained(this))),
388 raster_required_for_activation_synthetic_delay_(
389 base::debug::TraceEventSyntheticDelay::Lookup(
390 "cc.RasterRequiredForActivation")) {
386 rasterizer_->SetClient(this); 391 rasterizer_->SetClient(this);
387 } 392 }
388 393
389 TileManager::~TileManager() { 394 TileManager::~TileManager() {
390 // Reset global state and manage. This should cause 395 // Reset global state and manage. This should cause
391 // our memory usage to drop to zero. 396 // our memory usage to drop to zero.
392 global_state_ = GlobalStateThatImpactsTilePriority(); 397 global_state_ = GlobalStateThatImpactsTilePriority();
393 398
394 RasterTaskQueue empty; 399 RasterTaskQueue empty;
395 rasterizer_->ScheduleTasks(&empty); 400 rasterizer_->ScheduleTasks(&empty);
(...skipping 17 matching lines...) Expand all
413 DCHECK(TilePriority() == tile->combined_priority()); 418 DCHECK(TilePriority() == tile->combined_priority());
414 419
415 prioritized_tiles_dirty_ = true; 420 prioritized_tiles_dirty_ = true;
416 released_tiles_.push_back(tile); 421 released_tiles_.push_back(tile);
417 } 422 }
418 423
419 void TileManager::DidChangeTilePriority(Tile* tile) { 424 void TileManager::DidChangeTilePriority(Tile* tile) {
420 prioritized_tiles_dirty_ = true; 425 prioritized_tiles_dirty_ = true;
421 } 426 }
422 427
423 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { 428 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const {
424 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; 429 TaskSetCollection tasks_that_should_be_forced_to_complete;
430 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY)
431 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true;
432 return tasks_that_should_be_forced_to_complete;
425 } 433 }
426 434
427 void TileManager::FreeResourcesForReleasedTiles() { 435 void TileManager::FreeResourcesForReleasedTiles() {
428 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); 436 for (std::vector<Tile*>::iterator it = released_tiles_.begin();
429 it != released_tiles_.end(); 437 it != released_tiles_.end();
430 ++it) { 438 ++it) {
431 Tile* tile = *it; 439 Tile* tile = *it;
432 FreeResourcesForTile(tile); 440 FreeResourcesForTile(tile);
433 } 441 }
434 } 442 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 478
471 prioritized_tiles_.Clear(); 479 prioritized_tiles_.Clear();
472 480
473 FreeResourcesForReleasedTiles(); 481 FreeResourcesForReleasedTiles();
474 CleanUpReleasedTiles(); 482 CleanUpReleasedTiles();
475 483
476 GetTilesWithAssignedBins(&prioritized_tiles_); 484 GetTilesWithAssignedBins(&prioritized_tiles_);
477 prioritized_tiles_dirty_ = false; 485 prioritized_tiles_dirty_ = false;
478 } 486 }
479 487
480 void TileManager::DidFinishRunningTasks() { 488 void TileManager::DidFinishRunningTasks(TaskSet task_set) {
481 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); 489 TRACE_EVENT1(
490 "cc", "TileManager::DidFinishRunningTasks", "task_set", task_set);
482 491
483 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > 492 if (task_set == ALL) {
484 global_state_.soft_memory_limit_in_bytes; 493 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() >
494 global_state_.soft_memory_limit_in_bytes;
485 495
486 // When OOM, keep re-assigning memory until we reach a steady state 496 // When OOM, keep re-assigning memory until we reach a steady state
487 // where top-priority tiles are initialized. 497 // where top-priority tiles are initialized.
488 if (all_tiles_that_need_to_be_rasterized_have_memory_ && 498 if (all_tiles_that_need_to_be_rasterized_have_memory_ &&
489 !memory_usage_above_limit) 499 !memory_usage_above_limit)
490 return; 500 return;
491 501
492 rasterizer_->CheckForCompletedTasks(); 502 rasterizer_->CheckForCompletedTasks();
493 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 503 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
494 504
495 TileVector tiles_that_need_to_be_rasterized; 505 TileVector tiles_that_need_to_be_rasterized;
496 AssignGpuMemoryToTiles(&prioritized_tiles_, 506 AssignGpuMemoryToTiles(&prioritized_tiles_,
497 &tiles_that_need_to_be_rasterized); 507 &tiles_that_need_to_be_rasterized);
498 508
499 // |tiles_that_need_to_be_rasterized| will be empty when we reach a 509 // |tiles_that_need_to_be_rasterized| will be empty when we reach a
500 // steady memory state. Keep scheduling tasks until we reach this state. 510 // steady memory state. Keep scheduling tasks until we reach this state.
501 if (!tiles_that_need_to_be_rasterized.empty()) { 511 if (!tiles_that_need_to_be_rasterized.empty()) {
502 ScheduleTasks(tiles_that_need_to_be_rasterized); 512 ScheduleTasks(tiles_that_need_to_be_rasterized);
503 return; 513 return;
514 }
515
516 FreeResourcesForReleasedTiles();
517
518 resource_pool_->ReduceResourceUsage();
519
520 // We don't reserve memory for required-for-activation tiles during
521 // accelerated gestures, so we just postpone activation when we don't
522 // have these tiles, and activate after the accelerated gesture.
523 bool allow_rasterize_on_demand =
524 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY;
525
526 // Use on-demand raster for any required-for-activation tiles that have not
527 // been been assigned memory after reaching a steady memory state. This
528 // ensures that we activate even when OOM.
529 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
530 Tile* tile = it->second;
531 ManagedTileState& mts = tile->managed_state();
532 ManagedTileState::TileVersion& tile_version =
533 mts.tile_versions[mts.raster_mode];
534
535 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) {
536 // If we can't raster on demand, give up early (and don't activate).
537 if (!allow_rasterize_on_demand)
538 return;
539
540 tile_version.set_rasterize_on_demand();
541 client_->NotifyTileStateChanged(tile);
542 }
543 }
544
545 DCHECK(IsReadyToActivate());
546 ready_to_activate_check_notifier_.Schedule();
547 } else if (task_set == REQUIRED_FOR_ACTIVATION) {
548 // This is only a true indication that all tiles required for
549 // activation are initialized when no tiles are OOM. We need to
550 // wait for DidFinishRunningTasks() to be called, try to re-assign
551 // memory and in worst case use on-demand raster when tiles
552 // required for activation are OOM.
553 if (!all_tiles_required_for_activation_have_memory_)
554 return;
555
556 ready_to_activate_check_notifier_.Schedule();
504 } 557 }
505
506 FreeResourcesForReleasedTiles();
507
508 resource_pool_->ReduceResourceUsage();
509
510 // We don't reserve memory for required-for-activation tiles during
511 // accelerated gestures, so we just postpone activation when we don't
512 // have these tiles, and activate after the accelerated gesture.
513 bool allow_rasterize_on_demand =
514 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY;
515
516 // Use on-demand raster for any required-for-activation tiles that have not
517 // been been assigned memory after reaching a steady memory state. This
518 // ensures that we activate even when OOM.
519 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
520 Tile* tile = it->second;
521 ManagedTileState& mts = tile->managed_state();
522 ManagedTileState::TileVersion& tile_version =
523 mts.tile_versions[mts.raster_mode];
524
525 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) {
526 // If we can't raster on demand, give up early (and don't activate).
527 if (!allow_rasterize_on_demand)
528 return;
529
530 tile_version.set_rasterize_on_demand();
531 client_->NotifyTileStateChanged(tile);
532 }
533 }
534
535 DCHECK(IsReadyToActivate());
536 ready_to_activate_check_notifier_.Schedule();
537 } 558 }
538 559
539 void TileManager::DidFinishRunningTasksRequiredForActivation() { 560 base::debug::TraceEventSyntheticDelay* TileManager::SyntheticDelayForTasks(
540 // This is only a true indication that all tiles required for 561 TaskSet task_set) const {
541 // activation are initialized when no tiles are OOM. We need to 562 if (task_set == REQUIRED_FOR_ACTIVATION)
542 // wait for DidFinishRunningTasks() to be called, try to re-assign 563 return raster_required_for_activation_synthetic_delay_;
543 // memory and in worst case use on-demand raster when tiles 564 else
544 // required for activation are OOM. 565 return NULL;
545 if (!all_tiles_required_for_activation_have_memory_)
546 return;
547
548 ready_to_activate_check_notifier_.Schedule();
549 } 566 }
550 567
551 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { 568 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
552 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); 569 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins");
553 570
554 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; 571 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy;
555 const TreePriority tree_priority = global_state_.tree_priority; 572 const TreePriority tree_priority = global_state_.tree_priority;
556 573
557 // For each tree, bin into different categories of tiles. 574 // For each tree, bin into different categories of tiles.
558 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 575 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 ManagedTileState& mts = tile->managed_state(); 983 ManagedTileState& mts = tile->managed_state();
967 ManagedTileState::TileVersion& tile_version = 984 ManagedTileState::TileVersion& tile_version =
968 mts.tile_versions[mts.raster_mode]; 985 mts.tile_versions[mts.raster_mode];
969 986
970 DCHECK(tile_version.requires_resource()); 987 DCHECK(tile_version.requires_resource());
971 DCHECK(!tile_version.resource_); 988 DCHECK(!tile_version.resource_);
972 989
973 if (!tile_version.raster_task_.get()) 990 if (!tile_version.raster_task_.get())
974 tile_version.raster_task_ = CreateRasterTask(tile); 991 tile_version.raster_task_ = CreateRasterTask(tile);
975 992
976 raster_queue_.items.push_back(RasterTaskQueue::Item( 993 TaskSetCollection task_sets;
977 tile_version.raster_task_.get(), tile->required_for_activation())); 994 if (tile->required_for_activation())
978 raster_queue_.required_for_activation_count += 995 task_sets.set(REQUIRED_FOR_ACTIVATION);
979 tile->required_for_activation(); 996 task_sets.set(ALL);
997 raster_queue_.items.push_back(
998 RasterTaskQueue::Item(tile_version.raster_task_.get(), task_sets));
980 } 999 }
981 1000
982 // We must reduce the amount of unused resoruces before calling 1001 // We must reduce the amount of unused resoruces before calling
983 // ScheduleTasks to prevent usage from rising above limits. 1002 // ScheduleTasks to prevent usage from rising above limits.
984 resource_pool_->ReduceResourceUsage(); 1003 resource_pool_->ReduceResourceUsage();
985 1004
986 // Schedule running of |raster_tasks_|. This replaces any previously 1005 // Schedule running of |raster_tasks_|. This replaces any previously
987 // scheduled tasks and effectively cancels all tasks not present 1006 // scheduled tasks and effectively cancels all tasks not present
988 // in |raster_tasks_|. 1007 // in |raster_tasks_|.
989 rasterizer_->ScheduleTasks(&raster_queue_); 1008 rasterizer_->ScheduleTasks(&raster_queue_);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); 1187 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
1169 1188
1170 rasterizer_->CheckForCompletedTasks(); 1189 rasterizer_->CheckForCompletedTasks();
1171 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 1190 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
1172 1191
1173 if (IsReadyToActivate()) 1192 if (IsReadyToActivate())
1174 client_->NotifyReadyToActivate(); 1193 client_->NotifyReadyToActivate();
1175 } 1194 }
1176 1195
1177 } // namespace cc 1196 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698