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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 } | 264 } |
265 | 265 |
266 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { | 266 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { |
267 TaskSetCollection tasks_that_should_be_forced_to_complete; | 267 TaskSetCollection tasks_that_should_be_forced_to_complete; |
268 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) | 268 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) |
269 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; | 269 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; |
270 return tasks_that_should_be_forced_to_complete; | 270 return tasks_that_should_be_forced_to_complete; |
271 } | 271 } |
272 | 272 |
273 void TileManager::FreeResourcesForReleasedTiles() { | 273 void TileManager::FreeResourcesForReleasedTiles() { |
274 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); | 274 for (auto tile : released_tiles_) |
vmpstr
2015/05/08 18:11:06
nit: auto*
hendrikw
2015/05/08 19:21:02
Ugh, done.
| |
275 it != released_tiles_.end(); | |
276 ++it) { | |
277 Tile* tile = *it; | |
278 FreeResourcesForTile(tile); | 275 FreeResourcesForTile(tile); |
279 } | |
280 } | 276 } |
281 | 277 |
282 void TileManager::CleanUpReleasedTiles() { | 278 void TileManager::CleanUpReleasedTiles() { |
283 std::vector<Tile*> tiles_to_retain; | 279 std::vector<Tile*> tiles_to_retain; |
284 for (auto* tile : released_tiles_) { | 280 for (auto* tile : released_tiles_) { |
285 if (tile->HasRasterTask()) { | 281 if (tile->HasRasterTask()) { |
286 tiles_to_retain.push_back(tile); | 282 tiles_to_retain.push_back(tile); |
287 continue; | 283 continue; |
288 } | 284 } |
289 | 285 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 // We need to call CheckForCompletedTasks() once in-between each call | 337 // We need to call CheckForCompletedTasks() once in-between each call |
342 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 338 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
343 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 339 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
344 tile_task_runner_->CheckForCompletedTasks(); | 340 tile_task_runner_->CheckForCompletedTasks(); |
345 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 341 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
346 } | 342 } |
347 | 343 |
348 FreeResourcesForReleasedTiles(); | 344 FreeResourcesForReleasedTiles(); |
349 CleanUpReleasedTiles(); | 345 CleanUpReleasedTiles(); |
350 | 346 |
351 TileVector tiles_that_need_to_be_rasterized; | 347 PrioritizedTileVector tiles_that_need_to_be_rasterized; |
352 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 348 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
353 client_->BuildRasterQueue(global_state_.tree_priority, | 349 client_->BuildRasterQueue(global_state_.tree_priority, |
354 RasterTilePriorityQueue::Type::ALL)); | 350 RasterTilePriorityQueue::Type::ALL)); |
355 AssignGpuMemoryToTiles(raster_priority_queue.get(), | 351 AssignGpuMemoryToTiles(raster_priority_queue.get(), |
356 scheduled_raster_task_limit_, | 352 scheduled_raster_task_limit_, |
357 &tiles_that_need_to_be_rasterized); | 353 &tiles_that_need_to_be_rasterized); |
358 | 354 |
359 // Inform the client that will likely require a draw if the highest priority | 355 // Inform the client that will likely require a draw if the highest priority |
360 // tile that will be rasterized is required for draw. | 356 // tile that will be rasterized is required for draw. |
361 client_->SetIsLikelyToRequireADraw( | 357 client_->SetIsLikelyToRequireADraw( |
362 !tiles_that_need_to_be_rasterized.empty() && | 358 !tiles_that_need_to_be_rasterized.empty() && |
363 (*tiles_that_need_to_be_rasterized.begin())->required_for_draw()); | 359 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); |
364 | 360 |
365 // Schedule tile tasks. | 361 // Schedule tile tasks. |
366 ScheduleTasks(tiles_that_need_to_be_rasterized); | 362 ScheduleTasks(tiles_that_need_to_be_rasterized); |
367 | 363 |
368 did_notify_ready_to_activate_ = false; | 364 did_notify_ready_to_activate_ = false; |
369 did_notify_ready_to_draw_ = false; | 365 did_notify_ready_to_draw_ = false; |
370 | 366 |
371 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, | 367 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, |
372 "state", BasicStateAsValue()); | 368 "state", BasicStateAsValue()); |
373 | 369 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 const MemoryUsage& limit, | 412 const MemoryUsage& limit, |
417 MemoryUsage* usage) { | 413 MemoryUsage* usage) { |
418 while (usage->Exceeds(limit)) { | 414 while (usage->Exceeds(limit)) { |
419 if (!eviction_priority_queue) { | 415 if (!eviction_priority_queue) { |
420 eviction_priority_queue = | 416 eviction_priority_queue = |
421 client_->BuildEvictionQueue(global_state_.tree_priority); | 417 client_->BuildEvictionQueue(global_state_.tree_priority); |
422 } | 418 } |
423 if (eviction_priority_queue->IsEmpty()) | 419 if (eviction_priority_queue->IsEmpty()) |
424 break; | 420 break; |
425 | 421 |
426 Tile* tile = eviction_priority_queue->Top(); | 422 Tile* tile = eviction_priority_queue->Top().tile(); |
427 *usage -= MemoryUsage::FromTile(tile); | 423 *usage -= MemoryUsage::FromTile(tile); |
428 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 424 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
429 eviction_priority_queue->Pop(); | 425 eviction_priority_queue->Pop(); |
430 } | 426 } |
431 return eviction_priority_queue; | 427 return eviction_priority_queue; |
432 } | 428 } |
433 | 429 |
434 scoped_ptr<EvictionTilePriorityQueue> | 430 scoped_ptr<EvictionTilePriorityQueue> |
435 TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( | 431 TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( |
436 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, | 432 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue, |
437 const MemoryUsage& limit, | 433 const MemoryUsage& limit, |
438 const TilePriority& other_priority, | 434 const TilePriority& other_priority, |
439 MemoryUsage* usage) { | 435 MemoryUsage* usage) { |
440 while (usage->Exceeds(limit)) { | 436 while (usage->Exceeds(limit)) { |
441 if (!eviction_priority_queue) { | 437 if (!eviction_priority_queue) { |
442 eviction_priority_queue = | 438 eviction_priority_queue = |
443 client_->BuildEvictionQueue(global_state_.tree_priority); | 439 client_->BuildEvictionQueue(global_state_.tree_priority); |
444 } | 440 } |
445 if (eviction_priority_queue->IsEmpty()) | 441 if (eviction_priority_queue->IsEmpty()) |
446 break; | 442 break; |
447 | 443 |
448 Tile* tile = eviction_priority_queue->Top(); | 444 const PrioritizedTile& prioritized_tile = eviction_priority_queue->Top(); |
449 if (!other_priority.IsHigherPriorityThan(tile->priority())) | 445 if (!other_priority.IsHigherPriorityThan(prioritized_tile.priority())) |
450 break; | 446 break; |
451 | 447 |
448 Tile* tile = prioritized_tile.tile(); | |
452 *usage -= MemoryUsage::FromTile(tile); | 449 *usage -= MemoryUsage::FromTile(tile); |
453 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 450 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
454 eviction_priority_queue->Pop(); | 451 eviction_priority_queue->Pop(); |
455 } | 452 } |
456 return eviction_priority_queue; | 453 return eviction_priority_queue; |
457 } | 454 } |
458 | 455 |
459 bool TileManager::TilePriorityViolatesMemoryPolicy( | 456 bool TileManager::TilePriorityViolatesMemoryPolicy( |
460 const TilePriority& priority) { | 457 const TilePriority& priority) { |
461 switch (global_state_.memory_limit_policy) { | 458 switch (global_state_.memory_limit_policy) { |
462 case ALLOW_NOTHING: | 459 case ALLOW_NOTHING: |
463 return true; | 460 return true; |
464 case ALLOW_ABSOLUTE_MINIMUM: | 461 case ALLOW_ABSOLUTE_MINIMUM: |
465 return priority.priority_bin > TilePriority::NOW; | 462 return priority.priority_bin > TilePriority::NOW; |
466 case ALLOW_PREPAINT_ONLY: | 463 case ALLOW_PREPAINT_ONLY: |
467 return priority.priority_bin > TilePriority::SOON; | 464 return priority.priority_bin > TilePriority::SOON; |
468 case ALLOW_ANYTHING: | 465 case ALLOW_ANYTHING: |
469 return priority.distance_to_visible == | 466 return priority.distance_to_visible == |
470 std::numeric_limits<float>::infinity(); | 467 std::numeric_limits<float>::infinity(); |
471 } | 468 } |
472 NOTREACHED(); | 469 NOTREACHED(); |
473 return true; | 470 return true; |
474 } | 471 } |
475 | 472 |
476 void TileManager::AssignGpuMemoryToTiles( | 473 void TileManager::AssignGpuMemoryToTiles( |
477 RasterTilePriorityQueue* raster_priority_queue, | 474 RasterTilePriorityQueue* raster_priority_queue, |
478 size_t scheduled_raster_task_limit, | 475 size_t scheduled_raster_task_limit, |
479 TileVector* tiles_that_need_to_be_rasterized) { | 476 PrioritizedTileVector* tiles_that_need_to_be_rasterized) { |
480 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); | 477 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); |
481 | 478 |
482 // Maintain the list of released resources that can potentially be re-used | 479 // Maintain the list of released resources that can potentially be re-used |
483 // or deleted. If this operation becomes expensive too, only do this after | 480 // or deleted. If this operation becomes expensive too, only do this after |
484 // some resource(s) was returned. Note that in that case, one also need to | 481 // some resource(s) was returned. Note that in that case, one also need to |
485 // invalidate when releasing some resource from the pool. | 482 // invalidate when releasing some resource from the pool. |
486 resource_pool_->CheckBusyResources(false); | 483 resource_pool_->CheckBusyResources(false); |
487 | 484 |
488 // Now give memory out to the tiles until we're out, and build | 485 // Now give memory out to the tiles until we're out, and build |
489 // the needs-to-be-rasterized queue. | 486 // the needs-to-be-rasterized queue. |
490 unsigned schedule_priority = 1u; | 487 unsigned schedule_priority = 1u; |
491 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 488 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
492 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 489 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
493 | 490 |
494 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 491 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, |
495 global_state_.num_resources_limit); | 492 global_state_.num_resources_limit); |
496 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 493 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, |
497 global_state_.num_resources_limit); | 494 global_state_.num_resources_limit); |
498 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), | 495 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), |
499 resource_pool_->acquired_resource_count()); | 496 resource_pool_->acquired_resource_count()); |
500 | 497 |
501 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue; | 498 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue; |
502 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { | 499 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
503 Tile* tile = raster_priority_queue->Top(); | 500 const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); |
504 TilePriority priority = tile->priority(); | 501 Tile* tile = prioritized_tile.tile(); |
502 TilePriority priority = prioritized_tile.priority(); | |
505 | 503 |
506 if (TilePriorityViolatesMemoryPolicy(priority)) { | 504 if (TilePriorityViolatesMemoryPolicy(priority)) { |
507 TRACE_EVENT_INSTANT0( | 505 TRACE_EVENT_INSTANT0( |
508 "cc", "TileManager::AssignGpuMemory tile violates memory policy", | 506 "cc", "TileManager::AssignGpuMemory tile violates memory policy", |
509 TRACE_EVENT_SCOPE_THREAD); | 507 TRACE_EVENT_SCOPE_THREAD); |
510 break; | 508 break; |
511 } | 509 } |
512 | 510 |
513 // We won't be able to schedule this tile, so break out early. | 511 // We won't be able to schedule this tile, so break out early. |
514 if (tiles_that_need_to_be_rasterized->size() >= | 512 if (tiles_that_need_to_be_rasterized->size() >= |
515 scheduled_raster_task_limit) { | 513 scheduled_raster_task_limit) { |
516 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 514 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
517 break; | 515 break; |
518 } | 516 } |
519 | 517 |
520 TileDrawInfo& draw_info = tile->draw_info(); | 518 const TileDrawInfo& draw_info = tile->draw_info(); |
vmpstr
2015/05/08 18:11:06
Since this is only used in the dcheck below, can y
hendrikw
2015/05/08 19:21:02
Done.
| |
521 tile->scheduled_priority_ = schedule_priority++; | 519 tile->scheduled_priority_ = schedule_priority++; |
522 | 520 |
523 DCHECK_IMPLIES(draw_info.mode() != TileDrawInfo::OOM_MODE, | 521 DCHECK_IMPLIES(draw_info.mode() != TileDrawInfo::OOM_MODE, |
524 !draw_info.IsReadyToDraw()); | 522 !draw_info.IsReadyToDraw()); |
525 | 523 |
526 // If the tile already has a raster_task, then the memory used by it is | 524 // If the tile already has a raster_task, then the memory used by it is |
527 // already accounted for in memory_usage. Otherwise, we'll have to acquire | 525 // already accounted for in memory_usage. Otherwise, we'll have to acquire |
528 // more memory to create a raster task. | 526 // more memory to create a raster task. |
529 MemoryUsage memory_required_by_tile_to_be_scheduled; | 527 MemoryUsage memory_required_by_tile_to_be_scheduled; |
530 if (!tile->raster_task_.get()) { | 528 if (!tile->raster_task_.get()) { |
(...skipping 21 matching lines...) Expand all Loading... | |
552 // If we couldn't fit the tile into our current memory limit, then we're | 550 // If we couldn't fit the tile into our current memory limit, then we're |
553 // done. | 551 // done. |
554 if (!memory_usage_is_within_limit) { | 552 if (!memory_usage_is_within_limit) { |
555 if (tile_is_needed_now) | 553 if (tile_is_needed_now) |
556 had_enough_memory_to_schedule_tiles_needed_now = false; | 554 had_enough_memory_to_schedule_tiles_needed_now = false; |
557 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 555 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
558 break; | 556 break; |
559 } | 557 } |
560 | 558 |
561 memory_usage += memory_required_by_tile_to_be_scheduled; | 559 memory_usage += memory_required_by_tile_to_be_scheduled; |
562 tiles_that_need_to_be_rasterized->push_back(tile); | 560 tiles_that_need_to_be_rasterized->push_back(prioritized_tile); |
563 } | 561 } |
564 | 562 |
565 // Note that we should try and further reduce memory in case the above loop | 563 // Note that we should try and further reduce memory in case the above loop |
566 // didn't reduce memory. This ensures that we always release as many resources | 564 // didn't reduce memory. This ensures that we always release as many resources |
567 // as possible to stay within the memory limit. | 565 // as possible to stay within the memory limit. |
568 eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit( | 566 eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit( |
569 eviction_priority_queue.Pass(), hard_memory_limit, &memory_usage); | 567 eviction_priority_queue.Pass(), hard_memory_limit, &memory_usage); |
570 | 568 |
571 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", | 569 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", |
572 !had_enough_memory_to_schedule_tiles_needed_now); | 570 !had_enough_memory_to_schedule_tiles_needed_now); |
(...skipping 20 matching lines...) Expand all Loading... | |
593 | 591 |
594 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | 592 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
595 Tile* tile) { | 593 Tile* tile) { |
596 bool was_ready_to_draw = tile->IsReadyToDraw(); | 594 bool was_ready_to_draw = tile->IsReadyToDraw(); |
597 FreeResourcesForTile(tile); | 595 FreeResourcesForTile(tile); |
598 if (was_ready_to_draw) | 596 if (was_ready_to_draw) |
599 client_->NotifyTileStateChanged(tile); | 597 client_->NotifyTileStateChanged(tile); |
600 } | 598 } |
601 | 599 |
602 void TileManager::ScheduleTasks( | 600 void TileManager::ScheduleTasks( |
603 const TileVector& tiles_that_need_to_be_rasterized) { | 601 const PrioritizedTileVector& tiles_that_need_to_be_rasterized) { |
604 TRACE_EVENT1("cc", | 602 TRACE_EVENT1("cc", |
605 "TileManager::ScheduleTasks", | 603 "TileManager::ScheduleTasks", |
606 "count", | 604 "count", |
607 tiles_that_need_to_be_rasterized.size()); | 605 tiles_that_need_to_be_rasterized.size()); |
608 | 606 |
609 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 607 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
610 | 608 |
611 raster_queue_.Reset(); | 609 raster_queue_.Reset(); |
612 | 610 |
613 // Build a new task queue containing all task currently needed. Tasks | 611 // Build a new task queue containing all task currently needed. Tasks |
614 // are added in order of priority, highest priority task first. | 612 // are added in order of priority, highest priority task first. |
615 for (TileVector::const_iterator it = tiles_that_need_to_be_rasterized.begin(); | 613 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { |
616 it != tiles_that_need_to_be_rasterized.end(); | 614 Tile* tile = prioritized_tile.tile(); |
617 ++it) { | 615 const TileDrawInfo& draw_info = tile->draw_info(); |
618 Tile* tile = *it; | |
619 TileDrawInfo& draw_info = tile->draw_info(); | |
620 | 616 |
621 DCHECK(draw_info.requires_resource()); | 617 DCHECK(draw_info.requires_resource()); |
622 DCHECK(!draw_info.resource_); | 618 DCHECK(!draw_info.resource_); |
623 | 619 |
624 if (!tile->raster_task_.get()) | 620 if (!tile->raster_task_.get()) |
625 tile->raster_task_ = CreateRasterTask(tile); | 621 tile->raster_task_ = CreateRasterTask(prioritized_tile); |
626 | 622 |
627 TaskSetCollection task_sets; | 623 TaskSetCollection task_sets; |
628 if (tile->required_for_activation()) | 624 if (tile->required_for_activation()) |
629 task_sets.set(REQUIRED_FOR_ACTIVATION); | 625 task_sets.set(REQUIRED_FOR_ACTIVATION); |
630 if (tile->required_for_draw()) | 626 if (tile->required_for_draw()) |
631 task_sets.set(REQUIRED_FOR_DRAW); | 627 task_sets.set(REQUIRED_FOR_DRAW); |
632 task_sets.set(ALL); | 628 task_sets.set(ALL); |
633 raster_queue_.items.push_back( | 629 raster_queue_.items.push_back( |
634 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); | 630 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); |
635 } | 631 } |
(...skipping 19 matching lines...) Expand all Loading... | |
655 Tile* tile, | 651 Tile* tile, |
656 SkPixelRef* pixel_ref) { | 652 SkPixelRef* pixel_ref) { |
657 return make_scoped_refptr(new ImageDecodeTaskImpl( | 653 return make_scoped_refptr(new ImageDecodeTaskImpl( |
658 pixel_ref, | 654 pixel_ref, |
659 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 655 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
660 base::Unretained(this), | 656 base::Unretained(this), |
661 tile->layer_id(), | 657 tile->layer_id(), |
662 base::Unretained(pixel_ref)))); | 658 base::Unretained(pixel_ref)))); |
663 } | 659 } |
664 | 660 |
665 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { | 661 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
662 const PrioritizedTile& prioritized_tile) { | |
663 Tile* tile = prioritized_tile.tile(); | |
666 scoped_ptr<ScopedResource> resource = | 664 scoped_ptr<ScopedResource> resource = |
667 resource_pool_->AcquireResource(tile->desired_texture_size(), | 665 resource_pool_->AcquireResource(tile->desired_texture_size(), |
668 tile_task_runner_->GetResourceFormat()); | 666 tile_task_runner_->GetResourceFormat()); |
669 const ScopedResource* const_resource = resource.get(); | 667 const ScopedResource* const_resource = resource.get(); |
670 | 668 |
671 // Create and queue all image decode tasks that this tile depends on. | 669 // Create and queue all image decode tasks that this tile depends on. |
672 ImageDecodeTask::Vector decode_tasks; | 670 ImageDecodeTask::Vector decode_tasks; |
673 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; | 671 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; |
674 std::vector<SkPixelRef*> pixel_refs; | 672 std::vector<SkPixelRef*> pixel_refs; |
675 tile->raster_source()->GatherPixelRefs( | 673 tile->raster_source()->GatherPixelRefs( |
(...skipping 10 matching lines...) Expand all Loading... | |
686 | 684 |
687 // Create and append new image decode task for this pixel ref. | 685 // Create and append new image decode task for this pixel ref. |
688 scoped_refptr<ImageDecodeTask> decode_task = | 686 scoped_refptr<ImageDecodeTask> decode_task = |
689 CreateImageDecodeTask(tile, pixel_ref); | 687 CreateImageDecodeTask(tile, pixel_ref); |
690 decode_tasks.push_back(decode_task); | 688 decode_tasks.push_back(decode_task); |
691 existing_pixel_refs[id] = decode_task; | 689 existing_pixel_refs[id] = decode_task; |
692 } | 690 } |
693 | 691 |
694 return make_scoped_refptr(new RasterTaskImpl( | 692 return make_scoped_refptr(new RasterTaskImpl( |
695 const_resource, tile->raster_source(), tile->content_rect(), | 693 const_resource, tile->raster_source(), tile->content_rect(), |
696 tile->contents_scale(), tile->priority().resolution, tile->layer_id(), | 694 tile->contents_scale(), prioritized_tile.priority().resolution, |
697 static_cast<const void*>(tile), tile->source_frame_number(), | 695 tile->layer_id(), static_cast<const void*>(tile), |
698 tile->use_picture_analysis(), | 696 tile->source_frame_number(), tile->use_picture_analysis(), |
699 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 697 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
700 tile->id(), base::Passed(&resource)), | 698 tile->id(), base::Passed(&resource)), |
701 &decode_tasks)); | 699 &decode_tasks)); |
702 } | 700 } |
703 | 701 |
704 void TileManager::OnImageDecodeTaskCompleted(int layer_id, | 702 void TileManager::OnImageDecodeTaskCompleted(int layer_id, |
705 SkPixelRef* pixel_ref, | 703 SkPixelRef* pixel_ref, |
706 bool was_canceled) { | 704 bool was_canceled) { |
707 // If the task was canceled, we need to clean it up | 705 // If the task was canceled, we need to clean it up |
708 // from |image_decode_tasks_|. | 706 // from |image_decode_tasks_|. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
790 bool TileManager::AreRequiredTilesReadyToDraw( | 788 bool TileManager::AreRequiredTilesReadyToDraw( |
791 RasterTilePriorityQueue::Type type) const { | 789 RasterTilePriorityQueue::Type type) const { |
792 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 790 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
793 client_->BuildRasterQueue(global_state_.tree_priority, type)); | 791 client_->BuildRasterQueue(global_state_.tree_priority, type)); |
794 // It is insufficient to check whether the raster queue we constructed is | 792 // It is insufficient to check whether the raster queue we constructed is |
795 // empty. The reason for this is that there are situations (rasterize on | 793 // empty. The reason for this is that there are situations (rasterize on |
796 // demand) when the tile both needs raster and it's ready to draw. Hence, we | 794 // demand) when the tile both needs raster and it's ready to draw. Hence, we |
797 // have to iterate the queue to check whether the required tiles are ready to | 795 // have to iterate the queue to check whether the required tiles are ready to |
798 // draw. | 796 // draw. |
799 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { | 797 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
800 if (!raster_priority_queue->Top()->IsReadyToDraw()) | 798 if (!raster_priority_queue->Top().tile()->IsReadyToDraw()) |
801 return false; | 799 return false; |
802 } | 800 } |
803 | 801 |
804 #if DCHECK_IS_ON() | 802 #if DCHECK_IS_ON() |
805 scoped_ptr<RasterTilePriorityQueue> all_queue( | 803 scoped_ptr<RasterTilePriorityQueue> all_queue( |
806 client_->BuildRasterQueue(global_state_.tree_priority, type)); | 804 client_->BuildRasterQueue(global_state_.tree_priority, type)); |
807 for (; !all_queue->IsEmpty(); all_queue->Pop()) { | 805 for (; !all_queue->IsEmpty(); all_queue->Pop()) { |
808 auto* tile = all_queue->Top(); | 806 Tile* tile = all_queue->Top().tile(); |
809 DCHECK_IMPLIES(tile->required_for_activation(), tile->IsReadyToDraw()); | 807 DCHECK_IMPLIES(tile->required_for_activation(), tile->IsReadyToDraw()); |
810 } | 808 } |
811 #endif | 809 #endif |
812 return true; | 810 return true; |
813 } | 811 } |
814 bool TileManager::IsReadyToActivate() const { | 812 bool TileManager::IsReadyToActivate() const { |
815 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); | 813 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); |
816 return AreRequiredTilesReadyToDraw( | 814 return AreRequiredTilesReadyToDraw( |
817 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); | 815 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); |
818 } | 816 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
866 | 864 |
867 NotifyReadyToDraw(); | 865 NotifyReadyToDraw(); |
868 } | 866 } |
869 | 867 |
870 void TileManager::CheckIfMoreTilesNeedToBePrepared() { | 868 void TileManager::CheckIfMoreTilesNeedToBePrepared() { |
871 tile_task_runner_->CheckForCompletedTasks(); | 869 tile_task_runner_->CheckForCompletedTasks(); |
872 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 870 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
873 | 871 |
874 // When OOM, keep re-assigning memory until we reach a steady state | 872 // When OOM, keep re-assigning memory until we reach a steady state |
875 // where top-priority tiles are initialized. | 873 // where top-priority tiles are initialized. |
876 TileVector tiles_that_need_to_be_rasterized; | 874 PrioritizedTileVector tiles_that_need_to_be_rasterized; |
877 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( | 875 scoped_ptr<RasterTilePriorityQueue> raster_priority_queue( |
878 client_->BuildRasterQueue(global_state_.tree_priority, | 876 client_->BuildRasterQueue(global_state_.tree_priority, |
879 RasterTilePriorityQueue::Type::ALL)); | 877 RasterTilePriorityQueue::Type::ALL)); |
880 AssignGpuMemoryToTiles(raster_priority_queue.get(), | 878 AssignGpuMemoryToTiles(raster_priority_queue.get(), |
881 scheduled_raster_task_limit_, | 879 scheduled_raster_task_limit_, |
882 &tiles_that_need_to_be_rasterized); | 880 &tiles_that_need_to_be_rasterized); |
883 | 881 |
884 // Inform the client that will likely require a draw if the highest priority | 882 // Inform the client that will likely require a draw if the highest priority |
885 // tile that will be rasterized is required for draw. | 883 // tile that will be rasterized is required for draw. |
886 client_->SetIsLikelyToRequireADraw( | 884 client_->SetIsLikelyToRequireADraw( |
887 !tiles_that_need_to_be_rasterized.empty() && | 885 !tiles_that_need_to_be_rasterized.empty() && |
888 (*tiles_that_need_to_be_rasterized.begin())->required_for_draw()); | 886 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); |
889 | 887 |
890 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 888 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
891 // steady memory state. Keep scheduling tasks until we reach this state. | 889 // steady memory state. Keep scheduling tasks until we reach this state. |
892 if (!tiles_that_need_to_be_rasterized.empty()) { | 890 if (!tiles_that_need_to_be_rasterized.empty()) { |
893 ScheduleTasks(tiles_that_need_to_be_rasterized); | 891 ScheduleTasks(tiles_that_need_to_be_rasterized); |
894 return; | 892 return; |
895 } | 893 } |
896 | 894 |
897 FreeResourcesForReleasedTiles(); | 895 FreeResourcesForReleasedTiles(); |
898 | 896 |
(...skipping 20 matching lines...) Expand all Loading... | |
919 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); | 917 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); |
920 | 918 |
921 // If we have tiles left to raster for activation, and we don't allow | 919 // If we have tiles left to raster for activation, and we don't allow |
922 // activating without them, then skip activation and return early. | 920 // activating without them, then skip activation and return early. |
923 if (!required_for_activation_queue->IsEmpty() && wait_for_all_required_tiles) | 921 if (!required_for_activation_queue->IsEmpty() && wait_for_all_required_tiles) |
924 return; | 922 return; |
925 | 923 |
926 // Mark required tiles as OOM so that we can activate without them. | 924 // Mark required tiles as OOM so that we can activate without them. |
927 for (; !required_for_activation_queue->IsEmpty(); | 925 for (; !required_for_activation_queue->IsEmpty(); |
928 required_for_activation_queue->Pop()) { | 926 required_for_activation_queue->Pop()) { |
929 Tile* tile = required_for_activation_queue->Top(); | 927 Tile* tile = required_for_activation_queue->Top().tile(); |
930 tile->draw_info().set_oom(); | 928 tile->draw_info().set_oom(); |
931 client_->NotifyTileStateChanged(tile); | 929 client_->NotifyTileStateChanged(tile); |
932 } | 930 } |
933 | 931 |
934 DCHECK(IsReadyToActivate()); | 932 DCHECK(IsReadyToActivate()); |
935 ready_to_activate_check_notifier_.Schedule(); | 933 ready_to_activate_check_notifier_.Schedule(); |
936 } | 934 } |
937 | 935 |
938 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 936 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
939 } | 937 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
979 result -= other; | 977 result -= other; |
980 return result; | 978 return result; |
981 } | 979 } |
982 | 980 |
983 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 981 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
984 return memory_bytes_ > limit.memory_bytes_ || | 982 return memory_bytes_ > limit.memory_bytes_ || |
985 resource_count_ > limit.resource_count_; | 983 resource_count_ > limit.resource_count_; |
986 } | 984 } |
987 | 985 |
988 } // namespace cc | 986 } // namespace cc |
OLD | NEW |