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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 | 322 |
323 // When OOM, keep re-assigning memory until we reach a steady state | 323 // When OOM, keep re-assigning memory until we reach a steady state |
324 // where top-priority tiles are initialized. | 324 // where top-priority tiles are initialized. |
325 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 325 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
326 !memory_usage_above_limit) | 326 !memory_usage_above_limit) |
327 return; | 327 return; |
328 | 328 |
329 rasterizer_->CheckForCompletedTasks(); | 329 rasterizer_->CheckForCompletedTasks(); |
330 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 330 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
331 | 331 |
332 client_->BuildRasterQueue(&raster_priority_queue_, | |
333 global_state_.tree_priority); | |
332 TileVector tiles_that_need_to_be_rasterized; | 334 TileVector tiles_that_need_to_be_rasterized; |
333 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | 335 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, |
336 scheduled_raster_task_limit_); | |
337 raster_priority_queue_.Reset(); | |
334 | 338 |
335 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 339 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
336 // steady memory state. Keep scheduling tasks until we reach this state. | 340 // steady memory state. Keep scheduling tasks until we reach this state. |
337 if (!tiles_that_need_to_be_rasterized.empty()) { | 341 if (!tiles_that_need_to_be_rasterized.empty()) { |
338 ScheduleTasks(tiles_that_need_to_be_rasterized); | 342 ScheduleTasks(tiles_that_need_to_be_rasterized); |
339 return; | 343 return; |
340 } | 344 } |
341 | 345 |
342 FreeResourcesForReleasedTiles(); | 346 FreeResourcesForReleasedTiles(); |
343 | 347 |
344 resource_pool_->ReduceResourceUsage(); | 348 resource_pool_->ReduceResourceUsage(); |
345 | 349 |
346 // We don't reserve memory for required-for-activation tiles during | 350 // We don't reserve memory for required-for-activation tiles during |
347 // accelerated gestures, so we just postpone activation when we don't | 351 // accelerated gestures, so we just postpone activation when we don't |
348 // have these tiles, and activate after the accelerated gesture. | 352 // have these tiles, and activate after the accelerated gesture. |
349 // Likewise if we don't allow any tiles (as is the case when we're | 353 // Likewise if we don't allow any tiles (as is the case when we're |
350 // invisible), if we have tiles that aren't ready, then we shouldn't | 354 // invisible), if we have tiles that aren't ready, then we shouldn't |
351 // activate as activation can cause checkerboards. | 355 // activate as activation can cause checkerboards. |
352 bool allow_rasterize_on_demand = | 356 bool allow_rasterize_on_demand = |
353 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | 357 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && |
354 global_state_.memory_limit_policy != ALLOW_NOTHING; | 358 global_state_.memory_limit_policy != ALLOW_NOTHING; |
355 | 359 |
356 // Use on-demand raster for any required-for-activation tiles that have | 360 // Use on-demand raster for any required-for-activation tiles that have |
357 // not | 361 // not been been assigned memory after reaching a steady memory |
358 // been been assigned memory after reaching a steady memory state. This | 362 // state. This ensures that we activate even when OOM. Note that we have |
359 // ensures that we activate even when OOM. Note that we have to rebuilt | 363 // to rebuilt the queue in case the last AssignGpuMemoryToTiles evicted |
360 // the | 364 // some tiles that would otherwise not be picked up by the old raster |
361 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | 365 // queue. |
362 // would otherwise not be picked up by the old raster queue. | |
363 client_->BuildRasterQueue(&raster_priority_queue_, | 366 client_->BuildRasterQueue(&raster_priority_queue_, |
364 global_state_.tree_priority); | 367 global_state_.tree_priority); |
365 bool ready_to_activate = true; | 368 bool ready_to_activate = true; |
366 while (!raster_priority_queue_.IsEmpty()) { | 369 while (!raster_priority_queue_.IsEmpty()) { |
367 Tile* tile = raster_priority_queue_.Top(); | 370 Tile* tile = raster_priority_queue_.Top(); |
368 ManagedTileState& mts = tile->managed_state(); | 371 ManagedTileState& mts = tile->managed_state(); |
369 | 372 |
370 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { | 373 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { |
371 // If we can't raster on demand, give up early (and don't activate). | 374 // If we can't raster on demand, give up early (and don't activate). |
372 if (!allow_rasterize_on_demand) { | 375 if (!allow_rasterize_on_demand) { |
(...skipping 18 matching lines...) Expand all Loading... | |
391 ready_to_activate_check_notifier_.Schedule(); | 394 ready_to_activate_check_notifier_.Schedule(); |
392 return; | 395 return; |
393 case REQUIRED_FOR_DRAW: | 396 case REQUIRED_FOR_DRAW: |
394 ready_to_draw_check_notifier_.Schedule(); | 397 ready_to_draw_check_notifier_.Schedule(); |
395 return; | 398 return; |
396 } | 399 } |
397 | 400 |
398 NOTREACHED(); | 401 NOTREACHED(); |
399 } | 402 } |
400 | 403 |
404 void TileManager::RasterizeTiles( | |
405 const GlobalStateThatImpactsTilePriority& state) { | |
406 TRACE_EVENT0("cc", "TileManager::RasterizeTiles"); | |
407 | |
408 global_state_ = state; | |
409 | |
410 FreeResourcesForReleasedTiles(); | |
411 CleanUpReleasedTiles(); | |
412 | |
413 client_->BuildRasterQueue(&raster_priority_queue_, | |
414 global_state_.tree_priority); | |
415 TileVector tiles_that_need_to_be_rasterized; | |
416 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, | |
417 std::numeric_limits<size_t>::max()); | |
418 | |
419 // Build a new task queue containing all task currently needed. | |
420 raster_queue_.Reset(); | |
421 for (auto& tile : tiles_that_need_to_be_rasterized) { | |
422 ManagedTileState& mts = tile->managed_state(); | |
423 | |
424 if (!mts.raster_task.get()) | |
425 mts.raster_task = CreateRasterTask(tile); | |
426 | |
427 TaskSetCollection task_sets; | |
428 if (tile->required_for_draw()) | |
429 task_sets.set(REQUIRED_FOR_DRAW); | |
430 task_sets.set(ALL); | |
431 raster_queue_.items.push_back( | |
432 RasterTaskQueue::Item(mts.raster_task.get(), task_sets)); | |
433 } | |
434 | |
435 // We must reduce the amount of unused resoruces before calling | |
436 // RunTasks to prevent usage from rising above limits. | |
437 resource_pool_->ReduceResourceUsage(); | |
438 | |
439 // Run and complete all raster task synchronously. | |
440 rasterizer_->RunTasks(&raster_queue_); | |
441 | |
442 // Use on-demand raster for any tiles that have not been been assigned | |
443 // memory. This ensures that we draw even when OOM. | |
444 while (!raster_priority_queue_.IsEmpty()) { | |
vmpstr
2014/11/20 18:40:59
I think you still need to reset/rebuilt raster_pri
vmiura
2014/11/20 20:10:10
Is it possible for some required_for_draw tiles to
| |
445 Tile* tile = raster_priority_queue_.Top(); | |
446 ManagedTileState& mts = tile->managed_state(); | |
447 | |
448 if (!mts.draw_info.IsReadyToDraw()) { | |
449 mts.draw_info.set_rasterize_on_demand(); | |
450 client_->NotifyTileStateChanged(tile); | |
451 } | |
452 raster_priority_queue_.Pop(); | |
453 } | |
454 raster_priority_queue_.Reset(); | |
455 | |
456 if (IsReadyToDraw()) | |
457 client_->NotifyReadyToDraw(); | |
458 | |
459 TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state", | |
460 BasicStateAsValue()); | |
461 | |
462 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, | |
463 resource_pool_->total_memory_usage_bytes() - | |
464 resource_pool_->acquired_memory_usage_bytes()); | |
465 } | |
466 | |
401 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { | 467 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { |
402 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 468 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
403 | 469 |
404 global_state_ = state; | 470 global_state_ = state; |
405 | 471 |
406 // We need to call CheckForCompletedTasks() once in-between each call | 472 // We need to call CheckForCompletedTasks() once in-between each call |
407 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 473 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
408 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 474 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
409 rasterizer_->CheckForCompletedTasks(); | 475 rasterizer_->CheckForCompletedTasks(); |
410 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 476 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
411 } | 477 } |
412 | 478 |
413 FreeResourcesForReleasedTiles(); | 479 FreeResourcesForReleasedTiles(); |
414 CleanUpReleasedTiles(); | 480 CleanUpReleasedTiles(); |
415 | 481 |
482 client_->BuildRasterQueue(&raster_priority_queue_, | |
483 global_state_.tree_priority); | |
416 TileVector tiles_that_need_to_be_rasterized; | 484 TileVector tiles_that_need_to_be_rasterized; |
417 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | 485 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, |
486 scheduled_raster_task_limit_); | |
487 raster_priority_queue_.Reset(); | |
418 | 488 |
419 // Finally, schedule rasterizer tasks. | 489 // Finally, schedule rasterizer tasks. |
420 ScheduleTasks(tiles_that_need_to_be_rasterized); | 490 ScheduleTasks(tiles_that_need_to_be_rasterized); |
421 | 491 |
422 TRACE_EVENT_INSTANT1("cc", | 492 TRACE_EVENT_INSTANT1("cc", |
423 "DidManage", | 493 "DidManage", |
424 TRACE_EVENT_SCOPE_THREAD, | 494 TRACE_EVENT_SCOPE_THREAD, |
425 "state", | 495 "state", |
426 BasicStateAsValue()); | 496 BasicStateAsValue()); |
427 | 497 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 return priority.priority_bin > TilePriority::SOON; | 594 return priority.priority_bin > TilePriority::SOON; |
525 case ALLOW_ANYTHING: | 595 case ALLOW_ANYTHING: |
526 return priority.distance_to_visible == | 596 return priority.distance_to_visible == |
527 std::numeric_limits<float>::infinity(); | 597 std::numeric_limits<float>::infinity(); |
528 } | 598 } |
529 NOTREACHED(); | 599 NOTREACHED(); |
530 return true; | 600 return true; |
531 } | 601 } |
532 | 602 |
533 void TileManager::AssignGpuMemoryToTiles( | 603 void TileManager::AssignGpuMemoryToTiles( |
534 TileVector* tiles_that_need_to_be_rasterized) { | 604 TileVector* tiles_that_need_to_be_rasterized, |
605 size_t scheduled_raster_task_limit) { | |
535 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); | 606 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); |
536 | 607 |
537 // Maintain the list of released resources that can potentially be re-used | 608 // Maintain the list of released resources that can potentially be re-used |
538 // or deleted. | 609 // or deleted. |
539 // If this operation becomes expensive too, only do this after some | 610 // If this operation becomes expensive too, only do this after some |
540 // resource(s) was returned. Note that in that case, one also need to | 611 // resource(s) was returned. Note that in that case, one also need to |
541 // invalidate when releasing some resource from the pool. | 612 // invalidate when releasing some resource from the pool. |
542 resource_pool_->CheckBusyResources(false); | 613 resource_pool_->CheckBusyResources(false); |
543 | 614 |
544 // Now give memory out to the tiles until we're out, and build | 615 // Now give memory out to the tiles until we're out, and build |
545 // the needs-to-be-rasterized queue. | 616 // the needs-to-be-rasterized queue. |
546 unsigned schedule_priority = 1u; | 617 unsigned schedule_priority = 1u; |
547 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 618 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
548 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 619 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
549 | 620 |
550 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 621 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, |
551 global_state_.num_resources_limit); | 622 global_state_.num_resources_limit); |
552 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 623 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, |
553 global_state_.num_resources_limit); | 624 global_state_.num_resources_limit); |
554 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), | 625 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), |
555 resource_pool_->acquired_resource_count()); | 626 resource_pool_->acquired_resource_count()); |
556 | 627 |
557 eviction_priority_queue_is_up_to_date_ = false; | 628 eviction_priority_queue_is_up_to_date_ = false; |
558 client_->BuildRasterQueue(&raster_priority_queue_, | |
vmpstr
2014/11/20 18:40:59
What's the motivation for pulling this out of this
| |
559 global_state_.tree_priority); | |
560 | 629 |
561 while (!raster_priority_queue_.IsEmpty()) { | 630 while (!raster_priority_queue_.IsEmpty()) { |
562 Tile* tile = raster_priority_queue_.Top(); | 631 Tile* tile = raster_priority_queue_.Top(); |
563 TilePriority priority = tile->combined_priority(); | 632 TilePriority priority = tile->combined_priority(); |
564 | 633 |
565 if (TilePriorityViolatesMemoryPolicy(priority)) { | 634 if (TilePriorityViolatesMemoryPolicy(priority)) { |
566 TRACE_EVENT_INSTANT0( | 635 TRACE_EVENT_INSTANT0( |
567 "cc", | 636 "cc", |
568 "TileManager::AssignGpuMemory tile violates memory policy", | 637 "TileManager::AssignGpuMemory tile violates memory policy", |
569 TRACE_EVENT_SCOPE_THREAD); | 638 TRACE_EVENT_SCOPE_THREAD); |
570 break; | 639 break; |
571 } | 640 } |
572 | 641 |
573 // We won't be able to schedule this tile, so break out early. | 642 // We won't be able to schedule this tile, so break out early. |
574 if (tiles_that_need_to_be_rasterized->size() >= | 643 if (tiles_that_need_to_be_rasterized->size() >= |
575 scheduled_raster_task_limit_) { | 644 scheduled_raster_task_limit) { |
576 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 645 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
577 break; | 646 break; |
578 } | 647 } |
579 | 648 |
580 ManagedTileState& mts = tile->managed_state(); | 649 ManagedTileState& mts = tile->managed_state(); |
581 mts.scheduled_priority = schedule_priority++; | 650 mts.scheduled_priority = schedule_priority++; |
582 mts.resolution = priority.resolution; | 651 mts.resolution = priority.resolution; |
583 | 652 |
584 DCHECK(mts.draw_info.mode() == | 653 DCHECK(mts.draw_info.mode() == |
585 ManagedTileState::DrawInfo::PICTURE_PILE_MODE || | 654 ManagedTileState::DrawInfo::PICTURE_PILE_MODE || |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
630 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", | 699 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", |
631 !had_enough_memory_to_schedule_tiles_needed_now); | 700 !had_enough_memory_to_schedule_tiles_needed_now); |
632 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; | 701 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; |
633 | 702 |
634 memory_stats_from_last_assign_.total_budget_in_bytes = | 703 memory_stats_from_last_assign_.total_budget_in_bytes = |
635 global_state_.hard_memory_limit_in_bytes; | 704 global_state_.hard_memory_limit_in_bytes; |
636 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); | 705 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); |
637 memory_stats_from_last_assign_.had_enough_memory = | 706 memory_stats_from_last_assign_.had_enough_memory = |
638 had_enough_memory_to_schedule_tiles_needed_now; | 707 had_enough_memory_to_schedule_tiles_needed_now; |
639 | 708 |
640 raster_priority_queue_.Reset(); | |
641 | |
642 TRACE_EVENT_END2("cc", | 709 TRACE_EVENT_END2("cc", |
643 "TileManager::AssignGpuMemoryToTiles", | 710 "TileManager::AssignGpuMemoryToTiles", |
644 "all_tiles_that_need_to_be_rasterized_are_scheduled", | 711 "all_tiles_that_need_to_be_rasterized_are_scheduled", |
645 all_tiles_that_need_to_be_rasterized_are_scheduled_, | 712 all_tiles_that_need_to_be_rasterized_are_scheduled_, |
646 "had_enough_memory_to_schedule_tiles_needed_now", | 713 "had_enough_memory_to_schedule_tiles_needed_now", |
647 had_enough_memory_to_schedule_tiles_needed_now); | 714 had_enough_memory_to_schedule_tiles_needed_now); |
648 } | 715 } |
649 | 716 |
650 void TileManager::FreeResourcesForTile(Tile* tile) { | 717 void TileManager::FreeResourcesForTile(Tile* tile) { |
651 ManagedTileState& mts = tile->managed_state(); | 718 ManagedTileState& mts = tile->managed_state(); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
940 result -= other; | 1007 result -= other; |
941 return result; | 1008 return result; |
942 } | 1009 } |
943 | 1010 |
944 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 1011 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
945 return memory_bytes_ > limit.memory_bytes_ || | 1012 return memory_bytes_ > limit.memory_bytes_ || |
946 resource_count_ > limit.resource_count_; | 1013 resource_count_ > limit.resource_count_; |
947 } | 1014 } |
948 | 1015 |
949 } // namespace cc | 1016 } // namespace cc |
OLD | NEW |