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

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

Issue 2703633004: cc: Make image controller return a status with the callback. (Closed)
Patch Set: update Created 3 years, 9 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/image_controller.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/image_controller.h"
5 #include "base/bind.h" 6 #include "base/bind.h"
6 #include "base/optional.h" 7 #include "base/optional.h"
7 #include "base/run_loop.h" 8 #include "base/run_loop.h"
8 #include "base/test/test_simple_task_runner.h" 9 #include "base/test/test_simple_task_runner.h"
9 #include "base/threading/sequenced_task_runner_handle.h" 10 #include "base/threading/sequenced_task_runner_handle.h"
10 #include "cc/tiles/image_controller.h" 11 #include "cc/test/skia_common.h"
11 #include "cc/tiles/image_decode_cache.h" 12 #include "cc/tiles/image_decode_cache.h"
12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
13 14
14 namespace cc { 15 namespace cc {
15 namespace { 16 namespace {
16 17
17 class TestWorkerThread : public base::SimpleThread { 18 class TestWorkerThread : public base::SimpleThread {
18 public: 19 public:
19 TestWorkerThread() 20 TestWorkerThread()
20 : base::SimpleThread("test_worker_thread"), condition_(&lock_) {} 21 : base::SimpleThread("test_worker_thread"), condition_(&lock_) {}
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 }; 88 };
88 89
89 // Image decode cache with introspection! 90 // Image decode cache with introspection!
90 class TestableCache : public ImageDecodeCache { 91 class TestableCache : public ImageDecodeCache {
91 public: 92 public:
92 ~TestableCache() override { EXPECT_EQ(number_of_refs_, 0); } 93 ~TestableCache() override { EXPECT_EQ(number_of_refs_, 0); }
93 94
94 bool GetTaskForImageAndRef(const DrawImage& image, 95 bool GetTaskForImageAndRef(const DrawImage& image,
95 const TracingInfo& tracing_info, 96 const TracingInfo& tracing_info,
96 scoped_refptr<TileTask>* task) override { 97 scoped_refptr<TileTask>* task) override {
98 // Return false for large images to mimic "won't fit in memory"
99 // behavior.
100 if (image.image() &&
101 image.image()->width() * image.image()->height() >= 1000 * 1000) {
102 return false;
103 }
104
97 *task = task_to_use_; 105 *task = task_to_use_;
98 ++number_of_refs_; 106 ++number_of_refs_;
99 return true; 107 return true;
100 } 108 }
101 bool GetOutOfRasterDecodeTaskForImageAndRef( 109 bool GetOutOfRasterDecodeTaskForImageAndRef(
102 const DrawImage& image, 110 const DrawImage& image,
103 scoped_refptr<TileTask>* task) override { 111 scoped_refptr<TileTask>* task) override {
104 *task = task_to_use_; 112 return GetTaskForImageAndRef(image, TracingInfo(), task);
105 ++number_of_refs_;
106 return true;
107 } 113 }
108 114
109 void UnrefImage(const DrawImage& image) override { 115 void UnrefImage(const DrawImage& image) override {
110 ASSERT_GT(number_of_refs_, 0); 116 ASSERT_GT(number_of_refs_, 0);
111 --number_of_refs_; 117 --number_of_refs_;
112 } 118 }
113 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& image) override { 119 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& image) override {
114 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 120 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
115 } 121 }
116 void DrawWithImageFinished(const DrawImage& image, 122 void DrawWithImageFinished(const DrawImage& image,
117 const DecodedDrawImage& decoded_image) override {} 123 const DecodedDrawImage& decoded_image) override {}
118 void ReduceCacheUsage() override {} 124 void ReduceCacheUsage() override {}
119 void SetShouldAggressivelyFreeResources( 125 void SetShouldAggressivelyFreeResources(
120 bool aggressively_free_resources) override {} 126 bool aggressively_free_resources) override {}
121 127
122 int number_of_refs() const { return number_of_refs_; } 128 int number_of_refs() const { return number_of_refs_; }
123 void SetTaskToUse(scoped_refptr<TileTask> task) { task_to_use_ = task; } 129 void SetTaskToUse(scoped_refptr<TileTask> task) { task_to_use_ = task; }
124 130
125 private: 131 private:
126 int number_of_refs_ = 0; 132 int number_of_refs_ = 0;
127 scoped_refptr<TileTask> task_to_use_; 133 scoped_refptr<TileTask> task_to_use_;
128 }; 134 };
129 135
130 // A simple class that can receive decode callbacks. 136 // A simple class that can receive decode callbacks.
131 class DecodeClient { 137 class DecodeClient {
132 public: 138 public:
133 DecodeClient() {} 139 DecodeClient() {}
134 void Callback(const base::Closure& quit_closure, 140 void Callback(const base::Closure& quit_closure,
135 ImageController::ImageDecodeRequestId id) { 141 ImageController::ImageDecodeRequestId id,
142 ImageController::ImageDecodeResult result) {
136 id_ = id; 143 id_ = id;
144 result_ = result;
137 quit_closure.Run(); 145 quit_closure.Run();
138 } 146 }
139 147
140 ImageController::ImageDecodeRequestId id() { return id_; } 148 ImageController::ImageDecodeRequestId id() { return id_; }
149 ImageController::ImageDecodeResult result() { return result_; }
141 150
142 private: 151 private:
143 ImageController::ImageDecodeRequestId id_ = 0; 152 ImageController::ImageDecodeRequestId id_ = 0;
153 ImageController::ImageDecodeResult result_ =
154 ImageController::ImageDecodeResult::FAILURE;
144 }; 155 };
145 156
146 // A dummy task that does nothing. 157 // A dummy task that does nothing.
147 class SimpleTask : public TileTask { 158 class SimpleTask : public TileTask {
148 public: 159 public:
149 SimpleTask() : TileTask(true /* supports_concurrent_execution */) { 160 SimpleTask() : TileTask(true /* supports_concurrent_execution */) {
150 EXPECT_TRUE(thread_checker_.CalledOnValidThread()); 161 EXPECT_TRUE(thread_checker_.CalledOnValidThread());
151 } 162 }
152 163
153 void RunOnWorkerThread() override { 164 void RunOnWorkerThread() override {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 }; 222 };
212 223
213 // For tests that exercise image controller's thread, this is the timeout value 224 // For tests that exercise image controller's thread, this is the timeout value
214 // to 225 // to
215 // allow the worker thread to do its work. 226 // allow the worker thread to do its work.
216 int kDefaultTimeoutSeconds = 10; 227 int kDefaultTimeoutSeconds = 10;
217 228
218 class ImageControllerTest : public testing::Test { 229 class ImageControllerTest : public testing::Test {
219 public: 230 public:
220 ImageControllerTest() : task_runner_(base::SequencedTaskRunnerHandle::Get()) { 231 ImageControllerTest() : task_runner_(base::SequencedTaskRunnerHandle::Get()) {
221 bitmap_.allocN32Pixels(1, 1); 232 image_ = CreateDiscardableImage(gfx::Size(1, 1));
222 image_ = SkImage::MakeFromBitmap(bitmap_);
223 } 233 }
224 ~ImageControllerTest() override = default; 234 ~ImageControllerTest() override = default;
225 235
226 void SetUp() override { 236 void SetUp() override {
227 worker_task_runner_ = make_scoped_refptr(new WorkerTaskRunner); 237 worker_task_runner_ = make_scoped_refptr(new WorkerTaskRunner);
228 controller_.reset( 238 controller_.reset(
229 new ImageController(task_runner_.get(), worker_task_runner_)); 239 new ImageController(task_runner_.get(), worker_task_runner_));
230 cache_ = TestableCache(); 240 cache_ = TestableCache();
231 controller_->SetImageDecodeCache(&cache_); 241 controller_->SetImageDecodeCache(&cache_);
232 } 242 }
(...skipping 21 matching lines...) Expand all
254 base::Bind(&ImageControllerTest::Timeout, base::Unretained(run_loop)), 264 base::Bind(&ImageControllerTest::Timeout, base::Unretained(run_loop)),
255 base::TimeDelta::FromSeconds(kDefaultTimeoutSeconds)); 265 base::TimeDelta::FromSeconds(kDefaultTimeoutSeconds));
256 run_loop->Run(); 266 run_loop->Run();
257 } 267 }
258 268
259 private: 269 private:
260 scoped_refptr<base::SequencedTaskRunner> task_runner_; 270 scoped_refptr<base::SequencedTaskRunner> task_runner_;
261 scoped_refptr<WorkerTaskRunner> worker_task_runner_; 271 scoped_refptr<WorkerTaskRunner> worker_task_runner_;
262 TestableCache cache_; 272 TestableCache cache_;
263 std::unique_ptr<ImageController> controller_; 273 std::unique_ptr<ImageController> controller_;
264 SkBitmap bitmap_;
265 sk_sp<const SkImage> image_; 274 sk_sp<const SkImage> image_;
266 }; 275 };
267 276
268 TEST_F(ImageControllerTest, NullControllerUnrefsImages) { 277 TEST_F(ImageControllerTest, NullControllerUnrefsImages) {
269 std::vector<DrawImage> images(10); 278 std::vector<DrawImage> images(10);
270 ImageDecodeCache::TracingInfo tracing_info; 279 ImageDecodeCache::TracingInfo tracing_info;
271 280
272 ASSERT_EQ(10u, images.size()); 281 ASSERT_EQ(10u, images.size());
273 auto tasks = 282 auto tasks =
274 controller()->SetPredecodeImages(std::move(images), tracing_info); 283 controller()->SetPredecodeImages(std::move(images), tracing_info);
275 EXPECT_EQ(0u, tasks.size()); 284 EXPECT_EQ(0u, tasks.size());
276 EXPECT_EQ(10, cache()->number_of_refs()); 285 EXPECT_EQ(10, cache()->number_of_refs());
277 286
278 controller()->SetImageDecodeCache(nullptr); 287 controller()->SetImageDecodeCache(nullptr);
279 EXPECT_EQ(0, cache()->number_of_refs()); 288 EXPECT_EQ(0, cache()->number_of_refs());
280 } 289 }
281 290
282 TEST_F(ImageControllerTest, QueueImageDecode) { 291 TEST_F(ImageControllerTest, QueueImageDecode) {
283 base::RunLoop run_loop; 292 base::RunLoop run_loop;
284 DecodeClient decode_client; 293 DecodeClient decode_client;
285 EXPECT_EQ(image()->bounds().width(), 1); 294 EXPECT_EQ(image()->bounds().width(), 1);
286 ImageController::ImageDecodeRequestId expected_id = 295 ImageController::ImageDecodeRequestId expected_id =
287 controller()->QueueImageDecode( 296 controller()->QueueImageDecode(
288 image(), 297 image(),
289 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client), 298 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
290 run_loop.QuitClosure())); 299 run_loop.QuitClosure()));
291 RunOrTimeout(&run_loop); 300 RunOrTimeout(&run_loop);
292 EXPECT_EQ(expected_id, decode_client.id()); 301 EXPECT_EQ(expected_id, decode_client.id());
302 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
303 decode_client.result());
304 }
305
306 TEST_F(ImageControllerTest, QueueImageDecodeNonLazy) {
307 base::RunLoop run_loop;
308 DecodeClient decode_client;
309
310 SkBitmap bitmap;
311 bitmap.allocN32Pixels(1, 1);
312 sk_sp<const SkImage> image = SkImage::MakeFromBitmap(bitmap);
313
314 ImageController::ImageDecodeRequestId expected_id =
315 controller()->QueueImageDecode(
316 image,
317 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
318 run_loop.QuitClosure()));
319 RunOrTimeout(&run_loop);
320 EXPECT_EQ(expected_id, decode_client.id());
321 EXPECT_EQ(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED,
322 decode_client.result());
323 }
324
325 TEST_F(ImageControllerTest, QueueImageDecodeTooLarge) {
326 base::RunLoop run_loop;
327 DecodeClient decode_client;
328
329 sk_sp<const SkImage> image = CreateDiscardableImage(gfx::Size(2000, 2000));
330 ImageController::ImageDecodeRequestId expected_id =
331 controller()->QueueImageDecode(
332 image,
333 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client),
334 run_loop.QuitClosure()));
335 RunOrTimeout(&run_loop);
336 EXPECT_EQ(expected_id, decode_client.id());
337 EXPECT_EQ(ImageController::ImageDecodeResult::FAILURE,
338 decode_client.result());
293 } 339 }
294 340
295 TEST_F(ImageControllerTest, QueueImageDecodeMultipleImages) { 341 TEST_F(ImageControllerTest, QueueImageDecodeMultipleImages) {
296 base::RunLoop run_loop; 342 base::RunLoop run_loop;
297 DecodeClient decode_client1; 343 DecodeClient decode_client1;
298 ImageController::ImageDecodeRequestId expected_id1 = 344 ImageController::ImageDecodeRequestId expected_id1 =
299 controller()->QueueImageDecode( 345 controller()->QueueImageDecode(
300 image(), 346 image(),
301 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1), 347 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client1),
302 base::Bind([] {}))); 348 base::Bind([] {})));
303 DecodeClient decode_client2; 349 DecodeClient decode_client2;
304 ImageController::ImageDecodeRequestId expected_id2 = 350 ImageController::ImageDecodeRequestId expected_id2 =
305 controller()->QueueImageDecode( 351 controller()->QueueImageDecode(
306 image(), 352 image(),
307 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2), 353 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
308 base::Bind([] {}))); 354 base::Bind([] {})));
309 DecodeClient decode_client3; 355 DecodeClient decode_client3;
310 ImageController::ImageDecodeRequestId expected_id3 = 356 ImageController::ImageDecodeRequestId expected_id3 =
311 controller()->QueueImageDecode( 357 controller()->QueueImageDecode(
312 image(), 358 image(),
313 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client3), 359 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client3),
314 run_loop.QuitClosure())); 360 run_loop.QuitClosure()));
315 RunOrTimeout(&run_loop); 361 RunOrTimeout(&run_loop);
316 EXPECT_EQ(expected_id1, decode_client1.id()); 362 EXPECT_EQ(expected_id1, decode_client1.id());
363 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
364 decode_client1.result());
317 EXPECT_EQ(expected_id2, decode_client2.id()); 365 EXPECT_EQ(expected_id2, decode_client2.id());
366 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
367 decode_client2.result());
318 EXPECT_EQ(expected_id3, decode_client3.id()); 368 EXPECT_EQ(expected_id3, decode_client3.id());
369 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
370 decode_client3.result());
319 } 371 }
320 372
321 TEST_F(ImageControllerTest, QueueImageDecodeWithTask) { 373 TEST_F(ImageControllerTest, QueueImageDecodeWithTask) {
322 scoped_refptr<SimpleTask> task(new SimpleTask); 374 scoped_refptr<SimpleTask> task(new SimpleTask);
323 cache()->SetTaskToUse(task); 375 cache()->SetTaskToUse(task);
324 376
325 base::RunLoop run_loop; 377 base::RunLoop run_loop;
326 DecodeClient decode_client; 378 DecodeClient decode_client;
327 ImageController::ImageDecodeRequestId expected_id = 379 ImageController::ImageDecodeRequestId expected_id =
328 controller()->QueueImageDecode( 380 controller()->QueueImageDecode(
(...skipping 24 matching lines...) Expand all
353 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2), 405 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
354 base::Bind([] {}))); 406 base::Bind([] {})));
355 DecodeClient decode_client3; 407 DecodeClient decode_client3;
356 ImageController::ImageDecodeRequestId expected_id3 = 408 ImageController::ImageDecodeRequestId expected_id3 =
357 controller()->QueueImageDecode( 409 controller()->QueueImageDecode(
358 image(), 410 image(),
359 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client3), 411 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client3),
360 run_loop.QuitClosure())); 412 run_loop.QuitClosure()));
361 RunOrTimeout(&run_loop); 413 RunOrTimeout(&run_loop);
362 EXPECT_EQ(expected_id1, decode_client1.id()); 414 EXPECT_EQ(expected_id1, decode_client1.id());
415 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
416 decode_client1.result());
363 EXPECT_EQ(expected_id2, decode_client2.id()); 417 EXPECT_EQ(expected_id2, decode_client2.id());
418 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
419 decode_client2.result());
364 EXPECT_EQ(expected_id3, decode_client3.id()); 420 EXPECT_EQ(expected_id3, decode_client3.id());
421 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
422 decode_client3.result());
365 EXPECT_TRUE(task->has_run()); 423 EXPECT_TRUE(task->has_run());
366 EXPECT_TRUE(task->HasCompleted()); 424 EXPECT_TRUE(task->HasCompleted());
367 } 425 }
368 426
369 TEST_F(ImageControllerTest, QueueImageDecodeChangeControllerWithTaskQueued) { 427 TEST_F(ImageControllerTest, QueueImageDecodeChangeControllerWithTaskQueued) {
370 scoped_refptr<BlockingTask> task_one(new BlockingTask); 428 scoped_refptr<BlockingTask> task_one(new BlockingTask);
371 cache()->SetTaskToUse(task_one); 429 cache()->SetTaskToUse(task_one);
372 430
373 DecodeClient decode_client1; 431 DecodeClient decode_client1;
374 ImageController::ImageDecodeRequestId expected_id1 = 432 ImageController::ImageDecodeRequestId expected_id1 =
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 cache()->SetTaskToUse(nullptr); 476 cache()->SetTaskToUse(nullptr);
419 base::RunLoop run_loop2; 477 base::RunLoop run_loop2;
420 DecodeClient decode_client2; 478 DecodeClient decode_client2;
421 ImageController::ImageDecodeRequestId expected_id2 = 479 ImageController::ImageDecodeRequestId expected_id2 =
422 controller()->QueueImageDecode( 480 controller()->QueueImageDecode(
423 image(), 481 image(),
424 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2), 482 base::Bind(&DecodeClient::Callback, base::Unretained(&decode_client2),
425 run_loop2.QuitClosure())); 483 run_loop2.QuitClosure()));
426 RunOrTimeout(&run_loop2); 484 RunOrTimeout(&run_loop2);
427 EXPECT_EQ(expected_id2, decode_client2.id()); 485 EXPECT_EQ(expected_id2, decode_client2.id());
486 EXPECT_EQ(ImageController::ImageDecodeResult::SUCCESS,
487 decode_client2.result());
428 } 488 }
429 489
430 TEST_F(ImageControllerTest, QueueImageDecodeLockedImageControllerChange) { 490 TEST_F(ImageControllerTest, QueueImageDecodeLockedImageControllerChange) {
431 scoped_refptr<SimpleTask> task(new SimpleTask); 491 scoped_refptr<SimpleTask> task(new SimpleTask);
432 cache()->SetTaskToUse(task); 492 cache()->SetTaskToUse(task);
433 493
434 base::RunLoop run_loop1; 494 base::RunLoop run_loop1;
435 DecodeClient decode_client1; 495 DecodeClient decode_client1;
436 ImageController::ImageDecodeRequestId expected_id1 = 496 ImageController::ImageDecodeRequestId expected_id1 =
437 controller()->QueueImageDecode( 497 controller()->QueueImageDecode(
(...skipping 30 matching lines...) Expand all
468 // Now reset the image cache before decode completed callbacks are posted to 528 // Now reset the image cache before decode completed callbacks are posted to
469 // the compositor thread. Ensure that the completion callbacks for the decode 529 // the compositor thread. Ensure that the completion callbacks for the decode
470 // is still run. 530 // is still run.
471 controller()->SetImageDecodeCache(nullptr); 531 controller()->SetImageDecodeCache(nullptr);
472 RunOrTimeout(&run_loop1); 532 RunOrTimeout(&run_loop1);
473 RunOrTimeout(&run_loop2); 533 RunOrTimeout(&run_loop2);
474 } 534 }
475 535
476 } // namespace 536 } // namespace
477 } // namespace cc 537 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/image_controller.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698