| 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/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 client_(client), | 29 client_(client), |
| 30 enable_checker_imaging_(enable_checker_imaging), | 30 enable_checker_imaging_(enable_checker_imaging), |
| 31 weak_factory_(this) {} | 31 weak_factory_(this) {} |
| 32 | 32 |
| 33 CheckerImageTracker::~CheckerImageTracker() { | 33 CheckerImageTracker::~CheckerImageTracker() { |
| 34 // Unlock all images pending decode requests. | 34 // Unlock all images pending decode requests. |
| 35 for (auto it : image_id_to_decode_request_id_) | 35 for (auto it : image_id_to_decode_request_id_) |
| 36 image_controller_->UnlockImageDecode(it.second); | 36 image_controller_->UnlockImageDecode(it.second); |
| 37 } | 37 } |
| 38 | 38 |
| 39 void CheckerImageTracker::FilterImagesForCheckeringForTile( | 39 void CheckerImageTracker::ScheduleImageDecodeQueue( |
| 40 std::vector<DrawImage>* images, | 40 ImageDecodeQueue image_decode_queue) { |
| 41 ImageIdFlatSet* checkered_images, | 41 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 42 WhichTree tree) { | 42 "CheckerImageTracker::ScheduleImageDecodeQueue"); |
| 43 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 43 // Only checker-imaged (async updated) images are decoded using the image |
| 44 "CheckerImageTracker::FilterImagesForCheckeringForTile", "tree", | 44 // decode service. If |enable_checker_imaging_| is false, no image should |
| 45 tree); | 45 // be checkered. |
| 46 DCHECK(checkered_images->empty()); | 46 DCHECK(image_decode_queue.empty() || enable_checker_imaging_); |
| 47 | 47 |
| 48 base::EraseIf(*images, | 48 image_decode_queue_ = std::move(image_decode_queue); |
| 49 [this, tree, &checkered_images](const DrawImage& draw_image) { | 49 ScheduleNextImageDecode(); |
| 50 const sk_sp<const SkImage>& image = draw_image.image(); | |
| 51 DCHECK(image->isLazyGenerated()); | |
| 52 if (ShouldCheckerImage(image, tree)) { | |
| 53 ScheduleImageDecodeIfNecessary(image); | |
| 54 checkered_images->insert(image->uniqueID()); | |
| 55 return true; | |
| 56 } | |
| 57 return false; | |
| 58 }); | |
| 59 } | 50 } |
| 60 | 51 |
| 61 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { | 52 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { |
| 62 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 53 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 63 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); | 54 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); |
| 64 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) | 55 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) |
| 65 << "Sync tree can not be invalidated more than once"; | 56 << "Sync tree can not be invalidated more than once"; |
| 66 | 57 |
| 67 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); | 58 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); |
| 68 images_pending_invalidation_.clear(); | 59 images_pending_invalidation_.clear(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 83 | 74 |
| 84 void CheckerImageTracker::DidFinishImageDecode( | 75 void CheckerImageTracker::DidFinishImageDecode( |
| 85 ImageId image_id, | 76 ImageId image_id, |
| 86 ImageController::ImageDecodeRequestId request_id, | 77 ImageController::ImageDecodeRequestId request_id, |
| 87 ImageController::ImageDecodeResult result) { | 78 ImageController::ImageDecodeResult result) { |
| 88 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 79 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 89 "CheckerImageTracker::DidFinishImageDecode"); | 80 "CheckerImageTracker::DidFinishImageDecode"); |
| 90 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", | 81 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", |
| 91 image_id); | 82 image_id); |
| 92 | 83 |
| 93 DCHECK_NE(result, ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED); | 84 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); |
| 94 DCHECK_NE(pending_image_decodes_.count(image_id), 0u); | 85 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id); |
| 95 DCHECK_NE(image_async_decode_state_.count(image_id), 0u); | |
| 96 | 86 |
| 97 pending_image_decodes_.erase(image_id); | 87 outstanding_image_decode_ = nullptr; |
| 98 | |
| 99 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE; | 88 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE; |
| 100 images_pending_invalidation_.insert(image_id); | 89 images_pending_invalidation_.insert(image_id); |
| 90 |
| 91 ScheduleNextImageDecode(); |
| 101 client_->NeedsInvalidationForCheckerImagedTiles(); | 92 client_->NeedsInvalidationForCheckerImagedTiles(); |
| 102 } | 93 } |
| 103 | 94 |
| 104 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, | 95 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, |
| 105 WhichTree tree) { | 96 WhichTree tree) { |
| 106 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", | 97 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", |
| 107 image->uniqueID()); | 98 image->uniqueID()); |
| 108 | 99 |
| 109 if (!enable_checker_imaging_) | 100 if (!enable_checker_imaging_) |
| 110 return false; | 101 return false; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 130 auto it = insert_result.first; | 121 auto it = insert_result.first; |
| 131 if (insert_result.second) { | 122 if (insert_result.second) { |
| 132 it->second = SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes | 123 it->second = SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes |
| 133 ? DecodePolicy::ASYNC | 124 ? DecodePolicy::ASYNC |
| 134 : DecodePolicy::SYNC_PERMANENT; | 125 : DecodePolicy::SYNC_PERMANENT; |
| 135 } | 126 } |
| 136 | 127 |
| 137 return it->second == DecodePolicy::ASYNC; | 128 return it->second == DecodePolicy::ASYNC; |
| 138 } | 129 } |
| 139 | 130 |
| 140 void CheckerImageTracker::ScheduleImageDecodeIfNecessary( | 131 void CheckerImageTracker::ScheduleNextImageDecode() { |
| 141 const sk_sp<const SkImage>& image) { | |
| 142 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 132 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 143 "CheckerImageTracker::ScheduleImageDecodeIfNecessary"); | 133 "CheckerImageTracker::ScheduleNextImageDecode"); |
| 144 ImageId image_id = image->uniqueID(); | 134 // We can have only one outsanding decode pending completion with the decode |
| 145 | 135 // service. We'll come back here when it is completed. |
| 146 // Once an image has been decoded, they can still be present in the decode | 136 if (outstanding_image_decode_) |
| 147 // queue (duplicate entries), or while an image is still being skipped on the | |
| 148 // active tree. Check if the image is still ASYNC to see if a decode is | |
| 149 // needed. | |
| 150 auto it = image_async_decode_state_.find(image_id); | |
| 151 DCHECK(it != image_async_decode_state_.end()); | |
| 152 if (it->second != DecodePolicy::ASYNC) | |
| 153 return; | 137 return; |
| 154 | 138 |
| 155 // If a decode request is pending, we don't need to schedule another decode. | 139 while (!image_decode_queue_.empty()) { |
| 156 if (pending_image_decodes_.count(image_id) != 0) { | 140 auto candidate = std::move(image_decode_queue_.front()); |
| 141 image_decode_queue_.erase(image_decode_queue_.begin()); |
| 142 |
| 143 // Once an image has been decoded, it can still be present in the decode |
| 144 // queue (duplicate entries), or while an image is still being skipped on |
| 145 // the active tree. Check if the image is still ASYNC to see if a decode is |
| 146 // needed. |
| 147 ImageId image_id = candidate->uniqueID(); |
| 148 auto it = image_async_decode_state_.find(image_id); |
| 149 DCHECK(it != image_async_decode_state_.end()); |
| 150 if (it->second != DecodePolicy::ASYNC) |
| 151 continue; |
| 152 |
| 153 outstanding_image_decode_ = std::move(candidate); |
| 154 break; |
| 155 } |
| 156 |
| 157 // We either found an image to decode or we reached the end of the queue. If |
| 158 // we couldn't find an image, we're done. |
| 159 if (!outstanding_image_decode_) { |
| 160 DCHECK(image_decode_queue_.empty()); |
| 157 return; | 161 return; |
| 158 } | 162 } |
| 159 | 163 |
| 164 ImageId image_id = outstanding_image_decode_->uniqueID(); |
| 165 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u); |
| 160 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", | 166 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", |
| 161 image_id); | 167 image_id); |
| 162 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0U); | |
| 163 | |
| 164 image_id_to_decode_request_id_[image_id] = | 168 image_id_to_decode_request_id_[image_id] = |
| 165 image_controller_->QueueImageDecode( | 169 image_controller_->QueueImageDecode( |
| 166 image, base::Bind(&CheckerImageTracker::DidFinishImageDecode, | 170 outstanding_image_decode_, |
| 167 weak_factory_.GetWeakPtr(), image_id)); | 171 base::Bind(&CheckerImageTracker::DidFinishImageDecode, |
| 168 pending_image_decodes_.insert(image_id); | 172 weak_factory_.GetWeakPtr(), image_id)); |
| 169 } | 173 } |
| 170 | 174 |
| 171 } // namespace cc | 175 } // namespace cc |
| OLD | NEW |