| 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 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 uint64_t resource_content_id_; | 146 uint64_t resource_content_id_; |
| 147 int source_frame_number_; | 147 int source_frame_number_; |
| 148 bool analyze_picture_; | 148 bool analyze_picture_; |
| 149 const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)> | 149 const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)> |
| 150 reply_; | 150 reply_; |
| 151 scoped_ptr<RasterBuffer> raster_buffer_; | 151 scoped_ptr<RasterBuffer> raster_buffer_; |
| 152 | 152 |
| 153 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); | 153 DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); |
| 154 }; | 154 }; |
| 155 | 155 |
| 156 class ImageDecodeTaskImpl : public ImageDecodeTask { | |
| 157 public: | |
| 158 ImageDecodeTaskImpl(SkPixelRef* pixel_ref, | |
| 159 uint64_t source_prepare_tiles_id, | |
| 160 const base::Callback<void(bool was_canceled)>& reply) | |
| 161 : pixel_ref_(skia::SharePtr(pixel_ref)), | |
| 162 source_prepare_tiles_id_(source_prepare_tiles_id), | |
| 163 reply_(reply) {} | |
| 164 | |
| 165 // Overridden from Task: | |
| 166 void RunOnWorkerThread() override { | |
| 167 TRACE_EVENT1("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", | |
| 168 "source_prepare_tiles_id", source_prepare_tiles_id_); | |
| 169 | |
| 170 devtools_instrumentation::ScopedImageDecodeTask image_decode_task( | |
| 171 pixel_ref_.get()); | |
| 172 // This will cause the image referred to by pixel ref to be decoded. | |
| 173 pixel_ref_->lockPixels(); | |
| 174 pixel_ref_->unlockPixels(); | |
| 175 | |
| 176 // Release the reference after decoding image to ensure that it is not | |
| 177 // kept alive unless needed. | |
| 178 pixel_ref_.clear(); | |
| 179 } | |
| 180 | |
| 181 // Overridden from TileTask: | |
| 182 void ScheduleOnOriginThread(TileTaskClient* client) override {} | |
| 183 void CompleteOnOriginThread(TileTaskClient* client) override {} | |
| 184 void RunReplyOnOriginThread() override { reply_.Run(!HasFinishedRunning()); } | |
| 185 | |
| 186 protected: | |
| 187 ~ImageDecodeTaskImpl() override {} | |
| 188 | |
| 189 private: | |
| 190 skia::RefPtr<SkPixelRef> pixel_ref_; | |
| 191 uint64_t source_prepare_tiles_id_; | |
| 192 const base::Callback<void(bool was_canceled)> reply_; | |
| 193 | |
| 194 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | |
| 195 }; | |
| 196 | |
| 197 const char* TaskSetName(TaskSet task_set) { | 156 const char* TaskSetName(TaskSet task_set) { |
| 198 switch (task_set) { | 157 switch (task_set) { |
| 199 case TileManager::ALL: | 158 case TileManager::ALL: |
| 200 return "ALL"; | 159 return "ALL"; |
| 201 case TileManager::REQUIRED_FOR_ACTIVATION: | 160 case TileManager::REQUIRED_FOR_ACTIVATION: |
| 202 return "REQUIRED_FOR_ACTIVATION"; | 161 return "REQUIRED_FOR_ACTIVATION"; |
| 203 case TileManager::REQUIRED_FOR_DRAW: | 162 case TileManager::REQUIRED_FOR_DRAW: |
| 204 return "REQUIRED_FOR_DRAW"; | 163 return "REQUIRED_FOR_DRAW"; |
| 205 } | 164 } |
| 206 | 165 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 for (auto* tile : released_tiles_) { | 276 for (auto* tile : released_tiles_) { |
| 318 if (tile->HasRasterTask()) { | 277 if (tile->HasRasterTask()) { |
| 319 tiles_to_retain.push_back(tile); | 278 tiles_to_retain.push_back(tile); |
| 320 continue; | 279 continue; |
| 321 } | 280 } |
| 322 | 281 |
| 323 DCHECK(!tile->draw_info().has_resource()); | 282 DCHECK(!tile->draw_info().has_resource()); |
| 324 DCHECK(tiles_.find(tile->id()) != tiles_.end()); | 283 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 325 tiles_.erase(tile->id()); | 284 tiles_.erase(tile->id()); |
| 326 | 285 |
| 327 LayerCountMap::iterator layer_it = | 286 image_decode_controller_.SubtractLayerUsedCount(tile->layer_id()); |
| 328 used_layer_counts_.find(tile->layer_id()); | |
| 329 DCHECK_GT(layer_it->second, 0); | |
| 330 if (--layer_it->second == 0) { | |
| 331 used_layer_counts_.erase(layer_it); | |
| 332 image_decode_tasks_.erase(tile->layer_id()); | |
| 333 } | |
| 334 | |
| 335 delete tile; | 287 delete tile; |
| 336 } | 288 } |
| 337 released_tiles_.swap(tiles_to_retain); | 289 released_tiles_.swap(tiles_to_retain); |
| 338 } | 290 } |
| 339 | 291 |
| 340 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { | 292 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { |
| 341 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", | 293 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", |
| 342 TaskSetName(task_set)); | 294 TaskSetName(task_set)); |
| 343 DCHECK(resource_pool_); | 295 DCHECK(resource_pool_); |
| 344 DCHECK(tile_task_runner_); | 296 DCHECK(tile_task_runner_); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 tile_task_runner_->ScheduleTasks(&raster_queue_); | 657 tile_task_runner_->ScheduleTasks(&raster_queue_); |
| 706 | 658 |
| 707 // It's now safe to clean up orphan tasks as raster worker pool is not | 659 // It's now safe to clean up orphan tasks as raster worker pool is not |
| 708 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has | 660 // allowed to keep around unreferenced raster tasks after ScheduleTasks() has |
| 709 // been called. | 661 // been called. |
| 710 orphan_raster_tasks_.clear(); | 662 orphan_raster_tasks_.clear(); |
| 711 | 663 |
| 712 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; | 664 did_check_for_completed_tasks_since_last_schedule_tasks_ = false; |
| 713 } | 665 } |
| 714 | 666 |
| 715 scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask( | |
| 716 Tile* tile, | |
| 717 SkPixelRef* pixel_ref) { | |
| 718 return make_scoped_refptr(new ImageDecodeTaskImpl( | |
| 719 pixel_ref, prepare_tiles_count_, | |
| 720 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | |
| 721 base::Unretained(this), tile->layer_id(), | |
| 722 base::Unretained(pixel_ref)))); | |
| 723 } | |
| 724 | |
| 725 scoped_refptr<RasterTask> TileManager::CreateRasterTask( | 667 scoped_refptr<RasterTask> TileManager::CreateRasterTask( |
| 726 const PrioritizedTile& prioritized_tile) { | 668 const PrioritizedTile& prioritized_tile) { |
| 727 Tile* tile = prioritized_tile.tile(); | 669 Tile* tile = prioritized_tile.tile(); |
| 728 uint64_t resource_content_id = 0; | 670 uint64_t resource_content_id = 0; |
| 729 scoped_ptr<ScopedResource> resource; | 671 scoped_ptr<ScopedResource> resource; |
| 730 if (tile->invalidated_id()) { | 672 if (tile->invalidated_id()) { |
| 731 // TODO(danakj): For resources that are in use, we should still grab them | 673 // TODO(danakj): For resources that are in use, we should still grab them |
| 732 // and copy from them instead of rastering everything. crbug.com/492754 | 674 // and copy from them instead of rastering everything. crbug.com/492754 |
| 733 resource = | 675 resource = |
| 734 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); | 676 resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id()); |
| 735 } | 677 } |
| 736 if (resource) { | 678 if (resource) { |
| 737 resource_content_id = tile->invalidated_id(); | 679 resource_content_id = tile->invalidated_id(); |
| 738 DCHECK_EQ(tile_task_runner_->GetResourceFormat(), resource->format()); | 680 DCHECK_EQ(tile_task_runner_->GetResourceFormat(), resource->format()); |
| 739 DCHECK_EQ(tile->desired_texture_size().ToString(), | 681 DCHECK_EQ(tile->desired_texture_size().ToString(), |
| 740 resource->size().ToString()); | 682 resource->size().ToString()); |
| 741 } else { | 683 } else { |
| 742 resource = resource_pool_->AcquireResource( | 684 resource = resource_pool_->AcquireResource( |
| 743 tile->desired_texture_size(), tile_task_runner_->GetResourceFormat()); | 685 tile->desired_texture_size(), tile_task_runner_->GetResourceFormat()); |
| 744 } | 686 } |
| 745 const ScopedResource* const_resource = resource.get(); | 687 const ScopedResource* const_resource = resource.get(); |
| 746 | 688 |
| 747 // Create and queue all image decode tasks that this tile depends on. | 689 // Create and queue all image decode tasks that this tile depends on. |
| 748 ImageDecodeTask::Vector decode_tasks; | 690 ImageDecodeTask::Vector decode_tasks; |
| 749 PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()]; | |
| 750 std::vector<SkPixelRef*> pixel_refs; | 691 std::vector<SkPixelRef*> pixel_refs; |
| 751 prioritized_tile.raster_source()->GatherPixelRefs( | 692 prioritized_tile.raster_source()->GatherPixelRefs( |
| 752 tile->content_rect(), tile->contents_scale(), &pixel_refs); | 693 tile->content_rect(), tile->contents_scale(), &pixel_refs); |
| 753 for (SkPixelRef* pixel_ref : pixel_refs) { | 694 for (SkPixelRef* pixel_ref : pixel_refs) { |
| 754 uint32_t id = pixel_ref->getGenerationID(); | 695 decode_tasks.push_back(image_decode_controller_.GetTaskForPixelRef( |
| 755 | 696 pixel_ref, tile->layer_id(), prepare_tiles_count_)); |
| 756 // Append existing image decode task if available. | |
| 757 PixelRefTaskMap::iterator decode_task_it = existing_pixel_refs.find(id); | |
| 758 if (decode_task_it != existing_pixel_refs.end()) { | |
| 759 decode_tasks.push_back(decode_task_it->second); | |
| 760 continue; | |
| 761 } | |
| 762 | |
| 763 // Create and append new image decode task for this pixel ref. | |
| 764 scoped_refptr<ImageDecodeTask> decode_task = | |
| 765 CreateImageDecodeTask(tile, pixel_ref); | |
| 766 decode_tasks.push_back(decode_task); | |
| 767 existing_pixel_refs[id] = decode_task; | |
| 768 } | 697 } |
| 769 | 698 |
| 770 return make_scoped_refptr(new RasterTaskImpl( | 699 return make_scoped_refptr(new RasterTaskImpl( |
| 771 const_resource, prioritized_tile.raster_source(), tile->content_rect(), | 700 const_resource, prioritized_tile.raster_source(), tile->content_rect(), |
| 772 tile->invalidated_content_rect(), tile->contents_scale(), | 701 tile->invalidated_content_rect(), tile->contents_scale(), |
| 773 prioritized_tile.priority().resolution, tile->layer_id(), | 702 prioritized_tile.priority().resolution, tile->layer_id(), |
| 774 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), | 703 prepare_tiles_count_, static_cast<const void*>(tile), tile->id(), |
| 775 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), | 704 tile->invalidated_id(), resource_content_id, tile->source_frame_number(), |
| 776 tile->use_picture_analysis(), | 705 tile->use_picture_analysis(), |
| 777 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), | 706 base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this), |
| 778 tile->id(), base::Passed(&resource)), | 707 tile->id(), base::Passed(&resource)), |
| 779 &decode_tasks)); | 708 &decode_tasks)); |
| 780 } | 709 } |
| 781 | 710 |
| 782 void TileManager::OnImageDecodeTaskCompleted(int layer_id, | |
| 783 SkPixelRef* pixel_ref, | |
| 784 bool was_canceled) { | |
| 785 // If the task was canceled, we need to clean it up | |
| 786 // from |image_decode_tasks_|. | |
| 787 if (!was_canceled) | |
| 788 return; | |
| 789 | |
| 790 LayerPixelRefTaskMap::iterator layer_it = image_decode_tasks_.find(layer_id); | |
| 791 if (layer_it == image_decode_tasks_.end()) | |
| 792 return; | |
| 793 | |
| 794 PixelRefTaskMap& pixel_ref_tasks = layer_it->second; | |
| 795 PixelRefTaskMap::iterator task_it = | |
| 796 pixel_ref_tasks.find(pixel_ref->getGenerationID()); | |
| 797 | |
| 798 if (task_it != pixel_ref_tasks.end()) | |
| 799 pixel_ref_tasks.erase(task_it); | |
| 800 } | |
| 801 | |
| 802 void TileManager::OnRasterTaskCompleted( | 711 void TileManager::OnRasterTaskCompleted( |
| 803 Tile::Id tile_id, | 712 Tile::Id tile_id, |
| 804 scoped_ptr<ScopedResource> resource, | 713 scoped_ptr<ScopedResource> resource, |
| 805 const RasterSource::SolidColorAnalysis& analysis, | 714 const RasterSource::SolidColorAnalysis& analysis, |
| 806 bool was_canceled) { | 715 bool was_canceled) { |
| 807 DCHECK(tiles_.find(tile_id) != tiles_.end()); | 716 DCHECK(tiles_.find(tile_id) != tiles_.end()); |
| 808 | 717 |
| 809 Tile* tile = tiles_[tile_id]; | 718 Tile* tile = tiles_[tile_id]; |
| 810 DCHECK(tile->raster_task_.get()); | 719 DCHECK(tile->raster_task_.get()); |
| 811 orphan_raster_tasks_.push_back(tile->raster_task_); | 720 orphan_raster_tasks_.push_back(tile->raster_task_); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 int flags) { | 765 int flags) { |
| 857 // We need to have a tile task worker pool to do anything meaningful with | 766 // We need to have a tile task worker pool to do anything meaningful with |
| 858 // tiles. | 767 // tiles. |
| 859 DCHECK(tile_task_runner_); | 768 DCHECK(tile_task_runner_); |
| 860 ScopedTilePtr tile(new Tile(this, desired_texture_size, content_rect, | 769 ScopedTilePtr tile(new Tile(this, desired_texture_size, content_rect, |
| 861 contents_scale, layer_id, source_frame_number, | 770 contents_scale, layer_id, source_frame_number, |
| 862 flags)); | 771 flags)); |
| 863 DCHECK(tiles_.find(tile->id()) == tiles_.end()); | 772 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 864 | 773 |
| 865 tiles_[tile->id()] = tile.get(); | 774 tiles_[tile->id()] = tile.get(); |
| 866 used_layer_counts_[tile->layer_id()]++; | 775 image_decode_controller_.AddLayerUsedCount(tile->layer_id()); |
| 867 return tile; | 776 return tile; |
| 868 } | 777 } |
| 869 | 778 |
| 870 void TileManager::SetTileTaskRunnerForTesting( | 779 void TileManager::SetTileTaskRunnerForTesting( |
| 871 TileTaskRunner* tile_task_runner) { | 780 TileTaskRunner* tile_task_runner) { |
| 872 tile_task_runner_ = tile_task_runner; | 781 tile_task_runner_ = tile_task_runner; |
| 873 tile_task_runner_->SetClient(this); | 782 tile_task_runner_->SetClient(this); |
| 874 } | 783 } |
| 875 | 784 |
| 876 bool TileManager::AreRequiredTilesReadyToDraw( | 785 bool TileManager::AreRequiredTilesReadyToDraw( |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 void TileManager::Signals::reset() { | 1002 void TileManager::Signals::reset() { |
| 1094 ready_to_activate = false; | 1003 ready_to_activate = false; |
| 1095 did_notify_ready_to_activate = false; | 1004 did_notify_ready_to_activate = false; |
| 1096 ready_to_draw = false; | 1005 ready_to_draw = false; |
| 1097 did_notify_ready_to_draw = false; | 1006 did_notify_ready_to_draw = false; |
| 1098 all_tile_tasks_completed = false; | 1007 all_tile_tasks_completed = false; |
| 1099 did_notify_all_tile_tasks_completed = false; | 1008 did_notify_all_tile_tasks_completed = false; |
| 1100 } | 1009 } |
| 1101 | 1010 |
| 1102 } // namespace cc | 1011 } // namespace cc |
| OLD | NEW |