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 |