| 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)> | 128 const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)> |
| 129 reply_; | 129 reply_; |
| 130 scoped_ptr<RasterBuffer> raster_buffer_; | 130 scoped_ptr<RasterBuffer> raster_buffer_; |
| 131 | 131 |
| 132 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); | 132 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); |
| 133 }; | 133 }; |
| 134 | 134 |
| 135 class ImageDecodeTaskImpl : public ImageDecodeTask { | 135 class ImageDecodeTaskImpl : public ImageDecodeTask { |
| 136 public: | 136 public: |
| 137 ImageDecodeTaskImpl(SkPixelRef* pixel_ref, | 137 ImageDecodeTaskImpl(SkPixelRef* pixel_ref, |
| 138 int layer_id, | |
| 139 const base::Callback<void(bool was_canceled)>& reply) | 138 const base::Callback<void(bool was_canceled)>& reply) |
| 140 : pixel_ref_(skia::SharePtr(pixel_ref)), | 139 : pixel_ref_(skia::SharePtr(pixel_ref)), |
| 141 layer_id_(layer_id), | |
| 142 reply_(reply) {} | 140 reply_(reply) {} |
| 143 | 141 |
| 144 // Overridden from Task: | 142 // Overridden from Task: |
| 145 void RunOnWorkerThread() override { | 143 void RunOnWorkerThread() override { |
| 146 TRACE_EVENT0("cc", "ImageDecodeTaskImpl::RunOnWorkerThread"); | 144 TRACE_EVENT0("cc", "ImageDecodeTaskImpl::RunOnWorkerThread"); |
| 147 | 145 |
| 148 devtools_instrumentation::ScopedImageDecodeTask image_decode_task( | 146 devtools_instrumentation::ScopedImageDecodeTask image_decode_task( |
| 149 pixel_ref_.get()); | 147 pixel_ref_.get()); |
| 150 // This will cause the image referred to by pixel ref to be decoded. | 148 // This will cause the image referred to by pixel ref to be decoded. |
| 151 pixel_ref_->lockPixels(); | 149 pixel_ref_->lockPixels(); |
| 152 pixel_ref_->unlockPixels(); | 150 pixel_ref_->unlockPixels(); |
| 153 } | 151 } |
| 154 | 152 |
| 155 // Overridden from TileTask: | 153 // Overridden from TileTask: |
| 156 void ScheduleOnOriginThread(TileTaskClient* client) override {} | 154 void ScheduleOnOriginThread(TileTaskClient* client) override {} |
| 157 void CompleteOnOriginThread(TileTaskClient* client) override {} | 155 void CompleteOnOriginThread(TileTaskClient* client) override {} |
| 158 void RunReplyOnOriginThread() override { reply_.Run(!HasFinishedRunning()); } | 156 void RunReplyOnOriginThread() override { reply_.Run(!HasFinishedRunning()); } |
| 159 | 157 |
| 160 protected: | 158 protected: |
| 161 ~ImageDecodeTaskImpl() override {} | 159 ~ImageDecodeTaskImpl() override {} |
| 162 | 160 |
| 163 private: | 161 private: |
| 164 skia::RefPtr<SkPixelRef> pixel_ref_; | 162 skia::RefPtr<SkPixelRef> pixel_ref_; |
| 165 int layer_id_; | |
| 166 const base::Callback<void(bool was_canceled)> reply_; | 163 const base::Callback<void(bool was_canceled)> reply_; |
| 167 | 164 |
| 168 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 165 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); |
| 169 }; | 166 }; |
| 170 | 167 |
| 171 const char* TaskSetName(TaskSet task_set) { | 168 const char* TaskSetName(TaskSet task_set) { |
| 172 switch (task_set) { | 169 switch (task_set) { |
| 173 case TileManager::ALL: | 170 case TileManager::ALL: |
| 174 return "ALL"; | 171 return "ALL"; |
| 175 case TileManager::REQUIRED_FOR_ACTIVATION: | 172 case TileManager::REQUIRED_FOR_ACTIVATION: |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 353 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
| 357 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 354 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
| 358 tile_task_runner_->CheckForCompletedTasks(); | 355 tile_task_runner_->CheckForCompletedTasks(); |
| 359 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 356 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 360 } | 357 } |
| 361 | 358 |
| 362 FreeResourcesForReleasedTiles(); | 359 FreeResourcesForReleasedTiles(); |
| 363 CleanUpReleasedTiles(); | 360 CleanUpReleasedTiles(); |
| 364 | 361 |
| 365 TileVector tiles_that_need_to_be_rasterized; | 362 TileVector tiles_that_need_to_be_rasterized; |
| 366 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, | 363 RasterTilePriorityQueue raster_priority_queue; |
| 367 scheduled_raster_task_limit_, false); | 364 client_->BuildRasterQueue(&raster_priority_queue, |
| 365 global_state_.tree_priority, |
| 366 RasterTilePriorityQueue::Type::ALL); |
| 367 AssignGpuMemoryToTiles(&raster_priority_queue, scheduled_raster_task_limit_, |
| 368 &tiles_that_need_to_be_rasterized); |
| 368 | 369 |
| 369 // Schedule tile tasks. | 370 // Schedule tile tasks. |
| 370 ScheduleTasks(tiles_that_need_to_be_rasterized); | 371 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 371 | 372 |
| 372 did_notify_ready_to_activate_ = false; | 373 did_notify_ready_to_activate_ = false; |
| 373 did_notify_ready_to_draw_ = false; | 374 did_notify_ready_to_draw_ = false; |
| 374 } else { | 375 } else { |
| 375 if (global_state_.hard_memory_limit_in_bytes == 0) { | 376 if (global_state_.hard_memory_limit_in_bytes == 0) { |
| 376 TileVector tiles_that_need_to_be_rasterized; | 377 // TODO(vmpstr): Add a function to unconditionally create an eviction |
| 377 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, | 378 // queue and guard the rest of the calls sites with this flag, instead of |
| 378 scheduled_raster_task_limit_, false); | 379 // clearing here and building, which is a bit awkward. |
| 379 DCHECK(tiles_that_need_to_be_rasterized.empty()); | 380 eviction_priority_queue_is_up_to_date_ = false; |
| 381 resource_pool_->CheckBusyResources(false); |
| 382 MemoryUsage memory_limit(0, 0); |
| 383 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), |
| 384 resource_pool_->acquired_resource_count()); |
| 385 FreeTileResourcesUntilUsageIsWithinLimit(memory_limit, &memory_usage); |
| 380 } | 386 } |
| 381 | 387 |
| 382 did_notify_ready_to_activate_ = false; | 388 did_notify_ready_to_activate_ = false; |
| 383 did_notify_ready_to_draw_ = false; | 389 did_notify_ready_to_draw_ = false; |
| 384 ready_to_activate_notifier_.Schedule(); | 390 ready_to_activate_notifier_.Schedule(); |
| 385 ready_to_draw_notifier_.Schedule(); | 391 ready_to_draw_notifier_.Schedule(); |
| 386 } | 392 } |
| 387 | 393 |
| 388 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, | 394 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, |
| 389 "state", BasicStateAsValue()); | 395 "state", BasicStateAsValue()); |
| 390 | 396 |
| 391 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, | 397 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, |
| 392 resource_pool_->total_memory_usage_bytes() - | 398 resource_pool_->total_memory_usage_bytes() - |
| 393 resource_pool_->acquired_memory_usage_bytes()); | 399 resource_pool_->acquired_memory_usage_bytes()); |
| 394 } | 400 } |
| 395 | 401 |
| 396 void TileManager::SynchronouslyRasterizeTiles( | 402 void TileManager::SynchronouslyRasterizeTiles( |
| 397 const GlobalStateThatImpactsTilePriority& state) { | 403 const GlobalStateThatImpactsTilePriority& state) { |
| 398 TRACE_EVENT0("cc", "TileManager::SynchronouslyRasterizeTiles"); | 404 TRACE_EVENT0("cc", "TileManager::SynchronouslyRasterizeTiles"); |
| 399 | 405 |
| 400 DCHECK(rasterizer_->GetPrepareTilesMode() != | 406 DCHECK(rasterizer_->GetPrepareTilesMode() != |
| 401 PrepareTilesMode::RASTERIZE_PRIORITIZED_TILES); | 407 PrepareTilesMode::RASTERIZE_PRIORITIZED_TILES); |
| 402 | 408 |
| 403 global_state_ = state; | 409 global_state_ = state; |
| 404 | 410 |
| 405 FreeResourcesForReleasedTiles(); | 411 FreeResourcesForReleasedTiles(); |
| 406 CleanUpReleasedTiles(); | 412 CleanUpReleasedTiles(); |
| 407 | 413 |
| 414 RasterTilePriorityQueue required_for_draw_queue; |
| 415 client_->BuildRasterQueue(&required_for_draw_queue, |
| 416 global_state_.tree_priority, |
| 417 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); |
| 408 TileVector tiles_that_need_to_be_rasterized; | 418 TileVector tiles_that_need_to_be_rasterized; |
| 409 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, | 419 AssignGpuMemoryToTiles(&required_for_draw_queue, |
| 410 std::numeric_limits<size_t>::max(), true); | 420 std::numeric_limits<size_t>::max(), |
| 421 &tiles_that_need_to_be_rasterized); |
| 411 | 422 |
| 412 // We must reduce the amount of unused resources before calling | 423 // We must reduce the amount of unused resources before calling |
| 413 // RunTasks to prevent usage from rising above limits. | 424 // RunTasks to prevent usage from rising above limits. |
| 414 resource_pool_->ReduceResourceUsage(); | 425 resource_pool_->ReduceResourceUsage(); |
| 415 | 426 |
| 416 // Run and complete all raster task synchronously. | 427 // Run and complete all raster task synchronously. |
| 417 rasterizer_->RasterizeTiles( | 428 rasterizer_->RasterizeTiles( |
| 418 tiles_that_need_to_be_rasterized, resource_pool_, | 429 tiles_that_need_to_be_rasterized, resource_pool_, |
| 419 base::Bind(&TileManager::UpdateTileDrawInfo, base::Unretained(this))); | 430 base::Bind(&TileManager::UpdateTileDrawInfo, base::Unretained(this))); |
| 420 | 431 |
| 432 // Use on-demand raster for any required-for-draw tiles that have not been |
| 433 // assigned memory after reaching a steady memory state. |
| 434 // TODO(hendrikw): Figure out why this would improve jank on some tests - See |
| 435 // crbug.com/449288 |
| 436 required_for_draw_queue.Reset(); |
| 437 client_->BuildRasterQueue(&required_for_draw_queue, |
| 438 global_state_.tree_priority, |
| 439 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); |
| 440 |
| 441 // Use on-demand raster for any tiles that have not been been assigned |
| 442 // memory. This ensures that we draw even when OOM. |
| 443 for (; !required_for_draw_queue.IsEmpty(); required_for_draw_queue.Pop()) { |
| 444 Tile* tile = required_for_draw_queue.Top(); |
| 445 tile->draw_info().set_rasterize_on_demand(); |
| 446 client_->NotifyTileStateChanged(tile); |
| 447 } |
| 448 |
| 421 TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state", | 449 TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state", |
| 422 BasicStateAsValue()); | 450 BasicStateAsValue()); |
| 423 | 451 |
| 424 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, | 452 TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this, |
| 425 resource_pool_->total_memory_usage_bytes() - | 453 resource_pool_->total_memory_usage_bytes() - |
| 426 resource_pool_->acquired_memory_usage_bytes()); | 454 resource_pool_->acquired_memory_usage_bytes()); |
| 427 } | 455 } |
| 428 | 456 |
| 429 void TileManager::UpdateVisibleTiles( | 457 void TileManager::UpdateVisibleTiles( |
| 430 const GlobalStateThatImpactsTilePriority& state) { | 458 const GlobalStateThatImpactsTilePriority& state) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 return priority.priority_bin > TilePriority::SOON; | 553 return priority.priority_bin > TilePriority::SOON; |
| 526 case ALLOW_ANYTHING: | 554 case ALLOW_ANYTHING: |
| 527 return priority.distance_to_visible == | 555 return priority.distance_to_visible == |
| 528 std::numeric_limits<float>::infinity(); | 556 std::numeric_limits<float>::infinity(); |
| 529 } | 557 } |
| 530 NOTREACHED(); | 558 NOTREACHED(); |
| 531 return true; | 559 return true; |
| 532 } | 560 } |
| 533 | 561 |
| 534 void TileManager::AssignGpuMemoryToTiles( | 562 void TileManager::AssignGpuMemoryToTiles( |
| 535 TileVector* tiles_that_need_to_be_rasterized, | 563 RasterTilePriorityQueue* raster_priority_queue, |
| 536 size_t scheduled_raster_task_limit, | 564 size_t scheduled_raster_task_limit, |
| 537 bool required_for_draw_only) { | 565 TileVector* tiles_that_need_to_be_rasterized) { |
| 538 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); | 566 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 539 | 567 |
| 540 // Maintain the list of released resources that can potentially be re-used | 568 // Maintain the list of released resources that can potentially be re-used |
| 541 // or deleted. | 569 // or deleted. If this operation becomes expensive too, only do this after |
| 542 // If this operation becomes expensive too, only do this after some | 570 // some resource(s) was returned. Note that in that case, one also need to |
| 543 // resource(s) was returned. Note that in that case, one also need to | |
| 544 // invalidate when releasing some resource from the pool. | 571 // invalidate when releasing some resource from the pool. |
| 545 resource_pool_->CheckBusyResources(false); | 572 resource_pool_->CheckBusyResources(false); |
| 546 | 573 |
| 547 // Now give memory out to the tiles until we're out, and build | 574 // Now give memory out to the tiles until we're out, and build |
| 548 // the needs-to-be-rasterized queue. | 575 // the needs-to-be-rasterized queue. |
| 549 unsigned schedule_priority = 1u; | 576 unsigned schedule_priority = 1u; |
| 550 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 577 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
| 551 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 578 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
| 552 | 579 |
| 553 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 580 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, |
| 554 global_state_.num_resources_limit); | 581 global_state_.num_resources_limit); |
| 555 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 582 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, |
| 556 global_state_.num_resources_limit); | 583 global_state_.num_resources_limit); |
| 557 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), | 584 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), |
| 558 resource_pool_->acquired_resource_count()); | 585 resource_pool_->acquired_resource_count()); |
| 559 | 586 |
| 560 eviction_priority_queue_is_up_to_date_ = false; | 587 eviction_priority_queue_is_up_to_date_ = false; |
| 561 // TODO(vmpstr): Take this as a parameter and have SynchronousRaster build a | 588 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
| 562 // REQUIRED_FOR_DRAW queue. | 589 Tile* tile = raster_priority_queue->Top(); |
| 563 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 564 global_state_.tree_priority, | |
| 565 RasterTilePriorityQueue::Type::ALL); | |
| 566 | |
| 567 while (!raster_priority_queue_.IsEmpty()) { | |
| 568 Tile* tile = raster_priority_queue_.Top(); | |
| 569 | |
| 570 // TODO(vmpstr): Remove this when the iterator returns the correct tiles | |
| 571 // to draw for GPU rasterization. | |
| 572 if (required_for_draw_only) { | |
| 573 if (!tile->required_for_draw()) { | |
| 574 raster_priority_queue_.Pop(); | |
| 575 continue; | |
| 576 } | |
| 577 } | |
| 578 TilePriority priority = tile->combined_priority(); | 590 TilePriority priority = tile->combined_priority(); |
| 579 | 591 |
| 580 if (TilePriorityViolatesMemoryPolicy(priority)) { | 592 if (TilePriorityViolatesMemoryPolicy(priority)) { |
| 581 TRACE_EVENT_INSTANT0( | 593 TRACE_EVENT_INSTANT0( |
| 582 "cc", "TileManager::AssignGpuMemory tile violates memory policy", | 594 "cc", "TileManager::AssignGpuMemory tile violates memory policy", |
| 583 TRACE_EVENT_SCOPE_THREAD); | 595 TRACE_EVENT_SCOPE_THREAD); |
| 584 break; | 596 break; |
| 585 } | 597 } |
| 586 | 598 |
| 587 // We won't be able to schedule this tile, so break out early. | 599 // We won't be able to schedule this tile, so break out early. |
| 588 if (tiles_that_need_to_be_rasterized->size() >= | 600 if (tiles_that_need_to_be_rasterized->size() >= |
| 589 scheduled_raster_task_limit) { | 601 scheduled_raster_task_limit) { |
| 590 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 602 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
| 591 break; | 603 break; |
| 592 } | 604 } |
| 593 | 605 |
| 594 TileDrawInfo& draw_info = tile->draw_info(); | 606 TileDrawInfo& draw_info = tile->draw_info(); |
| 595 tile->scheduled_priority_ = schedule_priority++; | 607 tile->scheduled_priority_ = schedule_priority++; |
| 596 | 608 |
| 597 DCHECK(draw_info.mode() == TileDrawInfo::PICTURE_PILE_MODE || | 609 DCHECK(draw_info.mode() == TileDrawInfo::PICTURE_PILE_MODE || |
| 598 !draw_info.IsReadyToDraw()); | 610 !draw_info.IsReadyToDraw()); |
| 599 | 611 |
| 600 // If the tile already has a raster_task, then the memory used by it is | 612 // If the tile already has a raster_task, then the memory used by it is |
| 601 // already accounted for in memory_usage. Otherwise, we'll have to acquire | 613 // already accounted for in memory_usage. Otherwise, we'll have to acquire |
| 602 // more memory to create a raster task. | 614 // more memory to create a raster task. |
| 603 MemoryUsage memory_required_by_tile_to_be_scheduled; | 615 MemoryUsage memory_required_by_tile_to_be_scheduled; |
| 604 if (!tile->raster_task_.get()) { | 616 if (!tile->raster_task_.get()) { |
| 605 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig( | 617 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig( |
| 606 tile->desired_texture_size(), resource_pool_->resource_format()); | 618 tile->desired_texture_size(), resource_pool_->default_format()); |
| 607 } | 619 } |
| 608 | 620 |
| 609 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW; | 621 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW; |
| 610 | 622 |
| 611 // This is the memory limit that will be used by this tile. Depending on | 623 // This is the memory limit that will be used by this tile. Depending on |
| 612 // the tile priority, it will be one of hard_memory_limit or | 624 // the tile priority, it will be one of hard_memory_limit or |
| 613 // soft_memory_limit. | 625 // soft_memory_limit. |
| 614 MemoryUsage& tile_memory_limit = | 626 MemoryUsage& tile_memory_limit = |
| 615 tile_is_needed_now ? hard_memory_limit : soft_memory_limit; | 627 tile_is_needed_now ? hard_memory_limit : soft_memory_limit; |
| 616 | 628 |
| 617 bool memory_usage_is_within_limit = | 629 bool memory_usage_is_within_limit = |
| 618 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( | 630 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( |
| 619 tile_memory_limit - memory_required_by_tile_to_be_scheduled, | 631 tile_memory_limit - memory_required_by_tile_to_be_scheduled, |
| 620 priority, &memory_usage); | 632 priority, &memory_usage); |
| 621 | 633 |
| 622 // If we couldn't fit the tile into our current memory limit, then we're | 634 // If we couldn't fit the tile into our current memory limit, then we're |
| 623 // done. | 635 // done. |
| 624 if (!memory_usage_is_within_limit) { | 636 if (!memory_usage_is_within_limit) { |
| 625 if (tile_is_needed_now) | 637 if (tile_is_needed_now) |
| 626 had_enough_memory_to_schedule_tiles_needed_now = false; | 638 had_enough_memory_to_schedule_tiles_needed_now = false; |
| 627 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 639 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
| 628 break; | 640 break; |
| 629 } | 641 } |
| 630 | 642 |
| 631 memory_usage += memory_required_by_tile_to_be_scheduled; | 643 memory_usage += memory_required_by_tile_to_be_scheduled; |
| 632 tiles_that_need_to_be_rasterized->push_back(tile); | 644 tiles_that_need_to_be_rasterized->push_back(tile); |
| 633 raster_priority_queue_.Pop(); | |
| 634 } | 645 } |
| 635 | 646 |
| 636 // Note that we should try and further reduce memory in case the above loop | 647 // Note that we should try and further reduce memory in case the above loop |
| 637 // didn't reduce memory. This ensures that we always release as many resources | 648 // didn't reduce memory. This ensures that we always release as many resources |
| 638 // as possible to stay within the memory limit. | 649 // as possible to stay within the memory limit. |
| 639 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage); | 650 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage); |
| 640 | 651 |
| 641 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", | 652 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", |
| 642 !had_enough_memory_to_schedule_tiles_needed_now); | 653 !had_enough_memory_to_schedule_tiles_needed_now); |
| 643 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; | 654 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; |
| 644 | 655 |
| 645 memory_stats_from_last_assign_.total_budget_in_bytes = | 656 memory_stats_from_last_assign_.total_budget_in_bytes = |
| 646 global_state_.hard_memory_limit_in_bytes; | 657 global_state_.hard_memory_limit_in_bytes; |
| 647 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); | 658 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); |
| 648 memory_stats_from_last_assign_.had_enough_memory = | 659 memory_stats_from_last_assign_.had_enough_memory = |
| 649 had_enough_memory_to_schedule_tiles_needed_now; | 660 had_enough_memory_to_schedule_tiles_needed_now; |
| 650 | 661 |
| 651 raster_priority_queue_.Reset(); | |
| 652 | |
| 653 TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles", | 662 TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles", |
| 654 "all_tiles_that_need_to_be_rasterized_are_scheduled", | 663 "all_tiles_that_need_to_be_rasterized_are_scheduled", |
| 655 all_tiles_that_need_to_be_rasterized_are_scheduled_, | 664 all_tiles_that_need_to_be_rasterized_are_scheduled_, |
| 656 "had_enough_memory_to_schedule_tiles_needed_now", | 665 "had_enough_memory_to_schedule_tiles_needed_now", |
| 657 had_enough_memory_to_schedule_tiles_needed_now); | 666 had_enough_memory_to_schedule_tiles_needed_now); |
| 658 } | 667 } |
| 659 | 668 |
| 660 void TileManager::FreeResourcesForTile(Tile* tile) { | 669 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 661 TileDrawInfo& draw_info = tile->draw_info(); | 670 TileDrawInfo& draw_info = tile->draw_info(); |
| 662 if (draw_info.resource_) | 671 if (draw_info.resource_) |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 orphan_raster_tasks_.clear(); | 730 orphan_raster_tasks_.clear(); |
| 722 | 731 |
| 723 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; | 732 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; |
| 724 } | 733 } |
| 725 | 734 |
| 726 scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask( | 735 scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask( |
| 727 Tile* tile, | 736 Tile* tile, |
| 728 SkPixelRef* pixel_ref) { | 737 SkPixelRef* pixel_ref) { |
| 729 return make_scoped_refptr(new ImageDecodeTaskImpl( | 738 return make_scoped_refptr(new ImageDecodeTaskImpl( |
| 730 pixel_ref, | 739 pixel_ref, |
| 731 tile->layer_id(), | |
| 732 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 740 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
| 733 base::Unretained(this), | 741 base::Unretained(this), |
| 734 tile->layer_id(), | 742 tile->layer_id(), |
| 735 base::Unretained(pixel_ref)))); | 743 base::Unretained(pixel_ref)))); |
| 736 } | 744 } |
| 737 | 745 |
| 738 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { | 746 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) { |
| 739 scoped_ptr<ScopedResource> resource = | 747 scoped_ptr<ScopedResource> resource = |
| 740 resource_pool_->AcquireResource(tile->desired_texture_size()); | 748 resource_pool_->AcquireResource(tile->desired_texture_size(), |
| 749 resource_pool_->default_format()); |
| 741 const ScopedResource* const_resource = resource.get(); | 750 const ScopedResource* const_resource = resource.get(); |
| 742 | 751 |
| 743 // Create and queue all image decode tasks that this tile depends on. | 752 // Create and queue all image decode tasks that this tile depends on. |
| 744 ImageDecodeTask::Vector decode_tasks; | 753 ImageDecodeTask::Vector decode_tasks; |
| 745 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; | 754 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; |
| 746 std::vector<SkPixelRef*> pixel_refs; | 755 std::vector<SkPixelRef*> pixel_refs; |
| 747 tile->raster_source()->GatherPixelRefs( | 756 tile->raster_source()->GatherPixelRefs( |
| 748 tile->content_rect(), tile->contents_scale(), &pixel_refs); | 757 tile->content_rect(), tile->contents_scale(), &pixel_refs); |
| 749 for (SkPixelRef* pixel_ref : pixel_refs) { | 758 for (SkPixelRef* pixel_ref : pixel_refs) { |
| 750 uint32_t id = pixel_ref->getGenerationID(); | 759 uint32_t id = pixel_ref->getGenerationID(); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 TileTaskRunner* tile_task_runner) { | 864 TileTaskRunner* tile_task_runner) { |
| 856 tile_task_runner_ = tile_task_runner; | 865 tile_task_runner_ = tile_task_runner; |
| 857 tile_task_runner_->SetClient(this); | 866 tile_task_runner_->SetClient(this); |
| 858 } | 867 } |
| 859 | 868 |
| 860 bool TileManager::IsReadyToActivate() const { | 869 bool TileManager::IsReadyToActivate() const { |
| 861 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); | 870 TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); |
| 862 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); | 871 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
| 863 | 872 |
| 864 // TODO(vmpstr): Replace this with building a REQUIRED_TO_ACTIVATE raster | 873 // TODO(vmpstr): Replace this with building a REQUIRED_TO_ACTIVATE raster |
| 865 // queue and checking if it's empty. | 874 // queue and checking if the tiles it contains are all ready to draw. |
| 866 for (const auto& layer : layers) { | 875 for (const auto& layer : layers) { |
| 867 if (!layer->AllTilesRequiredForActivationAreReadyToDraw()) | 876 if (!layer->AllTilesRequiredForActivationAreReadyToDraw()) |
| 868 return false; | 877 return false; |
| 869 } | 878 } |
| 870 | 879 |
| 871 return true; | 880 return true; |
| 872 } | 881 } |
| 873 | 882 |
| 874 bool TileManager::IsReadyToDraw() const { | 883 bool TileManager::IsReadyToDraw() const { |
| 875 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); | 884 const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers(); |
| 876 | 885 |
| 877 // TODO(vmpstr): Replace this with building a REQUIRED_TO_DRAW raster queue | 886 // TODO(vmpstr): Replace this with building a REQUIRED_TO_DRAW raster queue |
| 878 // and checking if it's empty. | 887 // and checking if the tiles it contains are all ready to draw. |
| 879 for (const auto& layer : layers) { | 888 for (const auto& layer : layers) { |
| 880 if (!layer->AllTilesRequiredForDrawAreReadyToDraw()) | 889 if (!layer->AllTilesRequiredForDrawAreReadyToDraw()) |
| 881 return false; | 890 return false; |
| 882 } | 891 } |
| 883 | 892 |
| 884 return true; | 893 return true; |
| 885 } | 894 } |
| 886 | 895 |
| 887 void TileManager::NotifyReadyToActivate() { | 896 void TileManager::NotifyReadyToActivate() { |
| 888 TRACE_EVENT0("cc", "TileManager::NotifyReadyToActivate"); | 897 TRACE_EVENT0("cc", "TileManager::NotifyReadyToActivate"); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 NotifyReadyToDraw(); | 937 NotifyReadyToDraw(); |
| 929 } | 938 } |
| 930 | 939 |
| 931 void TileManager::CheckIfMoreTilesNeedToBePrepared() { | 940 void TileManager::CheckIfMoreTilesNeedToBePrepared() { |
| 932 tile_task_runner_->CheckForCompletedTasks(); | 941 tile_task_runner_->CheckForCompletedTasks(); |
| 933 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 942 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 934 | 943 |
| 935 // When OOM, keep re-assigning memory until we reach a steady state | 944 // When OOM, keep re-assigning memory until we reach a steady state |
| 936 // where top-priority tiles are initialized. | 945 // where top-priority tiles are initialized. |
| 937 TileVector tiles_that_need_to_be_rasterized; | 946 TileVector tiles_that_need_to_be_rasterized; |
| 938 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized, | 947 RasterTilePriorityQueue raster_priority_queue; |
| 939 scheduled_raster_task_limit_, false); | 948 client_->BuildRasterQueue(&raster_priority_queue, global_state_.tree_priority, |
| 949 RasterTilePriorityQueue::Type::ALL); |
| 950 AssignGpuMemoryToTiles(&raster_priority_queue, scheduled_raster_task_limit_, |
| 951 &tiles_that_need_to_be_rasterized); |
| 940 | 952 |
| 941 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 953 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 942 // steady memory state. Keep scheduling tasks until we reach this state. | 954 // steady memory state. Keep scheduling tasks until we reach this state. |
| 943 if (!tiles_that_need_to_be_rasterized.empty()) { | 955 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 944 ScheduleTasks(tiles_that_need_to_be_rasterized); | 956 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 945 return; | 957 return; |
| 946 } | 958 } |
| 947 | 959 |
| 948 FreeResourcesForReleasedTiles(); | 960 FreeResourcesForReleasedTiles(); |
| 949 | 961 |
| 950 resource_pool_->ReduceResourceUsage(); | 962 resource_pool_->ReduceResourceUsage(); |
| 951 | 963 |
| 952 // We don't reserve memory for required-for-activation tiles during | 964 // We don't reserve memory for required-for-activation tiles during |
| 953 // accelerated gestures, so we just postpone activation when we don't | 965 // accelerated gestures, so we just postpone activation when we don't |
| 954 // have these tiles, and activate after the accelerated gesture. | 966 // have these tiles, and activate after the accelerated gesture. |
| 955 // Likewise if we don't allow any tiles (as is the case when we're | 967 // Likewise if we don't allow any tiles (as is the case when we're |
| 956 // invisible), if we have tiles that aren't ready, then we shouldn't | 968 // invisible), if we have tiles that aren't ready, then we shouldn't |
| 957 // activate as activation can cause checkerboards. | 969 // activate as activation can cause checkerboards. |
| 958 bool allow_rasterize_on_demand = | 970 bool allow_rasterize_on_demand = |
| 959 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | 971 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && |
| 960 global_state_.memory_limit_policy != ALLOW_NOTHING; | 972 global_state_.memory_limit_policy != ALLOW_NOTHING; |
| 961 | 973 |
| 962 // Use on-demand raster for any required-for-activation tiles that have | 974 // Use on-demand raster for any required-for-activation tiles that have |
| 963 // not been been assigned memory after reaching a steady memory state. This | 975 // not been been assigned memory after reaching a steady memory state. This |
| 964 // ensures that we activate even when OOM. Note that we have to rebuilt the | 976 // ensures that we activate even when OOM. Note that we can't reuse the queue |
| 965 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | 977 // we used for AssignGpuMemoryToTiles, since the AssignGpuMemoryToTiles call |
| 966 // would otherwise not be picked up by the old raster queue. | 978 // could have evicted some tiles that would not be picked up by the old raster |
| 967 // TODO(vmpstr): Make this use REQUIRED_FOR_ACTIVAITON queue. | 979 // queue. |
| 968 client_->BuildRasterQueue(&raster_priority_queue_, | 980 RasterTilePriorityQueue required_for_activation_queue; |
| 969 global_state_.tree_priority, | 981 client_->BuildRasterQueue( |
| 970 RasterTilePriorityQueue::Type::ALL); | 982 &required_for_activation_queue, global_state_.tree_priority, |
| 971 bool ready_to_activate = true; | 983 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); |
| 972 while (!raster_priority_queue_.IsEmpty()) { | |
| 973 Tile* tile = raster_priority_queue_.Top(); | |
| 974 TileDrawInfo& draw_info = tile->draw_info(); | |
| 975 | 984 |
| 976 if (tile->required_for_activation() && !draw_info.IsReadyToDraw()) { | 985 // If we have tiles to mark as rasterize on demand, but we don't allow |
| 977 // If we can't raster on demand, give up early (and don't activate). | 986 // rasterize on demand, then skip activation and return early. |
| 978 if (!allow_rasterize_on_demand) { | 987 if (!required_for_activation_queue.IsEmpty() && !allow_rasterize_on_demand) |
| 979 ready_to_activate = false; | 988 return; |
| 980 break; | |
| 981 } | |
| 982 | 989 |
| 983 draw_info.set_rasterize_on_demand(); | 990 // Mark required tiles as rasterize on demand. |
| 984 client_->NotifyTileStateChanged(tile); | 991 for (; !required_for_activation_queue.IsEmpty(); |
| 985 } | 992 required_for_activation_queue.Pop()) { |
| 986 raster_priority_queue_.Pop(); | 993 Tile* tile = required_for_activation_queue.Top(); |
| 994 tile->draw_info().set_rasterize_on_demand(); |
| 995 client_->NotifyTileStateChanged(tile); |
| 987 } | 996 } |
| 988 | 997 |
| 989 if (ready_to_activate) { | 998 DCHECK(IsReadyToActivate()); |
| 990 DCHECK(IsReadyToActivate()); | 999 ready_to_activate_check_notifier_.Schedule(); |
| 991 ready_to_activate_check_notifier_.Schedule(); | |
| 992 } | |
| 993 raster_priority_queue_.Reset(); | |
| 994 } | 1000 } |
| 995 | 1001 |
| 996 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 1002 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
| 997 } | 1003 } |
| 998 | 1004 |
| 999 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 1005 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) |
| 1000 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | 1006 : memory_bytes_(memory_bytes), resource_count_(resource_count) { |
| 1001 } | 1007 } |
| 1002 | 1008 |
| 1003 // static | 1009 // static |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 result -= other; | 1043 result -= other; |
| 1038 return result; | 1044 return result; |
| 1039 } | 1045 } |
| 1040 | 1046 |
| 1041 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 1047 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
| 1042 return memory_bytes_ > limit.memory_bytes_ || | 1048 return memory_bytes_ > limit.memory_bytes_ || |
| 1043 resource_count_ > limit.resource_count_; | 1049 resource_count_ > limit.resource_count_; |
| 1044 } | 1050 } |
| 1045 | 1051 |
| 1046 } // namespace cc | 1052 } // namespace cc |
| OLD | NEW |