Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/checker_image_tracker.h" | 5 #include "cc/tiles/checker_image_tracker.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
| 9 | 9 |
| 10 namespace cc { | 10 namespace cc { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 client_(client), | 28 client_(client), |
| 29 enable_checker_imaging_(enable_checker_imaging), | 29 enable_checker_imaging_(enable_checker_imaging), |
| 30 weak_factory_(this) {} | 30 weak_factory_(this) {} |
| 31 | 31 |
| 32 CheckerImageTracker::~CheckerImageTracker() { | 32 CheckerImageTracker::~CheckerImageTracker() { |
| 33 // Unlock all images pending decode requests. | 33 // Unlock all images pending decode requests. |
| 34 for (auto it : image_id_to_decode_request_id_) | 34 for (auto it : image_id_to_decode_request_id_) |
| 35 image_controller_->UnlockImageDecode(it.second); | 35 image_controller_->UnlockImageDecode(it.second); |
| 36 } | 36 } |
| 37 | 37 |
| 38 void CheckerImageTracker::FilterImagesForCheckeringForTile( | 38 void CheckerImageTracker::SetImageDecodeQueue( |
| 39 std::vector<DrawImage>* images, | 39 ImageDecodeQueue image_decode_queue) { |
| 40 ImageIdFlatSet* checkered_images, | 40 image_decode_queue_ = std::move(image_decode_queue); |
| 41 WhichTree tree) { | 41 next_image_to_decode_ = 0; |
| 42 DCHECK(checkered_images->empty()); | 42 ScheduleNextImageDecode(); |
| 43 | |
| 44 auto images_to_checker = std::remove_if( | |
| 45 images->begin(), images->end(), | |
| 46 [this, tree, &checkered_images](const DrawImage& draw_image) { | |
| 47 const sk_sp<const SkImage>& image = draw_image.image(); | |
| 48 DCHECK(image->isLazyGenerated()); | |
| 49 if (ShouldCheckerImage(image, tree)) { | |
| 50 ScheduleImageDecodeIfNecessary(image); | |
| 51 checkered_images->insert(image->uniqueID()); | |
| 52 return true; | |
| 53 } | |
| 54 return false; | |
| 55 }); | |
| 56 images->erase(images_to_checker, images->end()); | |
| 57 } | 43 } |
| 58 | 44 |
| 59 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { | 45 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { |
| 60 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) | 46 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) |
| 61 << "Sync tree can not be invalidated more than once"; | 47 << "Sync tree can not be invalidated more than once"; |
| 62 | 48 |
| 63 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); | 49 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); |
| 64 images_pending_invalidation_.clear(); | 50 images_pending_invalidation_.clear(); |
| 65 return invalidated_images_on_current_sync_tree_; | 51 return invalidated_images_on_current_sync_tree_; |
| 66 } | 52 } |
| 67 | 53 |
| 68 void CheckerImageTracker::DidActivateSyncTree() { | 54 void CheckerImageTracker::DidActivateSyncTree() { |
| 69 for (auto image_id : invalidated_images_on_current_sync_tree_) { | 55 for (auto image_id : invalidated_images_on_current_sync_tree_) { |
| 70 auto it = image_id_to_decode_request_id_.find(image_id); | 56 auto it = image_id_to_decode_request_id_.find(image_id); |
| 71 image_controller_->UnlockImageDecode(it->second); | 57 image_controller_->UnlockImageDecode(it->second); |
| 72 image_id_to_decode_request_id_.erase(it); | 58 image_id_to_decode_request_id_.erase(it); |
| 73 } | 59 } |
| 74 | 60 |
| 75 invalidated_images_on_current_sync_tree_.clear(); | 61 invalidated_images_on_current_sync_tree_.clear(); |
| 76 } | 62 } |
| 77 | 63 |
| 78 void CheckerImageTracker::DidFinishImageDecode( | 64 void CheckerImageTracker::DidFinishImageDecode( |
| 79 ImageId image_id, | 65 ImageId image_id, |
| 80 ImageController::ImageDecodeRequestId request_id, | 66 ImageController::ImageDecodeRequestId request_id, |
| 81 ImageController::ImageDecodeResult result) { | 67 ImageController::ImageDecodeResult result) { |
| 82 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", | 68 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", |
| 83 image_id); | 69 image_id); |
| 84 | 70 |
| 85 DCHECK_NE(result, ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED); | 71 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); |
| 86 DCHECK_NE(pending_image_decodes_.count(image_id), 0u); | 72 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id); |
| 87 pending_image_decodes_.erase(image_id); | 73 outstanding_image_decode_ = nullptr; |
| 88 | |
| 89 images_decoded_once_.insert(image_id); | 74 images_decoded_once_.insert(image_id); |
| 90 images_pending_invalidation_.insert(image_id); | 75 images_pending_invalidation_.insert(image_id); |
| 76 | |
| 77 ScheduleNextImageDecode(); | |
| 91 client_->NeedsInvalidationForCheckerImagedTiles(); | 78 client_->NeedsInvalidationForCheckerImagedTiles(); |
| 92 } | 79 } |
| 93 | 80 |
| 94 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, | 81 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, |
| 95 WhichTree tree) const { | 82 WhichTree tree) const { |
| 96 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", | 83 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", |
| 97 image->uniqueID()); | 84 image->uniqueID()); |
| 98 | 85 |
| 99 if (!enable_checker_imaging_) | 86 if (!enable_checker_imaging_) |
| 100 return false; | 87 return false; |
| 101 | 88 |
| 102 // If the image was invalidated on the current sync tree and the tile is | 89 // If the image was invalidated on the current sync tree and the tile is |
| 103 // for the active tree, continue checkering it on the active tree to ensure | 90 // for the active tree, continue checkering it on the active tree to ensure |
| 104 // the image update is atomic for the frame. | 91 // the image update is atomic for the frame. |
| 105 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 && | 92 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 && |
| 106 tree == WhichTree::ACTIVE_TREE) { | 93 tree == WhichTree::ACTIVE_TREE) { |
| 107 return true; | 94 return true; |
| 108 } | 95 } |
| 109 | 96 |
| 110 // If a decode request is pending for this image, continue checkering it. | |
| 111 if (pending_image_decodes_.find(image->uniqueID()) != | |
| 112 pending_image_decodes_.end()) { | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 // If the image is pending invalidation, continue checkering it. All tiles | 97 // If the image is pending invalidation, continue checkering it. All tiles |
| 117 // for these images will be invalidated on the next pending tree. | 98 // for these images will be invalidated on the next pending tree. |
| 118 if (images_pending_invalidation_.find(image->uniqueID()) != | 99 if (images_pending_invalidation_.find(image->uniqueID()) != |
| 119 images_pending_invalidation_.end()) { | 100 images_pending_invalidation_.end()) { |
| 120 return true; | 101 return true; |
| 121 } | 102 } |
| 122 | 103 |
| 123 // If the image has been decoded once before, don't checker it again. | 104 // If the image has been decoded once before, don't checker it again. |
| 124 if (images_decoded_once_.find(image->uniqueID()) != | 105 if (images_decoded_once_.find(image->uniqueID()) != |
| 125 images_decoded_once_.end()) { | 106 images_decoded_once_.end()) { |
| 126 return false; | 107 return false; |
| 127 } | 108 } |
| 128 | 109 |
| 129 return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes; | 110 return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes; |
| 130 } | 111 } |
| 131 | 112 |
| 132 void CheckerImageTracker::ScheduleImageDecodeIfNecessary( | 113 void CheckerImageTracker::ScheduleNextImageDecode() { |
| 133 const sk_sp<const SkImage>& image) { | 114 if (image_decode_queue_.empty()) |
| 134 ImageId image_id = image->uniqueID(); | 115 return; |
| 135 | 116 |
| 136 // If the image has already been decoded, or a decode request is pending, we | 117 if (outstanding_image_decode_) |
|
vmpstr
2017/03/17 18:32:13
Leave a comment here explaining that if we have so
Khushal
2017/03/27 13:57:32
Done.
| |
| 137 // don't need to schedule another decode. | |
| 138 if (images_decoded_once_.count(image_id) != 0 || | |
| 139 pending_image_decodes_.count(image_id) != 0) { | |
| 140 return; | 118 return; |
| 119 | |
| 120 DCHECK_GE(next_image_to_decode_, 0u); | |
| 121 DCHECK_LT(next_image_to_decode_, image_decode_queue_.size()); | |
| 122 while (next_image_to_decode_ != image_decode_queue_.size()) { | |
| 123 outstanding_image_decode_ = | |
| 124 std::move(image_decode_queue_[next_image_to_decode_++]); | |
| 125 | |
| 126 // The image may have already been decoded. Proceed to the next image in the | |
|
vmpstr
2017/03/17 18:32:13
Can you rephrase this comment to match the code? T
Khushal
2017/03/27 13:57:32
Done.
| |
| 127 // queue in that case. | |
| 128 ImageId image_id = outstanding_image_decode_->uniqueID(); | |
| 129 if (images_decoded_once_.count(image_id) == 0) | |
| 130 break; | |
| 131 outstanding_image_decode_ = nullptr; | |
| 141 } | 132 } |
| 142 | 133 |
| 134 if (next_image_to_decode_ == image_decode_queue_.size()) { | |
|
vmpstr
2017/03/17 18:32:13
Comment here
Khushal
2017/03/27 13:57:32
Done.
| |
| 135 next_image_to_decode_ = 0; | |
| 136 image_decode_queue_.clear(); | |
| 137 } | |
| 138 | |
| 139 if (!outstanding_image_decode_) | |
| 140 return; | |
| 141 | |
| 142 ImageId image_id = outstanding_image_decode_->uniqueID(); | |
| 143 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u); | |
| 143 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", | 144 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", |
| 144 image_id); | 145 image_id); |
| 145 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0U); | |
| 146 | |
| 147 image_id_to_decode_request_id_[image_id] = | 146 image_id_to_decode_request_id_[image_id] = |
| 148 image_controller_->QueueImageDecode( | 147 image_controller_->QueueImageDecode( |
| 149 image, base::Bind(&CheckerImageTracker::DidFinishImageDecode, | 148 outstanding_image_decode_, |
| 150 weak_factory_.GetWeakPtr(), image_id)); | 149 base::Bind(&CheckerImageTracker::DidFinishImageDecode, |
| 151 pending_image_decodes_.insert(image_id); | 150 weak_factory_.GetWeakPtr(), image_id)); |
| 152 } | 151 } |
| 153 | 152 |
| 154 } // namespace cc | 153 } // namespace cc |
| OLD | NEW |