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 image_decode_queue_ = std::move(image_decode_queue); |
44 "CheckerImageTracker::FilterImagesForCheckeringForTile", "tree", | 44 next_image_index_to_decode_ = 0; |
45 tree); | 45 ScheduleNextImageDecode(); |
46 DCHECK(checkered_images->empty()); | |
47 | |
48 base::EraseIf(*images, | |
49 [this, tree, &checkered_images](const DrawImage& draw_image) { | |
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 } | 46 } |
60 | 47 |
61 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { | 48 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { |
62 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 49 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
63 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); | 50 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); |
64 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) | 51 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) |
65 << "Sync tree can not be invalidated more than once"; | 52 << "Sync tree can not be invalidated more than once"; |
66 | 53 |
67 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); | 54 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); |
68 images_pending_invalidation_.clear(); | 55 images_pending_invalidation_.clear(); |
(...skipping 14 matching lines...) Expand all Loading... | |
83 | 70 |
84 void CheckerImageTracker::DidFinishImageDecode( | 71 void CheckerImageTracker::DidFinishImageDecode( |
85 ImageId image_id, | 72 ImageId image_id, |
86 ImageController::ImageDecodeRequestId request_id, | 73 ImageController::ImageDecodeRequestId request_id, |
87 ImageController::ImageDecodeResult result) { | 74 ImageController::ImageDecodeResult result) { |
88 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 75 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
89 "CheckerImageTracker::DidFinishImageDecode"); | 76 "CheckerImageTracker::DidFinishImageDecode"); |
90 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", | 77 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", |
91 image_id); | 78 image_id); |
92 | 79 |
93 DCHECK_NE(result, ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED); | 80 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); |
94 DCHECK_NE(pending_image_decodes_.count(image_id), 0u); | 81 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id); |
95 pending_image_decodes_.erase(image_id); | 82 outstanding_image_decode_ = nullptr; |
96 | |
97 images_decoded_once_.insert(image_id); | 83 images_decoded_once_.insert(image_id); |
98 images_pending_invalidation_.insert(image_id); | 84 images_pending_invalidation_.insert(image_id); |
85 | |
86 ScheduleNextImageDecode(); | |
99 client_->NeedsInvalidationForCheckerImagedTiles(); | 87 client_->NeedsInvalidationForCheckerImagedTiles(); |
100 } | 88 } |
101 | 89 |
102 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, | 90 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, |
103 WhichTree tree) const { | 91 WhichTree tree) const { |
104 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", | 92 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", |
105 image->uniqueID()); | 93 image->uniqueID()); |
106 | 94 |
107 if (!enable_checker_imaging_) | 95 if (!enable_checker_imaging_) |
108 return false; | 96 return false; |
109 | 97 |
110 // If the image was invalidated on the current sync tree and the tile is | 98 // If the image was invalidated on the current sync tree and the tile is |
111 // for the active tree, continue checkering it on the active tree to ensure | 99 // for the active tree, continue checkering it on the active tree to ensure |
112 // the image update is atomic for the frame. | 100 // the image update is atomic for the frame. |
113 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 && | 101 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 && |
114 tree == WhichTree::ACTIVE_TREE) { | 102 tree == WhichTree::ACTIVE_TREE) { |
115 return true; | 103 return true; |
116 } | 104 } |
117 | 105 |
118 // If a decode request is pending for this image, continue checkering it. | |
vmpstr
2017/03/29 19:11:45
Why is this check gone?
Khushal
2017/03/29 22:10:20
This shouldn't be necessary I think. It was making
| |
119 if (pending_image_decodes_.find(image->uniqueID()) != | |
120 pending_image_decodes_.end()) { | |
121 return true; | |
122 } | |
123 | |
124 // If the image is pending invalidation, continue checkering it. All tiles | 106 // If the image is pending invalidation, continue checkering it. All tiles |
125 // for these images will be invalidated on the next pending tree. | 107 // for these images will be invalidated on the next pending tree. |
126 if (images_pending_invalidation_.find(image->uniqueID()) != | 108 if (images_pending_invalidation_.find(image->uniqueID()) != |
127 images_pending_invalidation_.end()) { | 109 images_pending_invalidation_.end()) { |
128 return true; | 110 return true; |
129 } | 111 } |
130 | 112 |
131 // If the image has been decoded once before, don't checker it again. | 113 // If the image has been decoded once before, don't checker it again. |
132 if (images_decoded_once_.find(image->uniqueID()) != | 114 if (images_decoded_once_.find(image->uniqueID()) != |
133 images_decoded_once_.end()) { | 115 images_decoded_once_.end()) { |
134 return false; | 116 return false; |
135 } | 117 } |
136 | 118 |
137 return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes; | 119 return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes; |
138 } | 120 } |
139 | 121 |
140 void CheckerImageTracker::ScheduleImageDecodeIfNecessary( | 122 void CheckerImageTracker::ScheduleNextImageDecode() { |
141 const sk_sp<const SkImage>& image) { | |
142 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 123 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
143 "CheckerImageTracker::ScheduleImageDecodeIfNecessary"); | 124 "CheckerImageTracker::ScheduleNextImageDecode"); |
144 ImageId image_id = image->uniqueID(); | |
145 | 125 |
146 // If the image has already been decoded, or a decode request is pending, we | 126 if (image_decode_queue_.empty()) |
147 // don't need to schedule another decode. | |
148 if (images_decoded_once_.count(image_id) != 0 || | |
149 pending_image_decodes_.count(image_id) != 0) { | |
150 return; | 127 return; |
128 | |
129 // We can have only one outsanding decode pending completion with the decode | |
130 // service. We'll come back here when it is completed. | |
131 if (outstanding_image_decode_) | |
132 return; | |
133 | |
134 DCHECK_GE(next_image_index_to_decode_, 0u); | |
135 DCHECK_LT(next_image_index_to_decode_, image_decode_queue_.size()); | |
136 while (next_image_index_to_decode_ != image_decode_queue_.size()) { | |
vmpstr
2017/03/29 19:11:45
It's not clear to me why you're using an index her
Khushal
2017/03/29 22:10:20
Erasing from the beginning of the vector is going
Khushal
2017/03/31 04:31:00
Discussed offline. Changed to erase instead.
| |
137 outstanding_image_decode_ = | |
138 std::move(image_decode_queue_[next_image_index_to_decode_++]); | |
139 | |
140 // Schedule decode for this image if it has not already been decoded, | |
141 // otherwise try the next image in the queue. | |
142 ImageId image_id = outstanding_image_decode_->uniqueID(); | |
143 if (images_decoded_once_.count(image_id) == 0) | |
144 break; | |
145 outstanding_image_decode_ = nullptr; | |
151 } | 146 } |
152 | 147 |
148 // If we have reached the end of the queue, reset to default state. | |
149 if (next_image_index_to_decode_ == image_decode_queue_.size()) { | |
150 next_image_index_to_decode_ = 0; | |
151 image_decode_queue_.clear(); | |
152 } | |
153 | |
154 if (!outstanding_image_decode_) | |
155 return; | |
156 | |
157 ImageId image_id = outstanding_image_decode_->uniqueID(); | |
158 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u); | |
153 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", | 159 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", |
154 image_id); | 160 image_id); |
155 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0U); | |
156 | |
157 image_id_to_decode_request_id_[image_id] = | 161 image_id_to_decode_request_id_[image_id] = |
158 image_controller_->QueueImageDecode( | 162 image_controller_->QueueImageDecode( |
159 image, base::Bind(&CheckerImageTracker::DidFinishImageDecode, | 163 outstanding_image_decode_, |
160 weak_factory_.GetWeakPtr(), image_id)); | 164 base::Bind(&CheckerImageTracker::DidFinishImageDecode, |
161 pending_image_decodes_.insert(image_id); | 165 weak_factory_.GetWeakPtr(), image_id)); |
162 } | 166 } |
163 | 167 |
164 } // namespace cc | 168 } // namespace cc |
OLD | NEW |