| 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/tiles/tile_manager.h" | 5 #include "cc/tiles/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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "base/numerics/safe_conversions.h" | 15 #include "base/numerics/safe_conversions.h" |
| 16 #include "base/trace_event/trace_event_argument.h" | 16 #include "base/trace_event/trace_event_argument.h" |
| 17 #include "cc/base/histograms.h" | 17 #include "cc/base/histograms.h" |
| 18 #include "cc/debug/devtools_instrumentation.h" | 18 #include "cc/debug/devtools_instrumentation.h" |
| 19 #include "cc/debug/frame_viewer_instrumentation.h" | 19 #include "cc/debug/frame_viewer_instrumentation.h" |
| 20 #include "cc/debug/traced_value.h" | 20 #include "cc/debug/traced_value.h" |
| 21 #include "cc/layers/picture_layer_impl.h" | 21 #include "cc/layers/picture_layer_impl.h" |
| 22 #include "cc/raster/raster_buffer.h" | 22 #include "cc/raster/raster_buffer.h" |
| 23 #include "cc/raster/tile_task_runner.h" | 23 #include "cc/raster/tile_task_runner.h" |
| 24 #include "cc/tiles/tile.h" | 24 #include "cc/tiles/tile.h" |
| 25 #include "ui/gfx/geometry/rect_conversions.h" | 25 #include "ui/gfx/geometry/rect_conversions.h" |
| 26 | 26 |
| 27 #include "ui/gfx/transform.h" |
| 27 namespace cc { | 28 namespace cc { |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 // Flag to indicate whether we should try and detect that | 31 // Flag to indicate whether we should try and detect that |
| 31 // a tile is of solid color. | 32 // a tile is of solid color. |
| 32 const bool kUseColorEstimator = true; | 33 const bool kUseColorEstimator = true; |
| 33 | 34 |
| 34 DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER( | 35 DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER( |
| 35 ScopedRasterTaskTimer, | 36 ScopedRasterTaskTimer, |
| 36 "Compositing.%s.RasterTask.RasterUs", | 37 "Compositing.%s.RasterTask.RasterUs", |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 CleanUpReleasedTiles(); | 242 CleanUpReleasedTiles(); |
| 242 | 243 |
| 243 tile_task_runner_ = nullptr; | 244 tile_task_runner_ = nullptr; |
| 244 resource_pool_ = nullptr; | 245 resource_pool_ = nullptr; |
| 245 more_tiles_need_prepare_check_notifier_.Cancel(); | 246 more_tiles_need_prepare_check_notifier_.Cancel(); |
| 246 signals_check_notifier_.Cancel(); | 247 signals_check_notifier_.Cancel(); |
| 247 } | 248 } |
| 248 | 249 |
| 249 void TileManager::SetResources(ResourcePool* resource_pool, | 250 void TileManager::SetResources(ResourcePool* resource_pool, |
| 250 TileTaskRunner* tile_task_runner, | 251 TileTaskRunner* tile_task_runner, |
| 251 size_t scheduled_raster_task_limit) { | 252 size_t scheduled_raster_task_limit, |
| 253 bool is_using_gpu_rasterization) { |
| 252 DCHECK(!tile_task_runner_); | 254 DCHECK(!tile_task_runner_); |
| 253 DCHECK(tile_task_runner); | 255 DCHECK(tile_task_runner); |
| 254 | 256 |
| 255 scheduled_raster_task_limit_ = scheduled_raster_task_limit; | 257 scheduled_raster_task_limit_ = scheduled_raster_task_limit; |
| 256 resource_pool_ = resource_pool; | 258 resource_pool_ = resource_pool; |
| 257 tile_task_runner_ = tile_task_runner; | 259 tile_task_runner_ = tile_task_runner; |
| 258 tile_task_runner_->SetClient(this); | 260 tile_task_runner_->SetClient(this); |
| 261 image_decode_controller_.SetIsUsingGpuRasterization( |
| 262 is_using_gpu_rasterization); |
| 259 } | 263 } |
| 260 | 264 |
| 261 void TileManager::Release(Tile* tile) { | 265 void TileManager::Release(Tile* tile) { |
| 262 released_tiles_.push_back(tile); | 266 released_tiles_.push_back(tile); |
| 263 } | 267 } |
| 264 | 268 |
| 265 void TileManager::FreeResourcesForReleasedTiles() { | 269 void TileManager::FreeResourcesForReleasedTiles() { |
| 266 for (auto* tile : released_tiles_) | 270 for (auto* tile : released_tiles_) |
| 267 FreeResourcesForTile(tile); | 271 FreeResourcesForTile(tile); |
| 268 } | 272 } |
| 269 | 273 |
| 270 void TileManager::CleanUpReleasedTiles() { | 274 void TileManager::CleanUpReleasedTiles() { |
| 271 std::vector<Tile*> tiles_to_retain; | 275 std::vector<Tile*> tiles_to_retain; |
| 272 for (auto* tile : released_tiles_) { | 276 for (auto* tile : released_tiles_) { |
| 273 if (tile->HasRasterTask()) { | 277 if (tile->HasRasterTask()) { |
| 274 tiles_to_retain.push_back(tile); | 278 tiles_to_retain.push_back(tile); |
| 275 continue; | 279 continue; |
| 276 } | 280 } |
| 277 | 281 |
| 278 DCHECK(!tile->draw_info().has_resource()); | 282 DCHECK(!tile->draw_info().has_resource()); |
| 279 DCHECK(tiles_.find(tile->id()) != tiles_.end()); | 283 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 280 tiles_.erase(tile->id()); | 284 tiles_.erase(tile->id()); |
| 281 | 285 |
| 282 image_decode_controller_.SubtractLayerUsedCount(tile->layer_id()); | |
| 283 delete tile; | 286 delete tile; |
| 284 } | 287 } |
| 285 released_tiles_.swap(tiles_to_retain); | 288 released_tiles_.swap(tiles_to_retain); |
| 286 } | 289 } |
| 287 | 290 |
| 288 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { | 291 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { |
| 289 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", | 292 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", |
| 290 TaskSetName(task_set)); | 293 TaskSetName(task_set)); |
| 291 DCHECK(resource_pool_); | 294 DCHECK(resource_pool_); |
| 292 DCHECK(tile_task_runner_); | 295 DCHECK(tile_task_runner_); |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 has_scheduled_tile_tasks_ = true; | 623 has_scheduled_tile_tasks_ = true; |
| 621 | 624 |
| 622 // Build a new task queue containing all task currently needed. Tasks | 625 // Build a new task queue containing all task currently needed. Tasks |
| 623 // are added in order of priority, highest priority task first. | 626 // are added in order of priority, highest priority task first. |
| 624 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { | 627 for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) { |
| 625 Tile* tile = prioritized_tile.tile(); | 628 Tile* tile = prioritized_tile.tile(); |
| 626 | 629 |
| 627 DCHECK(tile->draw_info().requires_resource()); | 630 DCHECK(tile->draw_info().requires_resource()); |
| 628 DCHECK(!tile->draw_info().resource_); | 631 DCHECK(!tile->draw_info().resource_); |
| 629 | 632 |
| 630 if (!tile->raster_task_.get()) | 633 if (!tile->raster_task_) |
| 631 tile->raster_task_ = CreateRasterTask(prioritized_tile); | 634 tile->raster_task_ = CreateRasterTask(prioritized_tile); |
| 632 | 635 |
| 633 TaskSetCollection task_sets; | 636 TaskSetCollection task_sets; |
| 634 if (tile->required_for_activation()) | 637 if (tile->required_for_activation()) |
| 635 task_sets.set(REQUIRED_FOR_ACTIVATION); | 638 task_sets.set(REQUIRED_FOR_ACTIVATION); |
| 636 if (tile->required_for_draw()) | 639 if (tile->required_for_draw()) |
| 637 task_sets.set(REQUIRED_FOR_DRAW); | 640 task_sets.set(REQUIRED_FOR_DRAW); |
| 638 task_sets.set(ALL); | 641 task_sets.set(ALL); |
| 639 raster_queue_.items.push_back( | 642 raster_queue_.items.push_back( |
| 640 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); | 643 TileTaskQueue::Item(tile->raster_task_.get(), task_sets)); |
| 641 } | 644 } |
| 642 | 645 |
| 643 // We must reduce the amount of unused resoruces before calling | 646 // We must reduce the amount of unused resoruces before calling |
| 644 // ScheduleTasks to prevent usage from rising above limits. | 647 // ScheduleTasks to prevent usage from rising above limits. |
| 645 resource_pool_->ReduceResourceUsage(); | 648 resource_pool_->ReduceResourceUsage(); |
| 649 image_decode_controller_.ReduceCacheUsage(); |
| 646 | 650 |
| 647 // Schedule running of |raster_queue_|. This replaces any previously | 651 // Schedule running of |raster_queue_|. This replaces any previously |
| 648 // scheduled tasks and effectively cancels all tasks not present | 652 // scheduled tasks and effectively cancels all tasks not present |
| 649 // in |raster_queue_|. | 653 // in |raster_queue_|. |
| 650 tile_task_runner_->ScheduleTasks(&raster_queue_); | 654 tile_task_runner_->ScheduleTasks(&raster_queue_); |
| 651 | 655 |
| 652 // It's now safe to clean up orphan tasks as raster worker pool is not | 656 // It's now safe to clean up orphan tasks as raster worker pool is not |
| 653 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has | 657 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has |
| 654 // been called. | 658 // been called. |
| 655 orphan_raster_tasks_.clear(); | 659 orphan_raster_tasks_.clear(); |
| 656 | 660 |
| 657 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; | 661 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; |
| 658 } | 662 } |
| 659 | 663 |
| 660 scoped_refptr<RasterTask> TileManager::CreateRasterTask( | 664 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
| 661 const PrioritizedTile& prioritized_tile) { | 665 const PrioritizedTile& prioritized_tile) { |
| 662 Tile* tile = prioritized_tile.tile(); | 666 Tile* tile = prioritized_tile.tile(); |
| 667 |
| 668 // Get the resource. |
| 663 uint64_t resource_content_id = 0; | 669 uint64_t resource_content_id = 0; |
| 664 Resource* resource = nullptr; | 670 Resource* resource = nullptr; |
| 665 if (use_partial_raster_ && tile->invalidated_id()) { | 671 if (use_partial_raster_ && tile->invalidated_id()) { |
| 666 // TODO(danakj): For resources that are in use, we should still grab them | 672 // TODO(danakj): For resources that are in use, we should still grab them |
| 667 // and copy from them instead of rastering everything. crbug.com/492754 | 673 // and copy from them instead of rastering everything. crbug.com/492754 |
| 668 resource = | 674 resource = |
| 669 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); | 675 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); |
| 670 } | 676 } |
| 671 if (resource) { | 677 if (resource) { |
| 672 resource_content_id = tile->invalidated_id(); | 678 resource_content_id = tile->invalidated_id(); |
| 673 DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); | 679 DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); |
| 674 DCHECK_EQ(tile->desired_texture_size().ToString(), | 680 DCHECK_EQ(tile->desired_texture_size().ToString(), |
| 675 resource->size().ToString()); | 681 resource->size().ToString()); |
| 676 } else { | 682 } else { |
| 677 resource = resource_pool_->AcquireResource(tile->desired_texture_size(), | 683 resource = resource_pool_->AcquireResource(tile->desired_texture_size(), |
| 678 DetermineResourceFormat(tile)); | 684 DetermineResourceFormat(tile)); |
| 679 } | 685 } |
| 680 | 686 |
| 681 // Create and queue all image decode tasks that this tile depends on. | 687 // Create and queue all image decode tasks that this tile depends on. |
| 682 ImageDecodeTask::Vector decode_tasks; | 688 ImageDecodeTask::Vector decode_tasks; |
| 683 std::vector<DrawImage> images; | 689 std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; |
| 690 images.clear(); |
| 684 prioritized_tile.raster_source()->GetDiscardableImagesInRect( | 691 prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
| 685 tile->enclosing_layer_rect(), tile->contents_scale(), &images); | 692 tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
| 686 for (const auto& image : images) { | 693 for (auto it = images.begin(); it != images.end();) { |
| 687 decode_tasks.push_back(image_decode_controller_.GetTaskForImage( | 694 scoped_refptr<ImageDecodeTask> task; |
| 688 image, tile->layer_id(), prepare_tiles_count_)); | 695 bool need_to_unref_when_finished = |
| 696 image_decode_controller_.GetTaskForImageAndRef( |
| 697 *it, prepare_tiles_count_, &task); |
| 698 if (task) |
| 699 decode_tasks.push_back(task); |
| 700 |
| 701 if (need_to_unref_when_finished) |
| 702 ++it; |
| 703 else |
| 704 it = images.erase(it); |
| 689 } | 705 } |
| 690 | 706 |
| 691 return make_scoped_refptr(new RasterTaskImpl( | 707 return make_scoped_refptr(new RasterTaskImpl( |
| 692 resource, prioritized_tile.raster_source(), tile->content_rect(), | 708 resource, prioritized_tile.raster_source(), tile->content_rect(), |
| 693 tile->invalidated_content_rect(), tile->contents_scale(), | 709 tile->invalidated_content_rect(), tile->contents_scale(), |
| 694 prioritized_tile.priority().resolution, tile->layer_id(), | 710 prioritized_tile.priority().resolution, tile->layer_id(), |
| 695 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), | 711 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), |
| 696 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), | 712 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), |
| 697 tile->use_picture_analysis(), | 713 tile->use_picture_analysis(), |
| 698 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 714 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
| 699 tile->id(), resource), | 715 tile->id(), resource), |
| 700 &decode_tasks)); | 716 &decode_tasks)); |
| 701 } | 717 } |
| 702 | 718 |
| 703 void TileManager::OnRasterTaskCompleted( | 719 void TileManager::OnRasterTaskCompleted( |
| 704 Tile::Id tile_id, | 720 Tile::Id tile_id, |
| 705 Resource* resource, | 721 Resource* resource, |
| 706 const DisplayListRasterSource::SolidColorAnalysis& analysis, | 722 const DisplayListRasterSource::SolidColorAnalysis& analysis, |
| 707 bool was_canceled) { | 723 bool was_canceled) { |
| 708 DCHECK(tiles_.find(tile_id) != tiles_.end()); | 724 DCHECK(tiles_.find(tile_id) != tiles_.end()); |
| 709 | 725 |
| 710 Tile* tile = tiles_[tile_id]; | 726 Tile* tile = tiles_[tile_id]; |
| 711 DCHECK(tile->raster_task_.get()); | 727 DCHECK(tile->raster_task_.get()); |
| 712 orphan_raster_tasks_.push_back(tile->raster_task_); | 728 orphan_raster_tasks_.push_back(tile->raster_task_); |
| 713 tile->raster_task_ = nullptr; | 729 tile->raster_task_ = nullptr; |
| 714 | 730 |
| 731 // Unref all the images. |
| 732 auto images_it = scheduled_draw_images_.find(tile->id()); |
| 733 const std::vector<DrawImage>& images = images_it->second; |
| 734 for (const auto& image : images) |
| 735 image_decode_controller_.UnrefImage(image); |
| 736 scheduled_draw_images_.erase(images_it); |
| 737 |
| 715 if (was_canceled) { | 738 if (was_canceled) { |
| 716 ++flush_stats_.canceled_count; | 739 ++flush_stats_.canceled_count; |
| 717 // TODO(ericrk): If more partial raster work is done in the future, it may | 740 // TODO(ericrk): If more partial raster work is done in the future, it may |
| 718 // be worth returning the resource to the pool with its previous ID (not | 741 // be worth returning the resource to the pool with its previous ID (not |
| 719 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method | 742 // currently tracked). crrev.com/1370333002/#ps40001 has a possible method |
| 720 // of achieving this. | 743 // of achieving this. |
| 721 resource_pool_->ReleaseResource(resource, 0 /* content_id */); | 744 resource_pool_->ReleaseResource(resource, 0 /* content_id */); |
| 722 return; | 745 return; |
| 723 } | 746 } |
| 724 | 747 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 int source_frame_number, | 782 int source_frame_number, |
| 760 int flags) { | 783 int flags) { |
| 761 // We need to have a tile task worker pool to do anything meaningful with | 784 // We need to have a tile task worker pool to do anything meaningful with |
| 762 // tiles. | 785 // tiles. |
| 763 DCHECK(tile_task_runner_); | 786 DCHECK(tile_task_runner_); |
| 764 ScopedTilePtr tile( | 787 ScopedTilePtr tile( |
| 765 new Tile(this, info, layer_id, source_frame_number, flags)); | 788 new Tile(this, info, layer_id, source_frame_number, flags)); |
| 766 DCHECK(tiles_.find(tile->id()) == tiles_.end()); | 789 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 767 | 790 |
| 768 tiles_[tile->id()] = tile.get(); | 791 tiles_[tile->id()] = tile.get(); |
| 769 image_decode_controller_.AddLayerUsedCount(tile->layer_id()); | |
| 770 return tile; | 792 return tile; |
| 771 } | 793 } |
| 772 | 794 |
| 773 void TileManager::SetTileTaskRunnerForTesting( | 795 void TileManager::SetTileTaskRunnerForTesting( |
| 774 TileTaskRunner* tile_task_runner) { | 796 TileTaskRunner* tile_task_runner) { |
| 775 tile_task_runner_ = tile_task_runner; | 797 tile_task_runner_ = tile_task_runner; |
| 776 tile_task_runner_->SetClient(this); | 798 tile_task_runner_->SetClient(this); |
| 777 } | 799 } |
| 778 | 800 |
| 779 bool TileManager::AreRequiredTilesReadyToDraw( | 801 bool TileManager::AreRequiredTilesReadyToDraw( |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 void TileManager::Signals::reset() { | 1039 void TileManager::Signals::reset() { |
| 1018 ready_to_activate = false; | 1040 ready_to_activate = false; |
| 1019 did_notify_ready_to_activate = false; | 1041 did_notify_ready_to_activate = false; |
| 1020 ready_to_draw = false; | 1042 ready_to_draw = false; |
| 1021 did_notify_ready_to_draw = false; | 1043 did_notify_ready_to_draw = false; |
| 1022 all_tile_tasks_completed = false; | 1044 all_tile_tasks_completed = false; |
| 1023 did_notify_all_tile_tasks_completed = false; | 1045 did_notify_all_tile_tasks_completed = false; |
| 1024 } | 1046 } |
| 1025 | 1047 |
| 1026 } // namespace cc | 1048 } // namespace cc |
| OLD | NEW |