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

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

Issue 885443002: Roll Chrome into Mojo. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Rebase to ToT mojo Created 5 years, 10 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
« 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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/debug/trace_event_argument.h"
13 #include "base/json/json_writer.h" 12 #include "base/json/json_writer.h"
14 #include "base/logging.h" 13 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/trace_event/trace_event_argument.h"
16 #include "cc/debug/devtools_instrumentation.h" 16 #include "cc/debug/devtools_instrumentation.h"
17 #include "cc/debug/frame_viewer_instrumentation.h" 17 #include "cc/debug/frame_viewer_instrumentation.h"
18 #include "cc/debug/traced_value.h" 18 #include "cc/debug/traced_value.h"
19 #include "cc/layers/picture_layer_impl.h" 19 #include "cc/layers/picture_layer_impl.h"
20 #include "cc/resources/raster_buffer.h" 20 #include "cc/resources/raster_buffer.h"
21 #include "cc/resources/rasterizer.h" 21 #include "cc/resources/rasterizer.h"
22 #include "cc/resources/tile.h" 22 #include "cc/resources/tile.h"
23 #include "cc/resources/tile_task_runner.h" 23 #include "cc/resources/tile_task_runner.h"
24 #include "ui/gfx/geometry/rect_conversions.h" 24 #include "ui/gfx/geometry/rect_conversions.h"
25 25
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 task_runner_.get(), 233 task_runner_.get(),
234 base::Bind(&TileManager::CheckIfReadyToActivate, 234 base::Bind(&TileManager::CheckIfReadyToActivate,
235 base::Unretained(this))), 235 base::Unretained(this))),
236 ready_to_draw_check_notifier_( 236 ready_to_draw_check_notifier_(
237 task_runner_.get(), 237 task_runner_.get(),
238 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))), 238 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))),
239 more_tiles_need_prepare_check_notifier_( 239 more_tiles_need_prepare_check_notifier_(
240 task_runner_.get(), 240 task_runner_.get(),
241 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, 241 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared,
242 base::Unretained(this))), 242 base::Unretained(this))),
243 eviction_priority_queue_is_up_to_date_(false),
244 did_notify_ready_to_activate_(false), 243 did_notify_ready_to_activate_(false),
245 did_notify_ready_to_draw_(false) { 244 did_notify_ready_to_draw_(false) {
246 tile_task_runner_->SetClient(this); 245 tile_task_runner_->SetClient(this);
247 } 246 }
248 247
249 TileManager::~TileManager() { 248 TileManager::~TileManager() {
250 // Reset global state and manage. This should cause 249 // Reset global state and manage. This should cause
251 // our memory usage to drop to zero. 250 // our memory usage to drop to zero.
252 global_state_ = GlobalStateThatImpactsTilePriority(); 251 global_state_ = GlobalStateThatImpactsTilePriority();
253 252
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 // to ScheduleTasks() to prevent canceled tasks from being scheduled. 352 // to ScheduleTasks() to prevent canceled tasks from being scheduled.
354 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { 353 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
355 tile_task_runner_->CheckForCompletedTasks(); 354 tile_task_runner_->CheckForCompletedTasks();
356 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 355 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
357 } 356 }
358 357
359 FreeResourcesForReleasedTiles(); 358 FreeResourcesForReleasedTiles();
360 CleanUpReleasedTiles(); 359 CleanUpReleasedTiles();
361 360
362 TileVector tiles_that_need_to_be_rasterized; 361 TileVector tiles_that_need_to_be_rasterized;
363 RasterTilePriorityQueue raster_priority_queue; 362 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue(
364 client_->BuildRasterQueue(&raster_priority_queue, 363 client_->BuildRasterQueue(global_state_.tree_priority,
365 global_state_.tree_priority, 364 RasterTilePriorityQueue::Type::ALL));
366 RasterTilePriorityQueue::Type::ALL); 365 AssignGpuMemoryToTiles(raster_priority_queue.get(),
367 AssignGpuMemoryToTiles(&raster_priority_queue, scheduled_raster_task_limit_, 366 scheduled_raster_task_limit_,
368 &tiles_that_need_to_be_rasterized); 367 &tiles_that_need_to_be_rasterized);
369 368
370 // Schedule tile tasks. 369 // Schedule tile tasks.
371 ScheduleTasks(tiles_that_need_to_be_rasterized); 370 ScheduleTasks(tiles_that_need_to_be_rasterized);
372 371
373 did_notify_ready_to_activate_ = false; 372 did_notify_ready_to_activate_ = false;
374 did_notify_ready_to_draw_ = false; 373 did_notify_ready_to_draw_ = false;
375 } else { 374 } else {
376 if (global_state_.hard_memory_limit_in_bytes == 0) { 375 if (global_state_.hard_memory_limit_in_bytes == 0) {
377 // TODO(vmpstr): Add a function to unconditionally create an eviction
378 // queue and guard the rest of the calls sites with this flag, instead of
379 // clearing here and building, which is a bit awkward.
380 eviction_priority_queue_is_up_to_date_ = false;
381 resource_pool_->CheckBusyResources(false); 376 resource_pool_->CheckBusyResources(false);
382 MemoryUsage memory_limit(0, 0); 377 MemoryUsage memory_limit(0, 0);
383 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), 378 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(),
384 resource_pool_->acquired_resource_count()); 379 resource_pool_->acquired_resource_count());
385 FreeTileResourcesUntilUsageIsWithinLimit(memory_limit, &memory_usage); 380 FreeTileResourcesUntilUsageIsWithinLimit(nullptr, memory_limit,
381 &memory_usage);
386 } 382 }
387 383
388 did_notify_ready_to_activate_ = false; 384 did_notify_ready_to_activate_ = false;
389 did_notify_ready_to_draw_ = false; 385 did_notify_ready_to_draw_ = false;
390 ready_to_activate_notifier_.Schedule(); 386 ready_to_activate_notifier_.Schedule();
391 ready_to_draw_notifier_.Schedule(); 387 ready_to_draw_notifier_.Schedule();
392 } 388 }
393 389
394 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, 390 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
395 "state", BasicStateAsValue()); 391 "state", BasicStateAsValue());
396 392
397 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, 393 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this,
398 resource_pool_->total_memory_usage_bytes() - 394 resource_pool_->total_memory_usage_bytes() -
399 resource_pool_->acquired_memory_usage_bytes()); 395 resource_pool_->acquired_memory_usage_bytes());
400 } 396 }
401 397
402 void TileManager::SynchronouslyRasterizeTiles( 398 void TileManager::SynchronouslyRasterizeTiles(
403 const GlobalStateThatImpactsTilePriority& state) { 399 const GlobalStateThatImpactsTilePriority& state) {
404 TRACE_EVENT0("cc", "TileManager::SynchronouslyRasterizeTiles"); 400 TRACE_EVENT0("cc", "TileManager::SynchronouslyRasterizeTiles");
405 401
406 DCHECK(rasterizer_->GetPrepareTilesMode() != 402 DCHECK(rasterizer_->GetPrepareTilesMode() !=
407 PrepareTilesMode::RASTERIZE_PRIORITIZED_TILES); 403 PrepareTilesMode::RASTERIZE_PRIORITIZED_TILES);
408 404
409 global_state_ = state; 405 global_state_ = state;
410 406
411 FreeResourcesForReleasedTiles(); 407 FreeResourcesForReleasedTiles();
412 CleanUpReleasedTiles(); 408 CleanUpReleasedTiles();
413 409
414 RasterTilePriorityQueue required_for_draw_queue; 410 scoped_ptr<RasterTilePriorityQueue> required_for_draw_queue(
415 client_->BuildRasterQueue(&required_for_draw_queue, 411 client_->BuildRasterQueue(
416 global_state_.tree_priority, 412 global_state_.tree_priority,
417 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); 413 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW));
418 TileVector tiles_that_need_to_be_rasterized; 414 TileVector tiles_that_need_to_be_rasterized;
419 AssignGpuMemoryToTiles(&required_for_draw_queue, 415 AssignGpuMemoryToTiles(required_for_draw_queue.get(),
420 std::numeric_limits<size_t>::max(), 416 std::numeric_limits<size_t>::max(),
421 &tiles_that_need_to_be_rasterized); 417 &tiles_that_need_to_be_rasterized);
422 418
423 // We must reduce the amount of unused resources before calling 419 // We must reduce the amount of unused resources before calling
424 // RunTasks to prevent usage from rising above limits. 420 // RunTasks to prevent usage from rising above limits.
425 resource_pool_->ReduceResourceUsage(); 421 resource_pool_->ReduceResourceUsage();
426 422
427 // Run and complete all raster task synchronously. 423 // Run and complete all raster task synchronously.
428 rasterizer_->RasterizeTiles( 424 rasterizer_->RasterizeTiles(
429 tiles_that_need_to_be_rasterized, resource_pool_, 425 tiles_that_need_to_be_rasterized, resource_pool_,
426 tile_task_runner_->GetResourceFormat(),
430 base::Bind(&TileManager::UpdateTileDrawInfo, base::Unretained(this))); 427 base::Bind(&TileManager::UpdateTileDrawInfo, base::Unretained(this)));
431 428
432 // Use on-demand raster for any required-for-draw tiles that have not been 429 // Use on-demand raster for any required-for-draw tiles that have not been
433 // assigned memory after reaching a steady memory state. 430 // assigned memory after reaching a steady memory state.
434 // TODO(hendrikw): Figure out why this would improve jank on some tests - See 431 // TODO(hendrikw): Figure out why this would improve jank on some tests - See
435 // crbug.com/449288 432 // crbug.com/449288
436 required_for_draw_queue.Reset(); 433 required_for_draw_queue = client_->BuildRasterQueue(
437 client_->BuildRasterQueue(&required_for_draw_queue, 434 global_state_.tree_priority,
438 global_state_.tree_priority, 435 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
439 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
440 436
441 // Use on-demand raster for any tiles that have not been been assigned 437 // Use on-demand raster for any tiles that have not been been assigned
442 // memory. This ensures that we draw even when OOM. 438 // memory. This ensures that we draw even when OOM.
443 for (; !required_for_draw_queue.IsEmpty(); required_for_draw_queue.Pop()) { 439 for (; !required_for_draw_queue->IsEmpty(); required_for_draw_queue->Pop()) {
444 Tile* tile = required_for_draw_queue.Top(); 440 Tile* tile = required_for_draw_queue->Top();
445 tile->draw_info().set_rasterize_on_demand(); 441 tile->draw_info().set_rasterize_on_demand();
446 client_->NotifyTileStateChanged(tile); 442 client_->NotifyTileStateChanged(tile);
447 } 443 }
448 444
449 TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state", 445 TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state",
450 BasicStateAsValue()); 446 BasicStateAsValue());
451 447
452 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, 448 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this,
453 resource_pool_->total_memory_usage_bytes() - 449 resource_pool_->total_memory_usage_bytes() -
454 resource_pool_->acquired_memory_usage_bytes()); 450 resource_pool_->acquired_memory_usage_bytes());
(...skipping 30 matching lines...) Expand all
485 } 481 }
486 482
487 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const { 483 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const {
488 state->SetInteger("tile_count", tiles_.size()); 484 state->SetInteger("tile_count", tiles_.size());
489 state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_); 485 state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_);
490 state->BeginDictionary("global_state"); 486 state->BeginDictionary("global_state");
491 global_state_.AsValueInto(state); 487 global_state_.AsValueInto(state);
492 state->EndDictionary(); 488 state->EndDictionary();
493 } 489 }
494 490
495 void TileManager::RebuildEvictionQueueIfNeeded() { 491 scoped_ptr<EvictionTilePriorityQueue>
496 TRACE_EVENT1("cc", 492 TileManager::FreeTileResourcesUntilUsageIsWithinLimit(
497 "TileManager::RebuildEvictionQueueIfNeeded", 493 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
498 "eviction_priority_queue_is_up_to_date",
499 eviction_priority_queue_is_up_to_date_);
500 if (eviction_priority_queue_is_up_to_date_)
501 return;
502
503 eviction_priority_queue_.Reset();
504 client_->BuildEvictionQueue(&eviction_priority_queue_,
505 global_state_.tree_priority);
506 eviction_priority_queue_is_up_to_date_ = true;
507 }
508
509 bool TileManager::FreeTileResourcesUntilUsageIsWithinLimit(
510 const MemoryUsage& limit, 494 const MemoryUsage& limit,
511 MemoryUsage* usage) { 495 MemoryUsage* usage) {
512 while (usage->Exceeds(limit)) { 496 while (usage->Exceeds(limit)) {
513 RebuildEvictionQueueIfNeeded(); 497 if (!eviction_priority_queue) {
514 if (eviction_priority_queue_.IsEmpty()) 498 eviction_priority_queue =
515 return false; 499 client_->BuildEvictionQueue(global_state_.tree_priority);
500 }
501 if (eviction_priority_queue->IsEmpty())
502 break;
516 503
517 Tile* tile = eviction_priority_queue_.Top(); 504 Tile* tile = eviction_priority_queue->Top();
518 *usage -= MemoryUsage::FromTile(tile); 505 *usage -= MemoryUsage::FromTile(tile);
519 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); 506 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
520 eviction_priority_queue_.Pop(); 507 eviction_priority_queue->Pop();
521 } 508 }
522 return true; 509 return eviction_priority_queue;
523 } 510 }
524 511
525 bool TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( 512 scoped_ptr<EvictionTilePriorityQueue>
513 TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
514 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
526 const MemoryUsage& limit, 515 const MemoryUsage& limit,
527 const TilePriority& other_priority, 516 const TilePriority& other_priority,
528 MemoryUsage* usage) { 517 MemoryUsage* usage) {
529 while (usage->Exceeds(limit)) { 518 while (usage->Exceeds(limit)) {
530 RebuildEvictionQueueIfNeeded(); 519 if (!eviction_priority_queue) {
531 if (eviction_priority_queue_.IsEmpty()) 520 eviction_priority_queue =
532 return false; 521 client_->BuildEvictionQueue(global_state_.tree_priority);
522 }
523 if (eviction_priority_queue->IsEmpty())
524 break;
533 525
534 Tile* tile = eviction_priority_queue_.Top(); 526 Tile* tile = eviction_priority_queue->Top();
535 if (!other_priority.IsHigherPriorityThan(tile->combined_priority())) 527 if (!other_priority.IsHigherPriorityThan(tile->combined_priority()))
536 return false; 528 break;
537 529
538 *usage -= MemoryUsage::FromTile(tile); 530 *usage -= MemoryUsage::FromTile(tile);
539 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); 531 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
540 eviction_priority_queue_.Pop(); 532 eviction_priority_queue->Pop();
541 } 533 }
542 return true; 534 return eviction_priority_queue;
543 } 535 }
544 536
545 bool TileManager::TilePriorityViolatesMemoryPolicy( 537 bool TileManager::TilePriorityViolatesMemoryPolicy(
546 const TilePriority& priority) { 538 const TilePriority& priority) {
547 switch (global_state_.memory_limit_policy) { 539 switch (global_state_.memory_limit_policy) {
548 case ALLOW_NOTHING: 540 case ALLOW_NOTHING:
549 return true; 541 return true;
550 case ALLOW_ABSOLUTE_MINIMUM: 542 case ALLOW_ABSOLUTE_MINIMUM:
551 return priority.priority_bin > TilePriority::NOW; 543 return priority.priority_bin > TilePriority::NOW;
552 case ALLOW_PREPAINT_ONLY: 544 case ALLOW_PREPAINT_ONLY:
(...skipping 24 matching lines...) Expand all
577 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; 569 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true;
578 bool had_enough_memory_to_schedule_tiles_needed_now = true; 570 bool had_enough_memory_to_schedule_tiles_needed_now = true;
579 571
580 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, 572 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes,
581 global_state_.num_resources_limit); 573 global_state_.num_resources_limit);
582 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, 574 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes,
583 global_state_.num_resources_limit); 575 global_state_.num_resources_limit);
584 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), 576 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(),
585 resource_pool_->acquired_resource_count()); 577 resource_pool_->acquired_resource_count());
586 578
587 eviction_priority_queue_is_up_to_date_ = false; 579 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue;
588 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { 580 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
589 Tile* tile = raster_priority_queue->Top(); 581 Tile* tile = raster_priority_queue->Top();
590 TilePriority priority = tile->combined_priority(); 582 TilePriority priority = tile->combined_priority();
591 583
592 if (TilePriorityViolatesMemoryPolicy(priority)) { 584 if (TilePriorityViolatesMemoryPolicy(priority)) {
593 TRACE_EVENT_INSTANT0( 585 TRACE_EVENT_INSTANT0(
594 "cc", "TileManager::AssignGpuMemory tile violates memory policy", 586 "cc", "TileManager::AssignGpuMemory tile violates memory policy",
595 TRACE_EVENT_SCOPE_THREAD); 587 TRACE_EVENT_SCOPE_THREAD);
596 break; 588 break;
597 } 589 }
(...skipping 10 matching lines...) Expand all
608 600
609 DCHECK(draw_info.mode() == TileDrawInfo::PICTURE_PILE_MODE || 601 DCHECK(draw_info.mode() == TileDrawInfo::PICTURE_PILE_MODE ||
610 !draw_info.IsReadyToDraw()); 602 !draw_info.IsReadyToDraw());
611 603
612 // If the tile already has a raster_task, then the memory used by it is 604 // If the tile already has a raster_task, then the memory used by it is
613 // already accounted for in memory_usage. Otherwise, we'll have to acquire 605 // already accounted for in memory_usage. Otherwise, we'll have to acquire
614 // more memory to create a raster task. 606 // more memory to create a raster task.
615 MemoryUsage memory_required_by_tile_to_be_scheduled; 607 MemoryUsage memory_required_by_tile_to_be_scheduled;
616 if (!tile->raster_task_.get()) { 608 if (!tile->raster_task_.get()) {
617 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig( 609 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig(
618 tile->desired_texture_size(), resource_pool_->default_format()); 610 tile->desired_texture_size(), tile_task_runner_->GetResourceFormat());
619 } 611 }
620 612
621 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW; 613 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW;
622 614
623 // This is the memory limit that will be used by this tile. Depending on 615 // This is the memory limit that will be used by this tile. Depending on
624 // the tile priority, it will be one of hard_memory_limit or 616 // the tile priority, it will be one of hard_memory_limit or
625 // soft_memory_limit. 617 // soft_memory_limit.
626 MemoryUsage& tile_memory_limit = 618 MemoryUsage& tile_memory_limit =
627 tile_is_needed_now ? hard_memory_limit : soft_memory_limit; 619 tile_is_needed_now ? hard_memory_limit : soft_memory_limit;
628 620
621 const MemoryUsage& scheduled_tile_memory_limit =
622 tile_memory_limit - memory_required_by_tile_to_be_scheduled;
623 eviction_priority_queue =
624 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
625 eviction_priority_queue.Pass(), scheduled_tile_memory_limit,
626 priority, &memory_usage);
629 bool memory_usage_is_within_limit = 627 bool memory_usage_is_within_limit =
630 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( 628 !memory_usage.Exceeds(scheduled_tile_memory_limit);
631 tile_memory_limit - memory_required_by_tile_to_be_scheduled,
632 priority, &memory_usage);
633 629
634 // If we couldn't fit the tile into our current memory limit, then we're 630 // If we couldn't fit the tile into our current memory limit, then we're
635 // done. 631 // done.
636 if (!memory_usage_is_within_limit) { 632 if (!memory_usage_is_within_limit) {
637 if (tile_is_needed_now) 633 if (tile_is_needed_now)
638 had_enough_memory_to_schedule_tiles_needed_now = false; 634 had_enough_memory_to_schedule_tiles_needed_now = false;
639 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; 635 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
640 break; 636 break;
641 } 637 }
642 638
643 memory_usage += memory_required_by_tile_to_be_scheduled; 639 memory_usage += memory_required_by_tile_to_be_scheduled;
644 tiles_that_need_to_be_rasterized->push_back(tile); 640 tiles_that_need_to_be_rasterized->push_back(tile);
645 } 641 }
646 642
647 // Note that we should try and further reduce memory in case the above loop 643 // Note that we should try and further reduce memory in case the above loop
648 // didn't reduce memory. This ensures that we always release as many resources 644 // didn't reduce memory. This ensures that we always release as many resources
649 // as possible to stay within the memory limit. 645 // as possible to stay within the memory limit.
650 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage); 646 eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit(
647 eviction_priority_queue.Pass(), hard_memory_limit, &memory_usage);
651 648
652 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", 649 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget",
653 !had_enough_memory_to_schedule_tiles_needed_now); 650 !had_enough_memory_to_schedule_tiles_needed_now);
654 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; 651 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now;
655 652
656 memory_stats_from_last_assign_.total_budget_in_bytes = 653 memory_stats_from_last_assign_.total_budget_in_bytes =
657 global_state_.hard_memory_limit_in_bytes; 654 global_state_.hard_memory_limit_in_bytes;
658 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); 655 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes();
659 memory_stats_from_last_assign_.had_enough_memory = 656 memory_stats_from_last_assign_.had_enough_memory =
660 had_enough_memory_to_schedule_tiles_needed_now; 657 had_enough_memory_to_schedule_tiles_needed_now;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 pixel_ref, 736 pixel_ref,
740 base::Bind(&TileManager::OnImageDecodeTaskCompleted, 737 base::Bind(&TileManager::OnImageDecodeTaskCompleted,
741 base::Unretained(this), 738 base::Unretained(this),
742 tile->layer_id(), 739 tile->layer_id(),
743 base::Unretained(pixel_ref)))); 740 base::Unretained(pixel_ref))));
744 } 741 }
745 742
746 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { 743 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) {
747 scoped_ptr<ScopedResource> resource = 744 scoped_ptr<ScopedResource> resource =
748 resource_pool_->AcquireResource(tile->desired_texture_size(), 745 resource_pool_->AcquireResource(tile->desired_texture_size(),
749 resource_pool_->default_format()); 746 tile_task_runner_->GetResourceFormat());
750 const ScopedResource* const_resource = resource.get(); 747 const ScopedResource* const_resource = resource.get();
751 748
752 // Create and queue all image decode tasks that this tile depends on. 749 // Create and queue all image decode tasks that this tile depends on.
753 ImageDecodeTask::Vector decode_tasks; 750 ImageDecodeTask::Vector decode_tasks;
754 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; 751 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()];
755 std::vector<SkPixelRef*> pixel_refs; 752 std::vector<SkPixelRef*> pixel_refs;
756 tile->raster_source()->GatherPixelRefs( 753 tile->raster_source()->GatherPixelRefs(
757 tile->content_rect(), tile->contents_scale(), &pixel_refs); 754 tile->content_rect(), tile->contents_scale(), &pixel_refs);
758 for (SkPixelRef* pixel_ref : pixel_refs) { 755 for (SkPixelRef* pixel_ref : pixel_refs) {
759 uint32_t id = pixel_ref->getGenerationID(); 756 uint32_t id = pixel_ref->getGenerationID();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 NotifyReadyToDraw(); 934 NotifyReadyToDraw();
938 } 935 }
939 936
940 void TileManager::CheckIfMoreTilesNeedToBePrepared() { 937 void TileManager::CheckIfMoreTilesNeedToBePrepared() {
941 tile_task_runner_->CheckForCompletedTasks(); 938 tile_task_runner_->CheckForCompletedTasks();
942 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 939 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
943 940
944 // When OOM, keep re-assigning memory until we reach a steady state 941 // When OOM, keep re-assigning memory until we reach a steady state
945 // where top-priority tiles are initialized. 942 // where top-priority tiles are initialized.
946 TileVector tiles_that_need_to_be_rasterized; 943 TileVector tiles_that_need_to_be_rasterized;
947 RasterTilePriorityQueue raster_priority_queue; 944 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue(
948 client_->BuildRasterQueue(&raster_priority_queue, global_state_.tree_priority, 945 client_->BuildRasterQueue(global_state_.tree_priority,
949 RasterTilePriorityQueue::Type::ALL); 946 RasterTilePriorityQueue::Type::ALL));
950 AssignGpuMemoryToTiles(&raster_priority_queue, scheduled_raster_task_limit_, 947 AssignGpuMemoryToTiles(raster_priority_queue.get(),
948 scheduled_raster_task_limit_,
951 &tiles_that_need_to_be_rasterized); 949 &tiles_that_need_to_be_rasterized);
952 950
953 // |tiles_that_need_to_be_rasterized| will be empty when we reach a 951 // |tiles_that_need_to_be_rasterized| will be empty when we reach a
954 // steady memory state. Keep scheduling tasks until we reach this state. 952 // steady memory state. Keep scheduling tasks until we reach this state.
955 if (!tiles_that_need_to_be_rasterized.empty()) { 953 if (!tiles_that_need_to_be_rasterized.empty()) {
956 ScheduleTasks(tiles_that_need_to_be_rasterized); 954 ScheduleTasks(tiles_that_need_to_be_rasterized);
957 return; 955 return;
958 } 956 }
959 957
960 FreeResourcesForReleasedTiles(); 958 FreeResourcesForReleasedTiles();
961 959
962 resource_pool_->ReduceResourceUsage(); 960 resource_pool_->ReduceResourceUsage();
963 961
964 // We don't reserve memory for required-for-activation tiles during 962 // We don't reserve memory for required-for-activation tiles during
965 // accelerated gestures, so we just postpone activation when we don't 963 // accelerated gestures, so we just postpone activation when we don't
966 // have these tiles, and activate after the accelerated gesture. 964 // have these tiles, and activate after the accelerated gesture.
967 // Likewise if we don't allow any tiles (as is the case when we're 965 // Likewise if we don't allow any tiles (as is the case when we're
968 // invisible), if we have tiles that aren't ready, then we shouldn't 966 // invisible), if we have tiles that aren't ready, then we shouldn't
969 // activate as activation can cause checkerboards. 967 // activate as activation can cause checkerboards.
970 bool allow_rasterize_on_demand = 968 bool allow_rasterize_on_demand =
971 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && 969 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY &&
972 global_state_.memory_limit_policy != ALLOW_NOTHING; 970 global_state_.memory_limit_policy != ALLOW_NOTHING;
973 971
974 // Use on-demand raster for any required-for-activation tiles that have 972 // Use on-demand raster for any required-for-activation tiles that have
975 // not been been assigned memory after reaching a steady memory state. This 973 // not been been assigned memory after reaching a steady memory state. This
976 // ensures that we activate even when OOM. Note that we can't reuse the queue 974 // ensures that we activate even when OOM. Note that we can't reuse the queue
977 // we used for AssignGpuMemoryToTiles, since the AssignGpuMemoryToTiles call 975 // we used for AssignGpuMemoryToTiles, since the AssignGpuMemoryToTiles call
978 // could have evicted some tiles that would not be picked up by the old raster 976 // could have evicted some tiles that would not be picked up by the old raster
979 // queue. 977 // queue.
980 RasterTilePriorityQueue required_for_activation_queue; 978 scoped_ptr<RasterTilePriorityQueue> required_for_activation_queue(
981 client_->BuildRasterQueue( 979 client_->BuildRasterQueue(
982 &required_for_activation_queue, global_state_.tree_priority, 980 global_state_.tree_priority,
983 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); 981 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION));
984 982
985 // If we have tiles to mark as rasterize on demand, but we don't allow 983 // If we have tiles to mark as rasterize on demand, but we don't allow
986 // rasterize on demand, then skip activation and return early. 984 // rasterize on demand, then skip activation and return early.
987 if (!required_for_activation_queue.IsEmpty() && !allow_rasterize_on_demand) 985 if (!required_for_activation_queue->IsEmpty() && !allow_rasterize_on_demand)
988 return; 986 return;
989 987
990 // Mark required tiles as rasterize on demand. 988 // Mark required tiles as rasterize on demand.
991 for (; !required_for_activation_queue.IsEmpty(); 989 for (; !required_for_activation_queue->IsEmpty();
992 required_for_activation_queue.Pop()) { 990 required_for_activation_queue->Pop()) {
993 Tile* tile = required_for_activation_queue.Top(); 991 Tile* tile = required_for_activation_queue->Top();
994 tile->draw_info().set_rasterize_on_demand(); 992 tile->draw_info().set_rasterize_on_demand();
995 client_->NotifyTileStateChanged(tile); 993 client_->NotifyTileStateChanged(tile);
996 } 994 }
997 995
998 DCHECK(IsReadyToActivate()); 996 DCHECK(IsReadyToActivate());
999 ready_to_activate_check_notifier_.Schedule(); 997 ready_to_activate_check_notifier_.Schedule();
1000 } 998 }
1001 999
1002 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { 1000 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) {
1003 } 1001 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 result -= other; 1041 result -= other;
1044 return result; 1042 return result;
1045 } 1043 }
1046 1044
1047 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { 1045 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const {
1048 return memory_bytes_ > limit.memory_bytes_ || 1046 return memory_bytes_ > limit.memory_bytes_ ||
1049 resource_count_ > limit.resource_count_; 1047 resource_count_ > limit.resource_count_;
1050 } 1048 }
1051 1049
1052 } // namespace cc 1050 } // 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