Chromium Code Reviews| 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 |