| 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 |