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