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/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 // the ImageController is over-ridden here. | 29 // the ImageController is over-ridden here. |
30 TestImageController() | 30 TestImageController() |
31 : ImageController(base::ThreadTaskRunnerHandle::Get().get(), | 31 : ImageController(base::ThreadTaskRunnerHandle::Get().get(), |
32 base::ThreadTaskRunnerHandle::Get()) { | 32 base::ThreadTaskRunnerHandle::Get()) { |
33 SetMaxImageCacheLimitBytesForTesting(kMaxImageCacheSizeBytes); | 33 SetMaxImageCacheLimitBytesForTesting(kMaxImageCacheSizeBytes); |
34 } | 34 } |
35 | 35 |
36 ~TestImageController() override { DCHECK_EQ(locked_images_.size(), 0U); } | 36 ~TestImageController() override { DCHECK_EQ(locked_images_.size(), 0U); } |
37 | 37 |
38 int num_of_locked_images() const { return locked_images_.size(); } | 38 int num_of_locked_images() const { return locked_images_.size(); } |
39 const ImageIdFlatSet& decodes_requested() const { return decodes_requested_; } | 39 const PaintImageIdFlatSet& decodes_requested() const { |
| 40 return decodes_requested_; |
| 41 } |
40 | 42 |
41 void UnlockImageDecode(ImageDecodeRequestId id) override { | 43 void UnlockImageDecode(ImageDecodeRequestId id) override { |
42 DCHECK_EQ(locked_images_.count(id), 1U); | 44 DCHECK_EQ(locked_images_.count(id), 1U); |
43 locked_images_.erase(id); | 45 locked_images_.erase(id); |
44 } | 46 } |
45 | 47 |
46 ImageDecodeRequestId QueueImageDecode( | 48 ImageDecodeRequestId QueueImageDecode( |
47 sk_sp<const SkImage> image, | 49 sk_sp<const SkImage> image, |
48 const ImageDecodedCallback& callback) override { | 50 const ImageDecodedCallback& callback) override { |
49 ImageDecodeRequestId request_id = next_image_request_id_++; | 51 ImageDecodeRequestId request_id = next_image_request_id_++; |
50 | 52 |
51 decodes_requested_.insert(image->uniqueID()); | 53 decodes_requested_.insert(image->uniqueID()); |
52 locked_images_.insert(request_id); | 54 locked_images_.insert(request_id); |
53 | 55 |
54 // Post the callback asynchronously to match the behaviour in | 56 // Post the callback asynchronously to match the behaviour in |
55 // ImageController. | 57 // ImageController. |
56 worker_task_runner_->PostTask( | 58 worker_task_runner_->PostTask( |
57 FROM_HERE, | 59 FROM_HERE, |
58 base::BindOnce(callback, request_id, ImageDecodeResult::SUCCESS)); | 60 base::BindOnce(callback, request_id, ImageDecodeResult::SUCCESS)); |
59 | 61 |
60 return request_id; | 62 return request_id; |
61 } | 63 } |
62 | 64 |
63 private: | 65 private: |
64 ImageDecodeRequestId next_image_request_id_ = 1U; | 66 ImageDecodeRequestId next_image_request_id_ = 1U; |
65 std::unordered_set<ImageDecodeRequestId> locked_images_; | 67 std::unordered_set<ImageDecodeRequestId> locked_images_; |
66 ImageIdFlatSet decodes_requested_; | 68 PaintImageIdFlatSet decodes_requested_; |
67 }; | 69 }; |
68 | 70 |
69 class CheckerImageTrackerTest : public testing::Test, | 71 class CheckerImageTrackerTest : public testing::Test, |
70 public CheckerImageTrackerClient { | 72 public CheckerImageTrackerClient { |
71 public: | 73 public: |
72 enum class ImageType { | 74 enum class ImageType { |
73 CHECKERABLE, | 75 CHECKERABLE, |
74 SMALL_NON_CHECKERABLE, | 76 SMALL_NON_CHECKERABLE, |
75 LARGE_NON_CHECKERABLE | 77 LARGE_NON_CHECKERABLE |
76 }; | 78 }; |
77 | 79 |
78 void SetUpTracker(bool checker_images_enabled) { | 80 void SetUpTracker(bool checker_images_enabled) { |
79 checker_image_tracker_ = base::MakeUnique<CheckerImageTracker>( | 81 checker_image_tracker_ = base::MakeUnique<CheckerImageTracker>( |
80 &image_controller_, this, checker_images_enabled); | 82 &image_controller_, this, checker_images_enabled); |
81 } | 83 } |
82 | 84 |
83 void TearDown() override { checker_image_tracker_.reset(); } | 85 void TearDown() override { checker_image_tracker_.reset(); } |
84 | 86 |
85 DrawImage CreateImage(ImageType image_type) { | 87 PaintImage CreateImage( |
| 88 ImageType image_type, |
| 89 PaintImage::AnimationType animation = PaintImage::AnimationType::STATIC, |
| 90 PaintImage::CompletionState completion = |
| 91 PaintImage::CompletionState::DONE) { |
86 int dimension = 0; | 92 int dimension = 0; |
87 switch (image_type) { | 93 switch (image_type) { |
88 case ImageType::CHECKERABLE: | 94 case ImageType::CHECKERABLE: |
89 dimension = kCheckerableImageDimension; | 95 dimension = kCheckerableImageDimension; |
90 break; | 96 break; |
91 case ImageType::SMALL_NON_CHECKERABLE: | 97 case ImageType::SMALL_NON_CHECKERABLE: |
92 dimension = kSmallNonCheckerableImageDimension; | 98 dimension = kSmallNonCheckerableImageDimension; |
93 break; | 99 break; |
94 case ImageType::LARGE_NON_CHECKERABLE: | 100 case ImageType::LARGE_NON_CHECKERABLE: |
95 dimension = kLargeNonCheckerableImageDimension; | 101 dimension = kLargeNonCheckerableImageDimension; |
96 break; | 102 break; |
97 } | 103 } |
98 | 104 |
99 sk_sp<SkImage> image = | 105 sk_sp<SkImage> image = |
100 CreateDiscardableImage(gfx::Size(dimension, dimension)); | 106 CreateDiscardableImage(gfx::Size(dimension, dimension)); |
101 gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB(); | 107 return PaintImage(PaintImage::GetNextId(), image, animation, completion); |
102 return DrawImage(image, SkIRect::MakeWH(image->width(), image->height()), | |
103 kNone_SkFilterQuality, SkMatrix::I(), target_color_space); | |
104 } | 108 } |
105 | 109 |
106 CheckerImageTracker::ImageDecodeQueue BuildImageDecodeQueue( | 110 CheckerImageTracker::ImageDecodeQueue BuildImageDecodeQueue( |
107 std::vector<DrawImage> draw_images, | 111 std::vector<PaintImage> images, |
108 WhichTree tree) { | 112 WhichTree tree) { |
109 CheckerImageTracker::ImageDecodeQueue decode_queue; | 113 CheckerImageTracker::ImageDecodeQueue decode_queue; |
110 for (auto draw_image : draw_images) { | 114 for (const auto& image : images) { |
111 sk_sp<const SkImage> image = draw_image.image(); | |
112 if (checker_image_tracker_->ShouldCheckerImage(image, tree)) | 115 if (checker_image_tracker_->ShouldCheckerImage(image, tree)) |
113 decode_queue.push_back(image); | 116 decode_queue.push_back(image); |
114 } | 117 } |
115 return decode_queue; | 118 return decode_queue; |
116 } | 119 } |
117 | 120 |
118 // CheckerImageTrackerClient implementation. | 121 // CheckerImageTrackerClient implementation. |
119 void NeedsInvalidationForCheckerImagedTiles() override { | 122 void NeedsInvalidationForCheckerImagedTiles() override { |
120 invalidation_request_pending_ = true; | 123 invalidation_request_pending_ = true; |
121 } | 124 } |
122 | 125 |
123 protected: | 126 protected: |
124 TestImageController image_controller_; | 127 TestImageController image_controller_; |
125 std::unique_ptr<CheckerImageTracker> checker_image_tracker_; | 128 std::unique_ptr<CheckerImageTracker> checker_image_tracker_; |
126 | 129 |
127 bool invalidation_request_pending_ = false; | 130 bool invalidation_request_pending_ = false; |
128 }; | 131 }; |
129 | 132 |
130 TEST_F(CheckerImageTrackerTest, CheckerImagesDisabled) { | 133 TEST_F(CheckerImageTrackerTest, CheckerImagesDisabled) { |
131 // Ensures that the tracker doesn't filter any images for checkering if it is | 134 // Ensures that the tracker doesn't filter any images for checkering if it is |
132 // disabled. | 135 // disabled. |
133 SetUpTracker(false); | 136 SetUpTracker(false); |
134 | 137 |
135 ImageIdFlatSet checkered_images; | 138 PaintImageIdFlatSet checkered_images; |
136 DrawImage draw_image = CreateImage(ImageType::CHECKERABLE); | 139 PaintImage paint_image = CreateImage(ImageType::CHECKERABLE); |
137 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 140 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
138 draw_image.image(), WhichTree::PENDING_TREE)); | 141 paint_image, WhichTree::PENDING_TREE)); |
139 EXPECT_EQ(image_controller_.num_of_locked_images(), 0); | 142 EXPECT_EQ(image_controller_.num_of_locked_images(), 0); |
140 } | 143 } |
141 | 144 |
142 TEST_F(CheckerImageTrackerTest, UpdatesImagesAtomically) { | 145 TEST_F(CheckerImageTrackerTest, UpdatesImagesAtomically) { |
143 // Ensures that the tracker updates images atomically for each frame. | 146 // Ensures that the tracker updates images atomically for each frame. |
144 SetUpTracker(true); | 147 SetUpTracker(true); |
145 | 148 |
146 DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 149 PaintImage checkerable_image = CreateImage(ImageType::CHECKERABLE); |
147 DrawImage small_non_checkerable_image = | 150 PaintImage small_non_checkerable_image = |
148 CreateImage(ImageType::SMALL_NON_CHECKERABLE); | 151 CreateImage(ImageType::SMALL_NON_CHECKERABLE); |
149 DrawImage large_non_checkerable_image = | 152 PaintImage large_non_checkerable_image = |
150 CreateImage(ImageType::LARGE_NON_CHECKERABLE); | 153 CreateImage(ImageType::LARGE_NON_CHECKERABLE); |
151 CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 154 CheckerImageTracker::ImageDecodeQueue image_decode_queue; |
152 | 155 |
153 // First request to filter images. | 156 // First request to filter images. |
154 std::vector<DrawImage> draw_images = { | 157 std::vector<PaintImage> paint_images = { |
155 checkerable_image, small_non_checkerable_image, | 158 checkerable_image, small_non_checkerable_image, |
156 large_non_checkerable_image, checkerable_image}; | 159 large_non_checkerable_image, checkerable_image}; |
157 image_decode_queue = | 160 image_decode_queue = |
158 BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 161 BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); |
159 | 162 |
160 ASSERT_EQ(2u, image_decode_queue.size()); | 163 ASSERT_EQ(2u, image_decode_queue.size()); |
161 EXPECT_EQ(checkerable_image.image(), image_decode_queue[0]); | 164 EXPECT_EQ(checkerable_image, image_decode_queue[0]); |
162 EXPECT_EQ(checkerable_image.image(), image_decode_queue[1]); | 165 EXPECT_EQ(checkerable_image, image_decode_queue[1]); |
163 | 166 |
164 checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 167 checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); |
165 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 168 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); |
166 | 169 |
167 // Run pending task to indicate completion of decode request to the tracker. | 170 // Run pending task to indicate completion of decode request to the tracker. |
168 // This should send an impl-side invalidation request to the client. The | 171 // This should send an impl-side invalidation request to the client. The |
169 // images must remain locked until the sync tree to which the invalidations | 172 // images must remain locked until the sync tree to which the invalidations |
170 // are added is activated. | 173 // are added is activated. |
171 base::RunLoop().RunUntilIdle(); | 174 base::RunLoop().RunUntilIdle(); |
172 EXPECT_TRUE(invalidation_request_pending_); | 175 EXPECT_TRUE(invalidation_request_pending_); |
173 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 176 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); |
174 | 177 |
175 // Continue checkering the image until the set of images to invalidate is | 178 // Continue checkering the image until the set of images to invalidate is |
176 // pulled. | 179 // pulled. |
177 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 180 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( |
178 checkerable_image.image(), WhichTree::PENDING_TREE)); | 181 checkerable_image, WhichTree::PENDING_TREE)); |
179 | 182 |
180 ImageIdFlatSet invalidated_images = | 183 PaintImageIdFlatSet invalidated_images = |
181 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 184 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); |
182 EXPECT_EQ(invalidated_images.size(), 1U); | 185 EXPECT_EQ(invalidated_images.size(), 1U); |
183 EXPECT_EQ(invalidated_images.count(checkerable_image.image()->uniqueID()), | 186 EXPECT_EQ(invalidated_images.count(checkerable_image.stable_id()), 1U); |
184 1U); | |
185 | 187 |
186 // Use the same set of draw images to ensure that they are not checkered on | 188 // Use the same set of draw images to ensure that they are not checkered on |
187 // the pending tree now. | 189 // the pending tree now. |
188 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 190 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
189 checkerable_image.image(), WhichTree::PENDING_TREE)); | 191 checkerable_image, WhichTree::PENDING_TREE)); |
190 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 192 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
191 small_non_checkerable_image.image(), WhichTree::PENDING_TREE)); | 193 small_non_checkerable_image, WhichTree::PENDING_TREE)); |
192 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 194 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
193 large_non_checkerable_image.image(), WhichTree::PENDING_TREE)); | 195 large_non_checkerable_image, WhichTree::PENDING_TREE)); |
194 | 196 |
195 // Use this set to make the same request from the active tree, we should | 197 // Use this set to make the same request from the active tree, we should |
196 // continue checkering this image on the active tree until activation. | 198 // continue checkering this image on the active tree until activation. |
197 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 199 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( |
198 checkerable_image.image(), WhichTree::ACTIVE_TREE)); | 200 checkerable_image, WhichTree::ACTIVE_TREE)); |
199 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 201 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
200 small_non_checkerable_image.image(), WhichTree::ACTIVE_TREE)); | 202 small_non_checkerable_image, WhichTree::ACTIVE_TREE)); |
201 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 203 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
202 large_non_checkerable_image.image(), WhichTree::ACTIVE_TREE)); | 204 large_non_checkerable_image, WhichTree::ACTIVE_TREE)); |
203 | 205 |
204 // Activate the sync tree. The images should be unlocked upon activation. | 206 // Activate the sync tree. The images should be unlocked upon activation. |
205 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 207 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); |
206 checker_image_tracker_->DidActivateSyncTree(); | 208 checker_image_tracker_->DidActivateSyncTree(); |
207 } | 209 } |
208 | 210 |
209 TEST_F(CheckerImageTrackerTest, NoConsecutiveCheckeringForImage) { | 211 TEST_F(CheckerImageTrackerTest, NoConsecutiveCheckeringForImage) { |
210 // Ensures that if an image is decoded and invalidated once, it is not | 212 // Ensures that if an image is decoded and invalidated once, it is not |
211 // checkered again in subsequent frames. | 213 // checkered again in subsequent frames. |
212 SetUpTracker(true); | 214 SetUpTracker(true); |
213 | 215 |
214 DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 216 PaintImage checkerable_image = CreateImage(ImageType::CHECKERABLE); |
215 std::vector<DrawImage> draw_images = {checkerable_image}; | 217 std::vector<PaintImage> paint_images = {checkerable_image}; |
216 | 218 |
217 CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 219 CheckerImageTracker::ImageDecodeQueue image_decode_queue = |
218 BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 220 BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); |
219 EXPECT_EQ(image_decode_queue.size(), 1U); | 221 EXPECT_EQ(image_decode_queue.size(), 1U); |
220 checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 222 checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); |
221 | 223 |
222 // Trigger decode completion, take images to invalidate and activate the sync | 224 // Trigger decode completion, take images to invalidate and activate the sync |
223 // tree. | 225 // tree. |
224 base::RunLoop().RunUntilIdle(); | 226 base::RunLoop().RunUntilIdle(); |
225 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 227 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); |
226 checker_image_tracker_->DidActivateSyncTree(); | 228 checker_image_tracker_->DidActivateSyncTree(); |
227 | 229 |
228 // Subsequent requests for this image should not be checkered. | 230 // Subsequent requests for this image should not be checkered. |
229 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 231 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
230 checkerable_image.image(), WhichTree::PENDING_TREE)); | 232 checkerable_image, WhichTree::PENDING_TREE)); |
231 } | 233 } |
232 | 234 |
233 TEST_F(CheckerImageTrackerTest, | 235 TEST_F(CheckerImageTrackerTest, |
234 TracksCheckeredImagesSeperatelyInConsecutiveFrames) { | 236 TracksCheckeredImagesSeperatelyInConsecutiveFrames) { |
235 // Ensures that the set of images being checkered on the pending tree, and the | 237 // Ensures that the set of images being checkered on the pending tree, and the |
236 // active tree are tracked correctly. | 238 // active tree are tracked correctly. |
237 SetUpTracker(true); | 239 SetUpTracker(true); |
238 | 240 |
239 DrawImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); | 241 PaintImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); |
240 std::vector<DrawImage> draw_images; | 242 std::vector<PaintImage> paint_images; |
241 CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 243 CheckerImageTracker::ImageDecodeQueue image_decode_queue; |
242 | 244 |
243 // First request to filter images on the pending and active tree. | 245 // First request to filter images on the pending and active tree. |
244 draw_images.push_back(checkerable_image1); | 246 paint_images.push_back(checkerable_image1); |
245 image_decode_queue = | 247 image_decode_queue = |
246 BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 248 BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); |
247 EXPECT_EQ(image_decode_queue.size(), 1U); | 249 EXPECT_EQ(image_decode_queue.size(), 1U); |
248 checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 250 checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); |
249 | 251 |
250 // The image is also checkered on the active tree while a decode request is | 252 // The image is also checkered on the active tree while a decode request is |
251 // pending. | 253 // pending. |
252 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 254 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( |
253 checkerable_image1.image(), WhichTree::ACTIVE_TREE)); | 255 checkerable_image1, WhichTree::ACTIVE_TREE)); |
254 | 256 |
255 // Trigger decode completion and take images to invalidate on the sync tree. | 257 // Trigger decode completion and take images to invalidate on the sync tree. |
256 base::RunLoop().RunUntilIdle(); | 258 base::RunLoop().RunUntilIdle(); |
257 EXPECT_TRUE(invalidation_request_pending_); | 259 EXPECT_TRUE(invalidation_request_pending_); |
258 ImageIdFlatSet invalidated_images = | 260 PaintImageIdFlatSet invalidated_images = |
259 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 261 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); |
260 EXPECT_EQ(invalidated_images.size(), 1U); | 262 EXPECT_EQ(invalidated_images.size(), 1U); |
261 EXPECT_EQ(invalidated_images.count(checkerable_image1.image()->uniqueID()), | 263 EXPECT_EQ(invalidated_images.count(checkerable_image1.stable_id()), 1U); |
262 1U); | |
263 | 264 |
264 // Second request to filter the same image on the pending and active tree. It | 265 // Second request to filter the same image on the pending and active tree. It |
265 // should be checkered on the active tree, but not the pending tree. | 266 // should be checkered on the active tree, but not the pending tree. |
266 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 267 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( |
267 checkerable_image1.image(), WhichTree::ACTIVE_TREE)); | 268 checkerable_image1, WhichTree::ACTIVE_TREE)); |
268 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 269 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
269 checkerable_image1.image(), WhichTree::PENDING_TREE)); | 270 checkerable_image1, WhichTree::PENDING_TREE)); |
270 | 271 |
271 // New checkerable image on the pending tree. | 272 // New checkerable image on the pending tree. |
272 DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 273 PaintImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); |
273 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 274 EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( |
274 checkerable_image2.image(), WhichTree::PENDING_TREE)); | 275 checkerable_image2, WhichTree::PENDING_TREE)); |
275 | 276 |
276 // Activate the sync tree. The initial image should no longer be checkered on | 277 // Activate the sync tree. The initial image should no longer be checkered on |
277 // the active tree. | 278 // the active tree. |
278 checker_image_tracker_->DidActivateSyncTree(); | 279 checker_image_tracker_->DidActivateSyncTree(); |
279 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 280 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
280 checkerable_image1.image(), WhichTree::ACTIVE_TREE)); | 281 checkerable_image1, WhichTree::ACTIVE_TREE)); |
281 } | 282 } |
282 | 283 |
283 TEST_F(CheckerImageTrackerTest, CancelsScheduledDecodes) { | 284 TEST_F(CheckerImageTrackerTest, CancelsScheduledDecodes) { |
284 SetUpTracker(true); | 285 SetUpTracker(true); |
285 | 286 |
286 DrawImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); | 287 PaintImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); |
287 DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 288 PaintImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); |
288 std::vector<DrawImage> draw_images = {checkerable_image1, checkerable_image2}; | 289 std::vector<PaintImage> paint_images = {checkerable_image1, |
| 290 checkerable_image2}; |
289 | 291 |
290 CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 292 CheckerImageTracker::ImageDecodeQueue image_decode_queue; |
291 image_decode_queue = | 293 image_decode_queue = |
292 BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 294 BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); |
293 EXPECT_EQ(image_decode_queue.size(), 2U); | 295 EXPECT_EQ(image_decode_queue.size(), 2U); |
294 checker_image_tracker_->ScheduleImageDecodeQueue( | 296 checker_image_tracker_->ScheduleImageDecodeQueue( |
295 std::move(image_decode_queue)); | 297 std::move(image_decode_queue)); |
296 | 298 |
297 // Only the first image in the queue should have been decoded. | 299 // Only the first image in the queue should have been decoded. |
298 EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); | 300 EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); |
299 EXPECT_EQ(image_controller_.decodes_requested().count( | 301 EXPECT_EQ(image_controller_.decodes_requested().count( |
300 checkerable_image1.image()->uniqueID()), | 302 checkerable_image1.sk_image()->uniqueID()), |
301 1U); | 303 1U); |
302 | 304 |
303 // Rebuild the queue before the tracker is notified of decode completion, | 305 // Rebuild the queue before the tracker is notified of decode completion, |
304 // removing the second image and adding a new one. | 306 // removing the second image and adding a new one. |
305 DrawImage checkerable_image3 = CreateImage(ImageType::CHECKERABLE); | 307 PaintImage checkerable_image3 = CreateImage(ImageType::CHECKERABLE); |
306 draw_images = {checkerable_image1, checkerable_image3}; | 308 paint_images = {checkerable_image1, checkerable_image3}; |
307 image_decode_queue = | 309 image_decode_queue = |
308 BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 310 BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); |
309 | 311 |
310 // The queue has 2 decodes because we are still checkering on the first one. | 312 // The queue has 2 decodes because we are still checkering on the first one. |
311 EXPECT_EQ(image_decode_queue.size(), 2U); | 313 EXPECT_EQ(image_decode_queue.size(), 2U); |
312 checker_image_tracker_->ScheduleImageDecodeQueue( | 314 checker_image_tracker_->ScheduleImageDecodeQueue( |
313 std::move(image_decode_queue)); | 315 std::move(image_decode_queue)); |
314 | 316 |
315 // We still have only one decode because the tracker keeps only one decode | 317 // We still have only one decode because the tracker keeps only one decode |
316 // pending at a time. | 318 // pending at a time. |
317 EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); | 319 EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); |
318 EXPECT_EQ(image_controller_.decodes_requested().count( | 320 EXPECT_EQ(image_controller_.decodes_requested().count( |
319 checkerable_image1.image()->uniqueID()), | 321 checkerable_image1.sk_image()->uniqueID()), |
320 1U); | 322 1U); |
321 | 323 |
322 // Trigger completion for all decodes. Only 2 images should have been decoded | 324 // Trigger completion for all decodes. Only 2 images should have been decoded |
323 // since the second image was cancelled. | 325 // since the second image was cancelled. |
324 base::RunLoop().RunUntilIdle(); | 326 base::RunLoop().RunUntilIdle(); |
325 EXPECT_EQ(image_controller_.decodes_requested().size(), 2U); | 327 EXPECT_EQ(image_controller_.decodes_requested().size(), 2U); |
326 EXPECT_EQ(image_controller_.decodes_requested().count( | 328 EXPECT_EQ(image_controller_.decodes_requested().count( |
327 checkerable_image3.image()->uniqueID()), | 329 checkerable_image3.sk_image()->uniqueID()), |
328 1U); | 330 1U); |
329 EXPECT_EQ(image_controller_.num_of_locked_images(), 2); | 331 EXPECT_EQ(image_controller_.num_of_locked_images(), 2); |
330 } | 332 } |
331 | 333 |
332 TEST_F(CheckerImageTrackerTest, ClearsTracker) { | 334 TEST_F(CheckerImageTrackerTest, ClearsTracker) { |
333 SetUpTracker(true); | 335 SetUpTracker(true); |
334 | 336 |
335 DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 337 PaintImage checkerable_image = CreateImage(ImageType::CHECKERABLE); |
336 CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 338 CheckerImageTracker::ImageDecodeQueue image_decode_queue = |
337 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 339 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); |
338 EXPECT_EQ(image_decode_queue.size(), 1U); | 340 EXPECT_EQ(image_decode_queue.size(), 1U); |
339 checker_image_tracker_->ScheduleImageDecodeQueue( | 341 checker_image_tracker_->ScheduleImageDecodeQueue( |
340 std::move(image_decode_queue)); | 342 std::move(image_decode_queue)); |
341 base::RunLoop().RunUntilIdle(); | 343 base::RunLoop().RunUntilIdle(); |
342 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 344 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); |
343 | 345 |
344 // The image is no longer checkered on the pending tree. | 346 // The image is no longer checkered on the pending tree. |
345 image_decode_queue = | 347 image_decode_queue = |
(...skipping 15 matching lines...) Expand all Loading... |
361 can_clear_decode_policy_tracking = true; | 363 can_clear_decode_policy_tracking = true; |
362 checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); | 364 checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); |
363 image_decode_queue = | 365 image_decode_queue = |
364 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 366 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); |
365 image_decode_queue = | 367 image_decode_queue = |
366 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 368 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); |
367 EXPECT_EQ(image_decode_queue.size(), 1U); | 369 EXPECT_EQ(image_decode_queue.size(), 1U); |
368 | 370 |
369 // If an image had been decoded and tracker was cleared after it, we should | 371 // If an image had been decoded and tracker was cleared after it, we should |
370 // continue checkering it. | 372 // continue checkering it. |
371 DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 373 PaintImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); |
372 image_decode_queue = | 374 image_decode_queue = |
373 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 375 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); |
374 EXPECT_EQ(image_decode_queue.size(), 1U); | 376 EXPECT_EQ(image_decode_queue.size(), 1U); |
375 checker_image_tracker_->ScheduleImageDecodeQueue( | 377 checker_image_tracker_->ScheduleImageDecodeQueue( |
376 std::move(image_decode_queue)); | 378 std::move(image_decode_queue)); |
377 base::RunLoop().RunUntilIdle(); | 379 base::RunLoop().RunUntilIdle(); |
378 | 380 |
379 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 381 EXPECT_EQ(image_controller_.num_of_locked_images(), 1); |
380 can_clear_decode_policy_tracking = false; | 382 can_clear_decode_policy_tracking = false; |
381 checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); | 383 checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); |
382 EXPECT_EQ(image_controller_.num_of_locked_images(), 0); | 384 EXPECT_EQ(image_controller_.num_of_locked_images(), 0); |
383 image_decode_queue = | 385 image_decode_queue = |
384 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 386 BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); |
385 EXPECT_EQ(image_decode_queue.size(), 1U); | 387 EXPECT_EQ(image_decode_queue.size(), 1U); |
386 } | 388 } |
387 | 389 |
| 390 TEST_F(CheckerImageTrackerTest, CheckersOnlyStaticCompletedImages) { |
| 391 SetUpTracker(true); |
| 392 |
| 393 PaintImage static_image = CreateImage(ImageType::CHECKERABLE); |
| 394 PaintImage animated_image = |
| 395 CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::ANIMATED); |
| 396 PaintImage partial_image = |
| 397 CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::STATIC, |
| 398 PaintImage::CompletionState::PARTIALLY_DONE); |
| 399 PaintImage video_image = |
| 400 CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::VIDEO); |
| 401 std::vector<PaintImage> paint_images = {static_image, animated_image, |
| 402 partial_image, video_image}; |
| 403 |
| 404 CheckerImageTracker::ImageDecodeQueue image_decode_queue = |
| 405 BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); |
| 406 EXPECT_EQ(image_decode_queue.size(), 1U); |
| 407 EXPECT_EQ(image_decode_queue[0], static_image); |
| 408 |
| 409 // Change the partial image to complete and try again. It should still not |
| 410 // be checkered. |
| 411 gfx::Size image_size = gfx::Size(partial_image.sk_image()->width(), |
| 412 partial_image.sk_image()->height()); |
| 413 PaintImage completed_paint_image = |
| 414 PaintImage(partial_image.stable_id(), CreateDiscardableImage(image_size)); |
| 415 EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( |
| 416 completed_paint_image, WhichTree::PENDING_TREE)); |
| 417 } |
| 418 |
388 } // namespace | 419 } // namespace |
389 } // namespace cc | 420 } // namespace cc |
OLD | NEW |