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 DCHECK(image_decode_queue.empty() || enable_checker_imaging_); |
vmpstr
2017/04/18 00:20:00
Can you comment to explain the dcheck a bit.
Khushal
2017/04/19 06:16:41
Done.
| |
44 "CheckerImageTracker::FilterImagesForCheckeringForTile", "tree", | |
45 tree); | |
46 DCHECK(checkered_images->empty()); | |
47 | 44 |
48 base::EraseIf(*images, | 45 image_decode_queue_ = std::move(image_decode_queue); |
49 [this, tree, &checkered_images](const DrawImage& draw_image) { | 46 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 } | 47 } |
60 | 48 |
61 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { | 49 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { |
62 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 50 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
63 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); | 51 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); |
64 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) | 52 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) |
65 << "Sync tree can not be invalidated more than once"; | 53 << "Sync tree can not be invalidated more than once"; |
66 | 54 |
67 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); | 55 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); |
68 images_pending_invalidation_.clear(); | 56 images_pending_invalidation_.clear(); |
(...skipping 14 matching lines...) Expand all Loading... | |
83 | 71 |
84 void CheckerImageTracker::DidFinishImageDecode( | 72 void CheckerImageTracker::DidFinishImageDecode( |
85 ImageId image_id, | 73 ImageId image_id, |
86 ImageController::ImageDecodeRequestId request_id, | 74 ImageController::ImageDecodeRequestId request_id, |
87 ImageController::ImageDecodeResult result) { | 75 ImageController::ImageDecodeResult result) { |
88 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 76 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
89 "CheckerImageTracker::DidFinishImageDecode"); | 77 "CheckerImageTracker::DidFinishImageDecode"); |
90 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", | 78 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", |
91 image_id); | 79 image_id); |
92 | 80 |
93 DCHECK_NE(result, ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED); | 81 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); |
94 DCHECK_NE(pending_image_decodes_.count(image_id), 0u); | 82 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id); |
95 DCHECK_NE(image_async_decode_state_.count(image_id), 0u); | |
96 | 83 |
97 pending_image_decodes_.erase(image_id); | 84 outstanding_image_decode_ = nullptr; |
98 | |
99 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE; | 85 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE; |
100 images_pending_invalidation_.insert(image_id); | 86 images_pending_invalidation_.insert(image_id); |
87 | |
88 ScheduleNextImageDecode(); | |
101 client_->NeedsInvalidationForCheckerImagedTiles(); | 89 client_->NeedsInvalidationForCheckerImagedTiles(); |
102 } | 90 } |
103 | 91 |
104 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, | 92 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, |
105 WhichTree tree) { | 93 WhichTree tree) { |
106 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", | 94 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", |
107 image->uniqueID()); | 95 image->uniqueID()); |
108 | 96 |
109 if (!enable_checker_imaging_) | 97 if (!enable_checker_imaging_) |
110 return false; | 98 return false; |
(...skipping 19 matching lines...) Expand all Loading... | |
130 auto it = insert_result.first; | 118 auto it = insert_result.first; |
131 if (insert_result.second) { | 119 if (insert_result.second) { |
132 it->second = SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes | 120 it->second = SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes |
133 ? DecodePolicy::ASYNC | 121 ? DecodePolicy::ASYNC |
134 : DecodePolicy::SYNC_PERMANENT; | 122 : DecodePolicy::SYNC_PERMANENT; |
135 } | 123 } |
136 | 124 |
137 return it->second == DecodePolicy::ASYNC; | 125 return it->second == DecodePolicy::ASYNC; |
138 } | 126 } |
139 | 127 |
140 void CheckerImageTracker::ScheduleImageDecodeIfNecessary( | 128 void CheckerImageTracker::ScheduleNextImageDecode() { |
141 const sk_sp<const SkImage>& image) { | |
142 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 129 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
143 "CheckerImageTracker::ScheduleImageDecodeIfNecessary"); | 130 "CheckerImageTracker::ScheduleNextImageDecode"); |
144 ImageId image_id = image->uniqueID(); | 131 // We can have only one outsanding decode pending completion with the decode |
145 | 132 // 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 | 133 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; | 134 return; |
154 | 135 |
155 // If a decode request is pending, we don't need to schedule another decode. | 136 while (!image_decode_queue_.empty()) { |
156 if (pending_image_decodes_.count(image_id) != 0) { | 137 auto candidate = image_decode_queue_.front(); |
vmpstr
2017/04/18 00:20:00
std::move
Khushal
2017/04/19 06:16:41
Done.
| |
138 image_decode_queue_.erase(image_decode_queue_.begin()); | |
139 | |
140 // Once an image has been decoded, they can still be present in the decode | |
vmpstr
2017/04/18 00:20:00
s/they/it/
Khushal
2017/04/19 06:16:41
Done.
| |
141 // queue (duplicate entries), or while an image is still being skipped on | |
142 // the active tree. Check if the image is still ASYNC to see if a decode is | |
143 // needed. | |
144 ImageId image_id = candidate->uniqueID(); | |
145 auto it = image_async_decode_state_.find(image_id); | |
146 DCHECK(it != image_async_decode_state_.end()); | |
147 if (it->second != DecodePolicy::ASYNC) | |
148 continue; | |
149 | |
150 outstanding_image_decode_ = std::move(candidate); | |
151 break; | |
152 } | |
153 | |
154 // We either found an image to decode or we reached the end of the queue. If | |
155 // we couldn't find an image, we're done. | |
156 if (!outstanding_image_decode_) { | |
157 DCHECK(image_decode_queue_.empty()); | |
157 return; | 158 return; |
158 } | 159 } |
159 | 160 |
161 ImageId image_id = outstanding_image_decode_->uniqueID(); | |
162 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u); | |
160 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", | 163 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", |
161 image_id); | 164 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] = | 165 image_id_to_decode_request_id_[image_id] = |
165 image_controller_->QueueImageDecode( | 166 image_controller_->QueueImageDecode( |
166 image, base::Bind(&CheckerImageTracker::DidFinishImageDecode, | 167 outstanding_image_decode_, |
167 weak_factory_.GetWeakPtr(), image_id)); | 168 base::Bind(&CheckerImageTracker::DidFinishImageDecode, |
168 pending_image_decodes_.insert(image_id); | 169 weak_factory_.GetWeakPtr(), image_id)); |
169 } | 170 } |
170 | 171 |
171 } // namespace cc | 172 } // namespace cc |
OLD | NEW |