Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(781)

Side by Side Diff: cc/tiles/checker_image_tracker_unittest.cc

Issue 2668873002: cc: Add checker-imaging support to TileManager. (Closed)
Patch Set: remove include Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/tiles/checker_image_tracker.cc ('k') | cc/tiles/image_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/tiles/checker_image_tracker.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/run_loop.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "cc/test/skia_common.h"
12 #include "cc/tiles/image_controller.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace cc {
16 namespace {
17
18 const int kCheckerableImageDimension = 512;
19 const int kNonCheckerableImageDimension = 16;
20
21 class TestImageController : public ImageController {
22 public:
23 // We can use the same thread for the image worker because all use of it in
24 // the ImageController is over-ridden here.
25 TestImageController()
26 : ImageController(base::ThreadTaskRunnerHandle::Get().get(),
27 base::ThreadTaskRunnerHandle::Get()) {}
28
29 ~TestImageController() override { DCHECK_EQ(locked_images_.size(), 0U); }
30
31 int num_of_locked_images() const { return locked_images_.size(); }
32
33 void UnlockImageDecode(ImageDecodeRequestId id) override {
34 DCHECK_EQ(locked_images_.count(id), 1U);
35 locked_images_.erase(id);
36 }
37
38 ImageDecodeRequestId QueueImageDecode(
39 sk_sp<const SkImage> image,
40 const ImageDecodedCallback& callback) override {
41 ImageDecodeRequestId request_id = next_image_request_id_++;
42
43 // The tracker should request a decode only once.
44 EXPECT_EQ(decodes_requested_.count(image->uniqueID()), 0u);
45 decodes_requested_.insert(image->uniqueID());
46
47 locked_images_.insert(request_id);
48
49 // Post the callback asynchronously to match the behaviour in
50 // ImageController.
51 worker_task_runner_->PostTask(FROM_HERE, base::Bind(callback, request_id));
52
53 return request_id;
54 }
55
56 private:
57 ImageDecodeRequestId next_image_request_id_ = 1U;
58 std::unordered_set<ImageDecodeRequestId> locked_images_;
59 ImageIdFlatSet decodes_requested_;
60 };
61
62 class CheckerImageTrackerTest : public testing::Test,
63 public CheckerImageTrackerClient {
64 public:
65 enum class ImageType { CHECKERABLE, NON_CHECKERABLE };
66
67 void SetUpTracker(bool checker_images_enabled) {
68 checker_image_tracker_ = base::MakeUnique<CheckerImageTracker>(
69 &image_controller_, this, checker_images_enabled);
70 }
71
72 void TearDown() override { checker_image_tracker_.reset(); }
73
74 DrawImage CreateImage(ImageType image_type) {
75 int dimension = image_type == ImageType::CHECKERABLE
76 ? kCheckerableImageDimension
77 : kNonCheckerableImageDimension;
78 sk_sp<SkImage> image =
79 CreateDiscardableImage(gfx::Size(dimension, dimension));
80 return DrawImage(image, SkIRect::MakeWH(image->width(), image->height()),
81 kNone_SkFilterQuality, SkMatrix::I());
82 }
83
84 // CheckerImageTrackerClient implementation.
85 void NeedsInvalidationForCheckerImagedTiles() override {
86 invalidation_request_pending_ = true;
87 }
88
89 protected:
90 TestImageController image_controller_;
91 std::unique_ptr<CheckerImageTracker> checker_image_tracker_;
92
93 bool invalidation_request_pending_ = false;
94 };
95
96 TEST_F(CheckerImageTrackerTest, CheckerImagesDisabled) {
97 // Ensures that the tracker doesn't filter any images for checkering if it is
98 // disabled.
99 SetUpTracker(false);
100
101 std::vector<DrawImage> draw_images;
102 ImageIdFlatSet checkered_images;
103 draw_images.push_back(CreateImage(ImageType::CHECKERABLE));
104 checker_image_tracker_->FilterImagesForCheckeringForTile(
105 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
106 EXPECT_EQ(draw_images.size(), 1U);
107 EXPECT_EQ(checkered_images.size(), 0U);
108 EXPECT_EQ(image_controller_.num_of_locked_images(), 0);
109 }
110
111 TEST_F(CheckerImageTrackerTest, UpdatesImagesAtomically) {
112 // Ensures that the tracker updates images atomically for each frame.
113 SetUpTracker(true);
114
115 DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE);
116 DrawImage non_checkerable_image = CreateImage(ImageType::NON_CHECKERABLE);
117 ImageIdFlatSet checkered_images;
118 std::vector<DrawImage> draw_images;
119
120 // First request to filter images.
121 draw_images.push_back(checkerable_image);
122 draw_images.push_back(non_checkerable_image);
123 draw_images.push_back(checkerable_image);
124 checker_image_tracker_->FilterImagesForCheckeringForTile(
125 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
126
127 EXPECT_EQ(draw_images.size(), 1U);
128 EXPECT_EQ(draw_images[0].image(), non_checkerable_image.image());
129 EXPECT_EQ(checkered_images.size(), 1U);
130 EXPECT_EQ(checkered_images.count(checkerable_image.image()->uniqueID()), 1U);
131 EXPECT_EQ(image_controller_.num_of_locked_images(), 1);
132
133 // Run pending task to indicate completion of decode request to the tracker.
134 // This should send an impl-side invalidation request to the client. The
135 // images must remain locked until the sync tree to which the invalidations
136 // are added is activated.
137 base::RunLoop().RunUntilIdle();
138 EXPECT_TRUE(invalidation_request_pending_);
139 EXPECT_EQ(image_controller_.num_of_locked_images(), 1);
140
141 // Continue checkering the image until the set of images to invalidate is
142 // pulled.
143 draw_images.clear();
144 draw_images.push_back(checkerable_image);
145 checkered_images.clear();
146 checker_image_tracker_->FilterImagesForCheckeringForTile(
147 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
148 EXPECT_EQ(draw_images.size(), 0U);
149 EXPECT_EQ(checkered_images.size(), 1U);
150 EXPECT_EQ(image_controller_.num_of_locked_images(), 1);
151
152 ImageIdFlatSet invalidated_images =
153 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree();
154 EXPECT_EQ(invalidated_images.size(), 1U);
155 EXPECT_EQ(invalidated_images.count(checkerable_image.image()->uniqueID()),
156 1U);
157
158 // Use the same set of draw images to ensure that they are not checkered on
159 // the pending tree now.
160 draw_images.clear();
161 draw_images.push_back(checkerable_image);
162 draw_images.push_back(non_checkerable_image);
163 checkered_images.clear();
164 checker_image_tracker_->FilterImagesForCheckeringForTile(
165 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
166 EXPECT_EQ(draw_images.size(), 2U);
167 EXPECT_EQ(checkered_images.size(), 0U);
168
169 // Use this set to make the same request from the active tree, we should
170 // continue checkering this image on the active tree until activation.
171 draw_images.clear();
172 draw_images.push_back(checkerable_image);
173 draw_images.push_back(non_checkerable_image);
174 checkered_images.clear();
175 checker_image_tracker_->FilterImagesForCheckeringForTile(
176 &draw_images, &checkered_images, WhichTree::ACTIVE_TREE);
177 EXPECT_EQ(draw_images.size(), 1U);
178 EXPECT_EQ(draw_images[0].image(), non_checkerable_image.image());
179 EXPECT_EQ(checkered_images.size(), 1U);
180 EXPECT_EQ(checkered_images.count(checkerable_image.image()->uniqueID()), 1U);
181
182 // Activate the sync tree. The images should be unlocked upon activation.
183 EXPECT_EQ(image_controller_.num_of_locked_images(), 1);
184 checker_image_tracker_->DidActivateSyncTree();
185 }
186
187 TEST_F(CheckerImageTrackerTest, NoConsecutiveCheckeringForImage) {
188 // Ensures that if an image is decoded and invalidated once, it is not
189 // checkered again in subsequent frames.
190 SetUpTracker(true);
191
192 DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE);
193 DrawImage non_checkerable_image = CreateImage(ImageType::NON_CHECKERABLE);
194 ImageIdFlatSet checkered_images;
195 std::vector<DrawImage> draw_images;
196
197 draw_images.clear();
198 draw_images.push_back(checkerable_image);
199 checkered_images.clear();
200 checker_image_tracker_->FilterImagesForCheckeringForTile(
201 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
202 EXPECT_EQ(draw_images.size(), 0U);
203 EXPECT_EQ(checkered_images.size(), 1U);
204
205 // Trigger decode completion, take images to invalidate and activate the sync
206 // tree.
207 base::RunLoop().RunUntilIdle();
208 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree();
209 checker_image_tracker_->DidActivateSyncTree();
210
211 // Subsequent requests for this image should not be checkered.
212 draw_images.clear();
213 draw_images.push_back(checkerable_image);
214 checkered_images.clear();
215 checker_image_tracker_->FilterImagesForCheckeringForTile(
216 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
217 EXPECT_EQ(draw_images.size(), 1U);
218 EXPECT_EQ(checkered_images.size(), 0U);
219 }
220
221 TEST_F(CheckerImageTrackerTest,
222 TracksCheckeredImagesSeperatelyInConsecutiveFrames) {
223 // Ensures that the set of images being checkered on the pending tree, and the
224 // active tree are tracked correctly.
225 SetUpTracker(true);
226
227 DrawImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE);
228 ImageIdFlatSet checkered_images;
229 std::vector<DrawImage> draw_images;
230
231 // First request to filter images on the pending and active tree.
232 draw_images.push_back(checkerable_image1);
233 checker_image_tracker_->FilterImagesForCheckeringForTile(
234 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
235 EXPECT_EQ(draw_images.size(), 0U);
236 EXPECT_EQ(checkered_images.size(), 1U);
237
238 // The image is also checkered on the active tree while a decode request is
239 // pending.
240 draw_images.clear();
241 checkered_images.clear();
242 draw_images.push_back(checkerable_image1);
243 checker_image_tracker_->FilterImagesForCheckeringForTile(
244 &draw_images, &checkered_images, WhichTree::ACTIVE_TREE);
245 EXPECT_EQ(draw_images.size(), 0U);
246 EXPECT_EQ(checkered_images.size(), 1U);
247
248 // Trigger decode completion and take images to invalidate on the sync tree.
249 base::RunLoop().RunUntilIdle();
250 EXPECT_TRUE(invalidation_request_pending_);
251 ImageIdFlatSet invalidated_images =
252 checker_image_tracker_->TakeImagesToInvalidateOnSyncTree();
253 EXPECT_EQ(invalidated_images.size(), 1U);
254 EXPECT_EQ(invalidated_images.count(checkerable_image1.image()->uniqueID()),
255 1U);
256
257 // Second request to filter the same image on the pending and active tree. It
258 // should be checkered on the active tree, but not the pending tree.
259 draw_images.clear();
260 checkered_images.clear();
261 draw_images.push_back(checkerable_image1);
262 checker_image_tracker_->FilterImagesForCheckeringForTile(
263 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
264 EXPECT_EQ(draw_images.size(), 1U);
265 EXPECT_EQ(checkered_images.size(), 0U);
266
267 checker_image_tracker_->FilterImagesForCheckeringForTile(
268 &draw_images, &checkered_images, WhichTree::ACTIVE_TREE);
269 EXPECT_EQ(draw_images.size(), 0U);
270 EXPECT_EQ(checkered_images.size(), 1U);
271
272 // New checkerable image on the pending tree.
273 DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE);
274 draw_images.clear();
275 checkered_images.clear();
276 draw_images.push_back(checkerable_image2);
277 checker_image_tracker_->FilterImagesForCheckeringForTile(
278 &draw_images, &checkered_images, WhichTree::PENDING_TREE);
279 EXPECT_EQ(draw_images.size(), 0U);
280 EXPECT_EQ(checkered_images.size(), 1U);
281
282 // Activate the sync tree. The initial image should no longer be checkered on
283 // the active tree.
284 checker_image_tracker_->DidActivateSyncTree();
285
286 draw_images.clear();
287 checkered_images.clear();
288 draw_images.push_back(checkerable_image1);
289 checker_image_tracker_->FilterImagesForCheckeringForTile(
290 &draw_images, &checkered_images, WhichTree::ACTIVE_TREE);
291 EXPECT_EQ(draw_images.size(), 1U);
292 EXPECT_EQ(checkered_images.size(), 0U);
293 }
294
295 } // namespace
296 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/checker_image_tracker.cc ('k') | cc/tiles/image_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698