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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 256 } |
257 | 257 |
258 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { | 258 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { |
259 TaskSetCollection tasks_that_should_be_forced_to_complete; | 259 TaskSetCollection tasks_that_should_be_forced_to_complete; |
260 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) | 260 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) |
261 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; | 261 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; |
262 return tasks_that_should_be_forced_to_complete; | 262 return tasks_that_should_be_forced_to_complete; |
263 } | 263 } |
264 | 264 |
265 void TileManager::FreeResourcesForReleasedTiles() { | 265 void TileManager::FreeResourcesForReleasedTiles() { |
266 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); | 266 for (auto* tile : released_tiles_) |
267 it != released_tiles_.end(); | |
268 ++it) { | |
269 Tile* tile = *it; | |
270 FreeResourcesForTile(tile); | 267 FreeResourcesForTile(tile); |
271 } | |
272 } | 268 } |
273 | 269 |
274 void TileManager::CleanUpReleasedTiles() { | 270 void TileManager::CleanUpReleasedTiles() { |
275 std::vector<Tile*> tiles_to_retain; | 271 std::vector<Tile*> tiles_to_retain; |
276 for (auto* tile : released_tiles_) { | 272 for (auto* tile : released_tiles_) { |
277 if (tile->HasRasterTask()) { | 273 if (tile->HasRasterTask()) { |
278 tiles_to_retain.push_back(tile); | 274 tiles_to_retain.push_back(tile); |
279 continue; | 275 continue; |
280 } | 276 } |
281 | 277 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 // We need to call CheckForCompletedTasks() once in-between each call | 329 // We need to call CheckForCompletedTasks() once in-between each call |
334 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 330 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
335 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 331 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
336 tile_task_runner_->CheckForCompletedTasks(); | 332 tile_task_runner_->CheckForCompletedTasks(); |
337 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 333 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
338 } | 334 } |
339 | 335 |
340 FreeResourcesForReleasedTiles(); | 336 FreeResourcesForReleasedTiles(); |
341 CleanUpReleasedTiles(); | 337 CleanUpReleasedTiles(); |
342 | 338 |
343 TileVector tiles_that_need_to_be_rasterized; | 339 PrioritizedTileVector tiles_that_need_to_be_rasterized; |
344 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 340 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
345 client_->BuildRasterQueue(global_state_.tree_priority, | 341 client_->BuildRasterQueue(global_state_.tree_priority, |
346 RasterTilePriorityQueue::Type::ALL)); | 342 RasterTilePriorityQueue::Type::ALL)); |
347 AssignGpuMemoryToTiles(raster_priority_queue.get(), | 343 AssignGpuMemoryToTiles(raster_priority_queue.get(), |
348 scheduled_raster_task_limit_, | 344 scheduled_raster_task_limit_, |
349 &tiles_that_need_to_be_rasterized); | 345 &tiles_that_need_to_be_rasterized); |
350 | 346 |
351 // Inform the client that will likely require a draw if the highest priority | 347 // Inform the client that will likely require a draw if the highest priority |
352 // tile that will be rasterized is required for draw. | 348 // tile that will be rasterized is required for draw. |
353 client_->SetIsLikelyToRequireADraw( | 349 client_->SetIsLikelyToRequireADraw( |
354 !tiles_that_need_to_be_rasterized.empty() && | 350 !tiles_that_need_to_be_rasterized.empty() && |
355 (*tiles_that_need_to_be_rasterized.begin())->required_for_draw()); | 351 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); |
356 | 352 |
357 // Schedule tile tasks. | 353 // Schedule tile tasks. |
358 ScheduleTasks(tiles_that_need_to_be_rasterized); | 354 ScheduleTasks(tiles_that_need_to_be_rasterized); |
359 | 355 |
360 did_notify_ready_to_activate_ = false; | 356 did_notify_ready_to_activate_ = false; |
361 did_notify_ready_to_draw_ = false; | 357 did_notify_ready_to_draw_ = false; |
362 | 358 |
363 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, | 359 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, |
364 "state", BasicStateAsValue()); | 360 "state", BasicStateAsValue()); |
365 | 361 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 const MemoryUsage& limit, | 404 const MemoryUsage& limit, |
409 MemoryUsage* usage) { | 405 MemoryUsage* usage) { |
410 while (usage->Exceeds(limit)) { | 406 while (usage->Exceeds(limit)) { |
411 if (!eviction_priority_queue) { | 407 if (!eviction_priority_queue) { |
412 eviction_priority_queue = | 408 eviction_priority_queue = |
413 client_->BuildEvictionQueue(global_state_.tree_priority); | 409 client_->BuildEvictionQueue(global_state_.tree_priority); |
414 } | 410 } |
415 if (eviction_priority_queue->IsEmpty()) | 411 if (eviction_priority_queue->IsEmpty()) |
416 break; | 412 break; |
417 | 413 |
418 Tile* tile = eviction_priority_queue->Top(); | 414 Tile* tile = eviction_priority_queue->Top().tile(); |
419 *usage -= MemoryUsage::FromTile(tile); | 415 *usage -= MemoryUsage::FromTile(tile); |
420 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 416 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
421 eviction_priority_queue->Pop(); | 417 eviction_priority_queue->Pop(); |
422 } | 418 } |
423 return eviction_priority_queue; | 419 return eviction_priority_queue; |
424 } | 420 } |
425 | 421 |
426 scoped_ptr<EvictionTilePriorityQueue> | 422 scoped_ptr<EvictionTilePriorityQueue> |
427 TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( | 423 TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( |
428 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, | 424 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, |
429 const MemoryUsage& limit, | 425 const MemoryUsage& limit, |
430 const TilePriority& other_priority, | 426 const TilePriority& other_priority, |
431 MemoryUsage* usage) { | 427 MemoryUsage* usage) { |
432 while (usage->Exceeds(limit)) { | 428 while (usage->Exceeds(limit)) { |
433 if (!eviction_priority_queue) { | 429 if (!eviction_priority_queue) { |
434 eviction_priority_queue = | 430 eviction_priority_queue = |
435 client_->BuildEvictionQueue(global_state_.tree_priority); | 431 client_->BuildEvictionQueue(global_state_.tree_priority); |
436 } | 432 } |
437 if (eviction_priority_queue->IsEmpty()) | 433 if (eviction_priority_queue->IsEmpty()) |
438 break; | 434 break; |
439 | 435 |
440 Tile* tile = eviction_priority_queue->Top(); | 436 const PrioritizedTile& prioritized_tile = eviction_priority_queue->Top(); |
441 if (!other_priority.IsHigherPriorityThan(tile->priority())) | 437 if (!other_priority.IsHigherPriorityThan(prioritized_tile.priority())) |
442 break; | 438 break; |
443 | 439 |
| 440 Tile* tile = prioritized_tile.tile(); |
444 *usage -= MemoryUsage::FromTile(tile); | 441 *usage -= MemoryUsage::FromTile(tile); |
445 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 442 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
446 eviction_priority_queue->Pop(); | 443 eviction_priority_queue->Pop(); |
447 } | 444 } |
448 return eviction_priority_queue; | 445 return eviction_priority_queue; |
449 } | 446 } |
450 | 447 |
451 bool TileManager::TilePriorityViolatesMemoryPolicy( | 448 bool TileManager::TilePriorityViolatesMemoryPolicy( |
452 const TilePriority& priority) { | 449 const TilePriority& priority) { |
453 switch (global_state_.memory_limit_policy) { | 450 switch (global_state_.memory_limit_policy) { |
454 case ALLOW_NOTHING: | 451 case ALLOW_NOTHING: |
455 return true; | 452 return true; |
456 case ALLOW_ABSOLUTE_MINIMUM: | 453 case ALLOW_ABSOLUTE_MINIMUM: |
457 return priority.priority_bin > TilePriority::NOW; | 454 return priority.priority_bin > TilePriority::NOW; |
458 case ALLOW_PREPAINT_ONLY: | 455 case ALLOW_PREPAINT_ONLY: |
459 return priority.priority_bin > TilePriority::SOON; | 456 return priority.priority_bin > TilePriority::SOON; |
460 case ALLOW_ANYTHING: | 457 case ALLOW_ANYTHING: |
461 return priority.distance_to_visible == | 458 return priority.distance_to_visible == |
462 std::numeric_limits<float>::infinity(); | 459 std::numeric_limits<float>::infinity(); |
463 } | 460 } |
464 NOTREACHED(); | 461 NOTREACHED(); |
465 return true; | 462 return true; |
466 } | 463 } |
467 | 464 |
468 void TileManager::AssignGpuMemoryToTiles( | 465 void TileManager::AssignGpuMemoryToTiles( |
469 RasterTilePriorityQueue* raster_priority_queue, | 466 RasterTilePriorityQueue* raster_priority_queue, |
470 size_t scheduled_raster_task_limit, | 467 size_t scheduled_raster_task_limit, |
471 TileVector* tiles_that_need_to_be_rasterized) { | 468 PrioritizedTileVector* tiles_that_need_to_be_rasterized) { |
472 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); | 469 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); |
473 | 470 |
474 // Maintain the list of released resources that can potentially be re-used | 471 // Maintain the list of released resources that can potentially be re-used |
475 // or deleted. If this operation becomes expensive too, only do this after | 472 // or deleted. If this operation becomes expensive too, only do this after |
476 // some resource(s) was returned. Note that in that case, one also need to | 473 // some resource(s) was returned. Note that in that case, one also need to |
477 // invalidate when releasing some resource from the pool. | 474 // invalidate when releasing some resource from the pool. |
478 resource_pool_->CheckBusyResources(false); | 475 resource_pool_->CheckBusyResources(false); |
479 | 476 |
480 // Now give memory out to the tiles until we're out, and build | 477 // Now give memory out to the tiles until we're out, and build |
481 // the needs-to-be-rasterized queue. | 478 // the needs-to-be-rasterized queue. |
482 unsigned schedule_priority = 1u; | 479 unsigned schedule_priority = 1u; |
483 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 480 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
484 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 481 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
485 | 482 |
486 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 483 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, |
487 global_state_.num_resources_limit); | 484 global_state_.num_resources_limit); |
488 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 485 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, |
489 global_state_.num_resources_limit); | 486 global_state_.num_resources_limit); |
490 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), | 487 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), |
491 resource_pool_->acquired_resource_count()); | 488 resource_pool_->acquired_resource_count()); |
492 | 489 |
493 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue; | 490 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue; |
494 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { | 491 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
495 Tile* tile = raster_priority_queue->Top(); | 492 const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); |
496 TilePriority priority = tile->priority(); | 493 Tile* tile = prioritized_tile.tile(); |
| 494 TilePriority priority = prioritized_tile.priority(); |
497 | 495 |
498 if (TilePriorityViolatesMemoryPolicy(priority)) { | 496 if (TilePriorityViolatesMemoryPolicy(priority)) { |
499 TRACE_EVENT_INSTANT0( | 497 TRACE_EVENT_INSTANT0( |
500 "cc", "TileManager::AssignGpuMemory tile violates memory policy", | 498 "cc", "TileManager::AssignGpuMemory tile violates memory policy", |
501 TRACE_EVENT_SCOPE_THREAD); | 499 TRACE_EVENT_SCOPE_THREAD); |
502 break; | 500 break; |
503 } | 501 } |
504 | 502 |
505 // We won't be able to schedule this tile, so break out early. | 503 // We won't be able to schedule this tile, so break out early. |
506 if (tiles_that_need_to_be_rasterized->size() >= | 504 if (tiles_that_need_to_be_rasterized->size() >= |
507 scheduled_raster_task_limit) { | 505 scheduled_raster_task_limit) { |
508 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 506 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
509 break; | 507 break; |
510 } | 508 } |
511 | 509 |
512 TileDrawInfo& draw_info = tile->draw_info(); | |
513 tile->scheduled_priority_ = schedule_priority++; | 510 tile->scheduled_priority_ = schedule_priority++; |
514 | 511 |
515 DCHECK_IMPLIES(draw_info.mode() != TileDrawInfo::OOM_MODE, | 512 DCHECK_IMPLIES(tile->draw_info().mode() != TileDrawInfo::OOM_MODE, |
516 !draw_info.IsReadyToDraw()); | 513 !tile->draw_info().IsReadyToDraw()); |
517 | 514 |
518 // If the tile already has a raster_task, then the memory used by it is | 515 // If the tile already has a raster_task, then the memory used by it is |
519 // already accounted for in memory_usage. Otherwise, we'll have to acquire | 516 // already accounted for in memory_usage. Otherwise, we'll have to acquire |
520 // more memory to create a raster task. | 517 // more memory to create a raster task. |
521 MemoryUsage memory_required_by_tile_to_be_scheduled; | 518 MemoryUsage memory_required_by_tile_to_be_scheduled; |
522 if (!tile->raster_task_.get()) { | 519 if (!tile->raster_task_.get()) { |
523 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig( | 520 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig( |
524 tile->desired_texture_size(), tile_task_runner_->GetResourceFormat()); | 521 tile->desired_texture_size(), tile_task_runner_->GetResourceFormat()); |
525 } | 522 } |
526 | 523 |
(...skipping 17 matching lines...) Expand all Loading... |
544 // If we couldn't fit the tile into our current memory limit, then we're | 541 // If we couldn't fit the tile into our current memory limit, then we're |
545 // done. | 542 // done. |
546 if (!memory_usage_is_within_limit) { | 543 if (!memory_usage_is_within_limit) { |
547 if (tile_is_needed_now) | 544 if (tile_is_needed_now) |
548 had_enough_memory_to_schedule_tiles_needed_now = false; | 545 had_enough_memory_to_schedule_tiles_needed_now = false; |
549 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 546 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
550 break; | 547 break; |
551 } | 548 } |
552 | 549 |
553 memory_usage += memory_required_by_tile_to_be_scheduled; | 550 memory_usage += memory_required_by_tile_to_be_scheduled; |
554 tiles_that_need_to_be_rasterized->push_back(tile); | 551 tiles_that_need_to_be_rasterized->push_back(prioritized_tile); |
555 } | 552 } |
556 | 553 |
557 // Note that we should try and further reduce memory in case the above loop | 554 // Note that we should try and further reduce memory in case the above loop |
558 // didn't reduce memory. This ensures that we always release as many resources | 555 // didn't reduce memory. This ensures that we always release as many resources |
559 // as possible to stay within the memory limit. | 556 // as possible to stay within the memory limit. |
560 eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit( | 557 eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit( |
561 eviction_priority_queue.Pass(), hard_memory_limit, &memory_usage); | 558 eviction_priority_queue.Pass(), hard_memory_limit, &memory_usage); |
562 | 559 |
563 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", | 560 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", |
564 !had_enough_memory_to_schedule_tiles_needed_now); | 561 !had_enough_memory_to_schedule_tiles_needed_now); |
(...skipping 20 matching lines...) Expand all Loading... |
585 | 582 |
586 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | 583 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
587 Tile* tile) { | 584 Tile* tile) { |
588 bool was_ready_to_draw = tile->IsReadyToDraw(); | 585 bool was_ready_to_draw = tile->IsReadyToDraw(); |
589 FreeResourcesForTile(tile); | 586 FreeResourcesForTile(tile); |
590 if (was_ready_to_draw) | 587 if (was_ready_to_draw) |
591 client_->NotifyTileStateChanged(tile); | 588 client_->NotifyTileStateChanged(tile); |
592 } | 589 } |
593 | 590 |
594 void TileManager::ScheduleTasks( | 591 void TileManager::ScheduleTasks( |
595 const TileVector& tiles_that_need_to_be_rasterized) { | 592 const PrioritizedTileVector& tiles_that_need_to_be_rasterized) { |
596 TRACE_EVENT1("cc", | 593 TRACE_EVENT1("cc", |
597 "TileManager::ScheduleTasks", | 594 "TileManager::ScheduleTasks", |
598 "count", | 595 "count", |
599 tiles_that_need_to_be_rasterized.size()); | 596 tiles_that_need_to_be_rasterized.size()); |
600 | 597 |
601 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 598 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
602 | 599 |
603 raster_queue_.Reset(); | 600 raster_queue_.Reset(); |
604 | 601 |
605 // Build a new task queue containing all task currently needed. Tasks | 602 // Build a new task queue containing all task currently needed. Tasks |
606 // are added in order of priority, highest priority task first. | 603 // are added in order of priority, highest priority task first. |
607 for (TileVector::const_iterator it = tiles_that_need_to_be_rasterized.begin(); | 604 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { |
608 it != tiles_that_need_to_be_rasterized.end(); | 605 Tile* tile = prioritized_tile.tile(); |
609 ++it) { | |
610 Tile* tile = *it; | |
611 TileDrawInfo& draw_info = tile->draw_info(); | |
612 | 606 |
613 DCHECK(draw_info.requires_resource()); | 607 DCHECK(tile->draw_info().requires_resource()); |
614 DCHECK(!draw_info.resource_); | 608 DCHECK(!tile->draw_info().resource_); |
615 | 609 |
616 if (!tile->raster_task_.get()) | 610 if (!tile->raster_task_.get()) |
617 tile->raster_task_ = CreateRasterTask(tile); | 611 tile->raster_task_ = CreateRasterTask(prioritized_tile); |
618 | 612 |
619 TaskSetCollection task_sets; | 613 TaskSetCollection task_sets; |
620 if (tile->required_for_activation()) | 614 if (tile->required_for_activation()) |
621 task_sets.set(REQUIRED_FOR_ACTIVATION); | 615 task_sets.set(REQUIRED_FOR_ACTIVATION); |
622 if (tile->required_for_draw()) | 616 if (tile->required_for_draw()) |
623 task_sets.set(REQUIRED_FOR_DRAW); | 617 task_sets.set(REQUIRED_FOR_DRAW); |
624 task_sets.set(ALL); | 618 task_sets.set(ALL); |
625 raster_queue_.items.push_back( | 619 raster_queue_.items.push_back( |
626 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); | 620 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); |
627 } | 621 } |
(...skipping 19 matching lines...) Expand all Loading... |
647 Tile* tile, | 641 Tile* tile, |
648 SkPixelRef* pixel_ref) { | 642 SkPixelRef* pixel_ref) { |
649 return make_scoped_refptr(new ImageDecodeTaskImpl( | 643 return make_scoped_refptr(new ImageDecodeTaskImpl( |
650 pixel_ref, | 644 pixel_ref, |
651 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 645 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
652 base::Unretained(this), | 646 base::Unretained(this), |
653 tile->layer_id(), | 647 tile->layer_id(), |
654 base::Unretained(pixel_ref)))); | 648 base::Unretained(pixel_ref)))); |
655 } | 649 } |
656 | 650 |
657 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { | 651 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
| 652 const PrioritizedTile& prioritized_tile) { |
| 653 Tile* tile = prioritized_tile.tile(); |
658 scoped_ptr<ScopedResource> resource = | 654 scoped_ptr<ScopedResource> resource = |
659 resource_pool_->AcquireResource(tile->desired_texture_size(), | 655 resource_pool_->AcquireResource(tile->desired_texture_size(), |
660 tile_task_runner_->GetResourceFormat()); | 656 tile_task_runner_->GetResourceFormat()); |
661 const ScopedResource* const_resource = resource.get(); | 657 const ScopedResource* const_resource = resource.get(); |
662 | 658 |
663 // Create and queue all image decode tasks that this tile depends on. | 659 // Create and queue all image decode tasks that this tile depends on. |
664 ImageDecodeTask::Vector decode_tasks; | 660 ImageDecodeTask::Vector decode_tasks; |
665 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; | 661 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; |
666 std::vector<SkPixelRef*> pixel_refs; | 662 std::vector<SkPixelRef*> pixel_refs; |
667 tile->raster_source()->GatherPixelRefs( | 663 tile->raster_source()->GatherPixelRefs( |
(...skipping 10 matching lines...) Expand all Loading... |
678 | 674 |
679 // Create and append new image decode task for this pixel ref. | 675 // Create and append new image decode task for this pixel ref. |
680 scoped_refptr<ImageDecodeTask> decode_task = | 676 scoped_refptr<ImageDecodeTask> decode_task = |
681 CreateImageDecodeTask(tile, pixel_ref); | 677 CreateImageDecodeTask(tile, pixel_ref); |
682 decode_tasks.push_back(decode_task); | 678 decode_tasks.push_back(decode_task); |
683 existing_pixel_refs[id] = decode_task; | 679 existing_pixel_refs[id] = decode_task; |
684 } | 680 } |
685 | 681 |
686 return make_scoped_refptr(new RasterTaskImpl( | 682 return make_scoped_refptr(new RasterTaskImpl( |
687 const_resource, tile->raster_source(), tile->content_rect(), | 683 const_resource, tile->raster_source(), tile->content_rect(), |
688 tile->contents_scale(), tile->priority().resolution, tile->layer_id(), | 684 tile->contents_scale(), prioritized_tile.priority().resolution, |
689 static_cast<const void*>(tile), tile->source_frame_number(), | 685 tile->layer_id(), static_cast<const void*>(tile), |
690 tile->use_picture_analysis(), | 686 tile->source_frame_number(), tile->use_picture_analysis(), |
691 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 687 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
692 tile->id(), base::Passed(&resource)), | 688 tile->id(), base::Passed(&resource)), |
693 &decode_tasks)); | 689 &decode_tasks)); |
694 } | 690 } |
695 | 691 |
696 void TileManager::OnImageDecodeTaskCompleted(int layer_id, | 692 void TileManager::OnImageDecodeTaskCompleted(int layer_id, |
697 SkPixelRef* pixel_ref, | 693 SkPixelRef* pixel_ref, |
698 bool was_canceled) { | 694 bool was_canceled) { |
699 // If the task was canceled, we need to clean it up | 695 // If the task was canceled, we need to clean it up |
700 // from |image_decode_tasks_|. | 696 // from |image_decode_tasks_|. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 bool TileManager::AreRequiredTilesReadyToDraw( | 777 bool TileManager::AreRequiredTilesReadyToDraw( |
782 RasterTilePriorityQueue::Type type) const { | 778 RasterTilePriorityQueue::Type type) const { |
783 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 779 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
784 client_->BuildRasterQueue(global_state_.tree_priority, type)); | 780 client_->BuildRasterQueue(global_state_.tree_priority, type)); |
785 // It is insufficient to check whether the raster queue we constructed is | 781 // It is insufficient to check whether the raster queue we constructed is |
786 // empty. The reason for this is that there are situations (rasterize on | 782 // empty. The reason for this is that there are situations (rasterize on |
787 // demand) when the tile both needs raster and it's ready to draw. Hence, we | 783 // demand) when the tile both needs raster and it's ready to draw. Hence, we |
788 // have to iterate the queue to check whether the required tiles are ready to | 784 // have to iterate the queue to check whether the required tiles are ready to |
789 // draw. | 785 // draw. |
790 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { | 786 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
791 if (!raster_priority_queue->Top()->IsReadyToDraw()) | 787 if (!raster_priority_queue->Top().tile()->IsReadyToDraw()) |
792 return false; | 788 return false; |
793 } | 789 } |
794 | 790 |
795 #if DCHECK_IS_ON() | 791 #if DCHECK_IS_ON() |
796 scoped_ptr<RasterTilePriorityQueue> all_queue( | 792 scoped_ptr<RasterTilePriorityQueue> all_queue( |
797 client_->BuildRasterQueue(global_state_.tree_priority, type)); | 793 client_->BuildRasterQueue(global_state_.tree_priority, type)); |
798 for (; !all_queue->IsEmpty(); all_queue->Pop()) { | 794 for (; !all_queue->IsEmpty(); all_queue->Pop()) { |
799 auto* tile = all_queue->Top(); | 795 Tile* tile = all_queue->Top().tile(); |
800 DCHECK_IMPLIES(tile->required_for_activation(), tile->IsReadyToDraw()); | 796 DCHECK_IMPLIES(tile->required_for_activation(), tile->IsReadyToDraw()); |
801 } | 797 } |
802 #endif | 798 #endif |
803 return true; | 799 return true; |
804 } | 800 } |
805 bool TileManager::IsReadyToActivate() const { | 801 bool TileManager::IsReadyToActivate() const { |
806 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); | 802 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); |
807 return AreRequiredTilesReadyToDraw( | 803 return AreRequiredTilesReadyToDraw( |
808 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); | 804 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); |
809 } | 805 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 | 853 |
858 NotifyReadyToDraw(); | 854 NotifyReadyToDraw(); |
859 } | 855 } |
860 | 856 |
861 void TileManager::CheckIfMoreTilesNeedToBePrepared() { | 857 void TileManager::CheckIfMoreTilesNeedToBePrepared() { |
862 tile_task_runner_->CheckForCompletedTasks(); | 858 tile_task_runner_->CheckForCompletedTasks(); |
863 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 859 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
864 | 860 |
865 // When OOM, keep re-assigning memory until we reach a steady state | 861 // When OOM, keep re-assigning memory until we reach a steady state |
866 // where top-priority tiles are initialized. | 862 // where top-priority tiles are initialized. |
867 TileVector tiles_that_need_to_be_rasterized; | 863 PrioritizedTileVector tiles_that_need_to_be_rasterized; |
868 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 864 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
869 client_->BuildRasterQueue(global_state_.tree_priority, | 865 client_->BuildRasterQueue(global_state_.tree_priority, |
870 RasterTilePriorityQueue::Type::ALL)); | 866 RasterTilePriorityQueue::Type::ALL)); |
871 AssignGpuMemoryToTiles(raster_priority_queue.get(), | 867 AssignGpuMemoryToTiles(raster_priority_queue.get(), |
872 scheduled_raster_task_limit_, | 868 scheduled_raster_task_limit_, |
873 &tiles_that_need_to_be_rasterized); | 869 &tiles_that_need_to_be_rasterized); |
874 | 870 |
875 // Inform the client that will likely require a draw if the highest priority | 871 // Inform the client that will likely require a draw if the highest priority |
876 // tile that will be rasterized is required for draw. | 872 // tile that will be rasterized is required for draw. |
877 client_->SetIsLikelyToRequireADraw( | 873 client_->SetIsLikelyToRequireADraw( |
878 !tiles_that_need_to_be_rasterized.empty() && | 874 !tiles_that_need_to_be_rasterized.empty() && |
879 (*tiles_that_need_to_be_rasterized.begin())->required_for_draw()); | 875 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); |
880 | 876 |
881 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 877 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
882 // steady memory state. Keep scheduling tasks until we reach this state. | 878 // steady memory state. Keep scheduling tasks until we reach this state. |
883 if (!tiles_that_need_to_be_rasterized.empty()) { | 879 if (!tiles_that_need_to_be_rasterized.empty()) { |
884 ScheduleTasks(tiles_that_need_to_be_rasterized); | 880 ScheduleTasks(tiles_that_need_to_be_rasterized); |
885 return; | 881 return; |
886 } | 882 } |
887 | 883 |
888 FreeResourcesForReleasedTiles(); | 884 FreeResourcesForReleasedTiles(); |
889 | 885 |
(...skipping 20 matching lines...) Expand all Loading... |
910 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); | 906 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); |
911 | 907 |
912 // If we have tiles left to raster for activation, and we don't allow | 908 // If we have tiles left to raster for activation, and we don't allow |
913 // activating without them, then skip activation and return early. | 909 // activating without them, then skip activation and return early. |
914 if (!required_for_activation_queue->IsEmpty() && wait_for_all_required_tiles) | 910 if (!required_for_activation_queue->IsEmpty() && wait_for_all_required_tiles) |
915 return; | 911 return; |
916 | 912 |
917 // Mark required tiles as OOM so that we can activate without them. | 913 // Mark required tiles as OOM so that we can activate without them. |
918 for (; !required_for_activation_queue->IsEmpty(); | 914 for (; !required_for_activation_queue->IsEmpty(); |
919 required_for_activation_queue->Pop()) { | 915 required_for_activation_queue->Pop()) { |
920 Tile* tile = required_for_activation_queue->Top(); | 916 Tile* tile = required_for_activation_queue->Top().tile(); |
921 tile->draw_info().set_oom(); | 917 tile->draw_info().set_oom(); |
922 client_->NotifyTileStateChanged(tile); | 918 client_->NotifyTileStateChanged(tile); |
923 } | 919 } |
924 | 920 |
925 DCHECK(IsReadyToActivate()); | 921 DCHECK(IsReadyToActivate()); |
926 ready_to_activate_check_notifier_.Schedule(); | 922 ready_to_activate_check_notifier_.Schedule(); |
927 } | 923 } |
928 | 924 |
929 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 925 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
930 } | 926 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 result -= other; | 966 result -= other; |
971 return result; | 967 return result; |
972 } | 968 } |
973 | 969 |
974 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 970 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
975 return memory_bytes_ > limit.memory_bytes_ || | 971 return memory_bytes_ > limit.memory_bytes_ || |
976 resource_count_ > limit.resource_count_; | 972 resource_count_ > limit.resource_count_; |
977 } | 973 } |
978 | 974 |
979 } // namespace cc | 975 } // namespace cc |
OLD | NEW |