[go: nahoru, domu]

blob: 71bc0630400feb379d5b5c5d296a39369313129e [file] [log] [blame]
ericrkd2ff2a132016-04-11 22:16:001// Copyright 2016 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/gpu_image_decode_controller.h"
6
7#include "cc/playback/draw_image.h"
8#include "cc/raster/tile_task_runner.h"
9#include "cc/test/test_context_provider.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace cc {
13namespace {
14
15skia::RefPtr<SkImage> CreateImage(int width, int height) {
16 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
17 SkBitmap bitmap;
18 bitmap.allocPixels(info);
19 return skia::AdoptRef(SkImage::NewFromBitmap(bitmap));
20}
21
22SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
23 SkMatrix matrix;
24 matrix.setScale(scale.width(), scale.height());
25
26 if (!is_decomposable) {
27 // Perspective is not decomposable, add it.
28 matrix[SkMatrix::kMPersp0] = 0.1f;
29 }
30
31 return matrix;
32}
33
prashant.n49b3e64652016-04-19 07:04:4934void ScheduleTask(TileTask* task) {
ericrkd2ff2a132016-04-11 22:16:0035 task->WillSchedule();
36 task->ScheduleOnOriginThread(nullptr);
37 task->DidSchedule();
38}
39
prashant.n49b3e64652016-04-19 07:04:4940void RunTask(TileTask* task) {
ericrkd2ff2a132016-04-11 22:16:0041 task->WillRun();
42 task->RunOnWorkerThread();
43 task->DidRun();
44}
45
prashant.n49b3e64652016-04-19 07:04:4946void CompleteTask(TileTask* task) {
ericrkd2ff2a132016-04-11 22:16:0047 task->WillComplete();
48 task->CompleteOnOriginThread(nullptr);
49 task->DidComplete();
50}
51
prashant.n49b3e64652016-04-19 07:04:4952void ProcessTask(TileTask* task) {
ericrkd2ff2a132016-04-11 22:16:0053 ScheduleTask(task);
54 RunTask(task);
55 CompleteTask(task);
56}
57
58TEST(GpuImageDecodeControllerTest, GetTaskForImageSameImage) {
59 auto context_provider = TestContextProvider::Create();
60 context_provider->BindToCurrentThread();
61 GpuImageDecodeController controller(context_provider.get(),
62 ResourceFormat::RGBA_8888);
63 skia::RefPtr<SkImage> image = CreateImage(100, 100);
64 bool is_decomposable = true;
65 SkFilterQuality quality = kHigh_SkFilterQuality;
66 uint64_t prepare_tiles_id = 1;
67
68 DrawImage draw_image(
69 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
70 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:4971 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:0072 bool need_unref =
73 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
74 EXPECT_TRUE(need_unref);
75 EXPECT_TRUE(task);
76
77 DrawImage another_draw_image(
78 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
79 CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:4980 scoped_refptr<TileTask> another_task;
ericrkd2ff2a132016-04-11 22:16:0081 need_unref = controller.GetTaskForImageAndRef(
82 another_draw_image, prepare_tiles_id, &another_task);
83 EXPECT_TRUE(need_unref);
84 EXPECT_TRUE(task.get() == another_task.get());
85
prashant.n49b3e64652016-04-19 07:04:4986 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:0087 ProcessTask(task.get());
88
89 controller.UnrefImage(draw_image);
90 controller.UnrefImage(draw_image);
91}
92
93TEST(GpuImageDecodeControllerTest, GetTaskForImageDifferentImage) {
94 auto context_provider = TestContextProvider::Create();
95 context_provider->BindToCurrentThread();
96 GpuImageDecodeController controller(context_provider.get(),
97 ResourceFormat::RGBA_8888);
98 bool is_decomposable = true;
99 uint64_t prepare_tiles_id = 1;
100 SkFilterQuality quality = kHigh_SkFilterQuality;
101
102 skia::RefPtr<SkImage> first_image = CreateImage(100, 100);
103 DrawImage first_draw_image(
104 first_image.get(),
105 SkIRect::MakeWH(first_image->width(), first_image->height()), quality,
106 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49107 scoped_refptr<TileTask> first_task;
ericrkd2ff2a132016-04-11 22:16:00108 bool need_unref = controller.GetTaskForImageAndRef(
109 first_draw_image, prepare_tiles_id, &first_task);
110 EXPECT_TRUE(need_unref);
111 EXPECT_TRUE(first_task);
112
113 skia::RefPtr<SkImage> second_image = CreateImage(100, 100);
114 DrawImage second_draw_image(
115 second_image.get(),
116 SkIRect::MakeWH(second_image->width(), second_image->height()), quality,
117 CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49118 scoped_refptr<TileTask> second_task;
ericrkd2ff2a132016-04-11 22:16:00119 need_unref = controller.GetTaskForImageAndRef(second_draw_image,
120 prepare_tiles_id, &second_task);
121 EXPECT_TRUE(need_unref);
122 EXPECT_TRUE(second_task);
123 EXPECT_TRUE(first_task.get() != second_task.get());
124
prashant.n49b3e64652016-04-19 07:04:49125 ProcessTask(first_task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00126 ProcessTask(first_task.get());
prashant.n49b3e64652016-04-19 07:04:49127 ProcessTask(second_task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00128 ProcessTask(second_task.get());
129
130 controller.UnrefImage(first_draw_image);
131 controller.UnrefImage(second_draw_image);
132}
133
134TEST(GpuImageDecodeControllerTest, GetTaskForImageAlreadyDecoded) {
135 auto context_provider = TestContextProvider::Create();
136 context_provider->BindToCurrentThread();
137 GpuImageDecodeController controller(context_provider.get(),
138 ResourceFormat::RGBA_8888);
139 bool is_decomposable = true;
140 uint64_t prepare_tiles_id = 1;
141 SkFilterQuality quality = kHigh_SkFilterQuality;
142
143 skia::RefPtr<SkImage> image = CreateImage(100, 100);
144 DrawImage draw_image(
145 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
146 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49147 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00148 bool need_unref =
149 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
150 EXPECT_TRUE(need_unref);
151 EXPECT_TRUE(task);
prashant.n49b3e64652016-04-19 07:04:49152 EXPECT_EQ(task->dependencies().size(), 1u);
153 EXPECT_TRUE(task->dependencies()[0]);
ericrkd2ff2a132016-04-11 22:16:00154
prashant.n49b3e64652016-04-19 07:04:49155 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00156 ScheduleTask(task.get());
157 RunTask(task.get());
158
prashant.n49b3e64652016-04-19 07:04:49159 scoped_refptr<TileTask> another_task;
ericrkd2ff2a132016-04-11 22:16:00160 need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
161 &another_task);
162 EXPECT_TRUE(need_unref);
163 EXPECT_FALSE(another_task);
164
165 CompleteTask(task.get());
166
167 controller.UnrefImage(draw_image);
168 controller.UnrefImage(draw_image);
169}
170
171TEST(GpuImageDecodeControllerTest, GetTaskForImageCanceledGetsNewTask) {
172 auto context_provider = TestContextProvider::Create();
173 context_provider->BindToCurrentThread();
174 GpuImageDecodeController controller(context_provider.get(),
175 ResourceFormat::RGBA_8888);
176 bool is_decomposable = true;
177 uint64_t prepare_tiles_id = 1;
178 SkFilterQuality quality = kHigh_SkFilterQuality;
179
180 skia::RefPtr<SkImage> image = CreateImage(100, 100);
181 DrawImage draw_image(
182 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
183 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49184 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00185 bool need_unref =
186 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
187 EXPECT_TRUE(need_unref);
188 EXPECT_TRUE(task);
189
prashant.n49b3e64652016-04-19 07:04:49190 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00191 ScheduleTask(task.get());
192
prashant.n49b3e64652016-04-19 07:04:49193 scoped_refptr<TileTask> another_task;
ericrkd2ff2a132016-04-11 22:16:00194 need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
195 &another_task);
196 EXPECT_TRUE(need_unref);
197 EXPECT_TRUE(another_task.get() == task.get());
198
199 // Didn't run the task, complete it (it was canceled).
200 CompleteTask(task.get());
201
202 // Fully cancel everything (so the raster would unref things).
203 controller.UnrefImage(draw_image);
204 controller.UnrefImage(draw_image);
205
206 // Here a new task is created.
prashant.n49b3e64652016-04-19 07:04:49207 scoped_refptr<TileTask> third_task;
ericrkd2ff2a132016-04-11 22:16:00208 need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
209 &third_task);
210 EXPECT_TRUE(need_unref);
211 EXPECT_TRUE(third_task);
212 EXPECT_FALSE(third_task.get() == task.get());
213
prashant.n49b3e64652016-04-19 07:04:49214 ProcessTask(third_task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00215 ProcessTask(third_task.get());
216
217 controller.UnrefImage(draw_image);
218}
219
220TEST(GpuImageDecodeControllerTest,
221 GetTaskForImageCanceledWhileReffedGetsNewTask) {
222 auto context_provider = TestContextProvider::Create();
223 context_provider->BindToCurrentThread();
224 GpuImageDecodeController controller(context_provider.get(),
225 ResourceFormat::RGBA_8888);
226 bool is_decomposable = true;
227 uint64_t prepare_tiles_id = 1;
228 SkFilterQuality quality = kHigh_SkFilterQuality;
229
230 skia::RefPtr<SkImage> image = CreateImage(100, 100);
231 DrawImage draw_image(
232 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
233 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49234 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00235 bool need_unref =
236 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
237 EXPECT_TRUE(need_unref);
238 EXPECT_TRUE(task);
239
prashant.n49b3e64652016-04-19 07:04:49240 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00241 ScheduleTask(task.get());
242
prashant.n49b3e64652016-04-19 07:04:49243 scoped_refptr<TileTask> another_task;
ericrkd2ff2a132016-04-11 22:16:00244 need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
245 &another_task);
246 EXPECT_TRUE(need_unref);
247 EXPECT_TRUE(another_task.get() == task.get());
248
249 // Didn't run the task, complete it (it was canceled).
250 CompleteTask(task.get());
251
252 // Note that here, everything is reffed, but a new task is created. This is
253 // possible with repeated schedule/cancel operations.
prashant.n49b3e64652016-04-19 07:04:49254 scoped_refptr<TileTask> third_task;
ericrkd2ff2a132016-04-11 22:16:00255 need_unref = controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id,
256 &third_task);
257 EXPECT_TRUE(need_unref);
258 EXPECT_TRUE(third_task);
259 EXPECT_FALSE(third_task.get() == task.get());
260
prashant.n49b3e64652016-04-19 07:04:49261 ProcessTask(third_task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00262 ProcessTask(third_task.get());
263
264 // 3 Unrefs!
265 controller.UnrefImage(draw_image);
266 controller.UnrefImage(draw_image);
267 controller.UnrefImage(draw_image);
268}
269
270TEST(GpuImageDecodeControllerTest, GetDecodedImageForDraw) {
271 auto context_provider = TestContextProvider::Create();
272 context_provider->BindToCurrentThread();
273 GpuImageDecodeController controller(context_provider.get(),
274 ResourceFormat::RGBA_8888);
275 bool is_decomposable = true;
276 uint64_t prepare_tiles_id = 1;
277 SkFilterQuality quality = kHigh_SkFilterQuality;
278
279 skia::RefPtr<SkImage> image = CreateImage(100, 100);
280 DrawImage draw_image(
281 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
282 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49283 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00284 bool need_unref =
285 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
286 EXPECT_TRUE(need_unref);
287 EXPECT_TRUE(task);
288
prashant.n49b3e64652016-04-19 07:04:49289 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00290 ProcessTask(task.get());
291
292 // Must hold context lock before calling GetDecodedImageForDraw /
293 // DrawWithImageFinished.
294 ContextProvider::ScopedContextLock context_lock(context_provider.get());
295 DecodedDrawImage decoded_draw_image =
296 controller.GetDecodedImageForDraw(draw_image);
297 EXPECT_TRUE(decoded_draw_image.image());
298 EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
299 EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
300
301 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
302 controller.UnrefImage(draw_image);
303}
304
305TEST(GpuImageDecodeControllerTest, GetLargeDecodedImageForDraw) {
306 auto context_provider = TestContextProvider::Create();
307 context_provider->BindToCurrentThread();
308 GpuImageDecodeController controller(context_provider.get(),
309 ResourceFormat::RGBA_8888);
310 bool is_decomposable = true;
311 uint64_t prepare_tiles_id = 1;
312 SkFilterQuality quality = kHigh_SkFilterQuality;
313
314 skia::RefPtr<SkImage> image = CreateImage(1, 24000);
315 DrawImage draw_image(
316 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
317 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49318 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00319 bool need_unref =
320 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
321 EXPECT_TRUE(need_unref);
322 EXPECT_TRUE(task);
323
prashant.n49b3e64652016-04-19 07:04:49324 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00325 ProcessTask(task.get());
326
327 // Must hold context lock before calling GetDecodedImageForDraw /
328 // DrawWithImageFinished.
329 ContextProvider::ScopedContextLock context_lock(context_provider.get());
330 DecodedDrawImage decoded_draw_image =
331 controller.GetDecodedImageForDraw(draw_image);
332 EXPECT_TRUE(decoded_draw_image.image());
333 EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
334 EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
335
336 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
337 controller.UnrefImage(draw_image);
338}
339
340TEST(GpuImageDecodeControllerTest, GetDecodedImageForDrawAtRasterDecode) {
341 auto context_provider = TestContextProvider::Create();
342 context_provider->BindToCurrentThread();
343 GpuImageDecodeController controller(context_provider.get(),
344 ResourceFormat::RGBA_8888);
345 bool is_decomposable = true;
346 uint64_t prepare_tiles_id = 1;
347 SkFilterQuality quality = kHigh_SkFilterQuality;
348
349 controller.SetCachedItemLimitForTesting(0);
350 controller.SetCachedBytesLimitForTesting(0);
351
352 skia::RefPtr<SkImage> image = CreateImage(100, 100);
353 DrawImage draw_image(
354 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
355 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
356
prashant.n49b3e64652016-04-19 07:04:49357 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00358 bool need_unref =
359 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
360 EXPECT_FALSE(need_unref);
361 EXPECT_FALSE(task);
362
363 // Must hold context lock before calling GetDecodedImageForDraw /
364 // DrawWithImageFinished.
365 ContextProvider::ScopedContextLock context_lock(context_provider.get());
366 DecodedDrawImage decoded_draw_image =
367 controller.GetDecodedImageForDraw(draw_image);
368 EXPECT_TRUE(decoded_draw_image.image());
369 EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
370 EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
371
372 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
373}
374
375TEST(GpuImageDecodeControllerTest, AtRasterUsedDirectlyIfSpaceAllows) {
376 auto context_provider = TestContextProvider::Create();
377 context_provider->BindToCurrentThread();
378 GpuImageDecodeController controller(context_provider.get(),
379 ResourceFormat::RGBA_8888);
380 bool is_decomposable = true;
381 uint64_t prepare_tiles_id = 1;
382 SkFilterQuality quality = kHigh_SkFilterQuality;
383
384 controller.SetCachedItemLimitForTesting(0);
385 controller.SetCachedBytesLimitForTesting(0);
386
387 skia::RefPtr<SkImage> image = CreateImage(100, 100);
388 DrawImage draw_image(
389 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
390 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
391
prashant.n49b3e64652016-04-19 07:04:49392 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00393 bool need_unref =
394 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
395 EXPECT_FALSE(need_unref);
396 EXPECT_FALSE(task);
397
398 // Must hold context lock before calling GetDecodedImageForDraw /
399 // DrawWithImageFinished.
400 ContextProvider::ScopedContextLock context_lock(context_provider.get());
401 DecodedDrawImage decoded_draw_image =
402 controller.GetDecodedImageForDraw(draw_image);
403 EXPECT_TRUE(decoded_draw_image.image());
404 EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
405 EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
406
407 controller.SetCachedItemLimitForTesting(1000);
408 controller.SetCachedBytesLimitForTesting(96 * 1024 * 1024);
409
410 // Finish our draw after increasing the memory limit, image should be added to
411 // cache.
412 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
413
prashant.n49b3e64652016-04-19 07:04:49414 scoped_refptr<TileTask> another_task;
ericrkd2ff2a132016-04-11 22:16:00415 bool another_task_needs_unref =
416 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
417 EXPECT_TRUE(another_task_needs_unref);
418 EXPECT_FALSE(another_task);
419 controller.UnrefImage(draw_image);
420}
421
422TEST(GpuImageDecodeControllerTest,
423 GetDecodedImageForDrawAtRasterDecodeMultipleTimes) {
424 auto context_provider = TestContextProvider::Create();
425 context_provider->BindToCurrentThread();
426 GpuImageDecodeController controller(context_provider.get(),
427 ResourceFormat::RGBA_8888);
428 bool is_decomposable = true;
429 SkFilterQuality quality = kHigh_SkFilterQuality;
430
431 controller.SetCachedItemLimitForTesting(0);
432 controller.SetCachedBytesLimitForTesting(0);
433
434 skia::RefPtr<SkImage> image = CreateImage(100, 100);
435 DrawImage draw_image(
436 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
437 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
438
439 // Must hold context lock before calling GetDecodedImageForDraw /
440 // DrawWithImageFinished.
441 ContextProvider::ScopedContextLock context_lock(context_provider.get());
442 DecodedDrawImage decoded_draw_image =
443 controller.GetDecodedImageForDraw(draw_image);
444 EXPECT_TRUE(decoded_draw_image.image());
445 EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
446 EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
447
448 DecodedDrawImage another_decoded_draw_image =
449 controller.GetDecodedImageForDraw(draw_image);
450 EXPECT_EQ(decoded_draw_image.image()->uniqueID(),
451 another_decoded_draw_image.image()->uniqueID());
452
453 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
454 controller.DrawWithImageFinished(draw_image, another_decoded_draw_image);
455}
456
457TEST(GpuImageDecodeControllerTest, ZeroSizedImagesAreSkipped) {
458 auto context_provider = TestContextProvider::Create();
459 context_provider->BindToCurrentThread();
460 GpuImageDecodeController controller(context_provider.get(),
461 ResourceFormat::RGBA_8888);
462 bool is_decomposable = true;
463 uint64_t prepare_tiles_id = 1;
464 SkFilterQuality quality = kHigh_SkFilterQuality;
465
466 skia::RefPtr<SkImage> image = CreateImage(100, 100);
467 DrawImage draw_image(
468 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
469 CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable));
470
prashant.n49b3e64652016-04-19 07:04:49471 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00472 bool need_unref =
473 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
474 EXPECT_FALSE(task);
475 EXPECT_FALSE(need_unref);
476
477 // Must hold context lock before calling GetDecodedImageForDraw /
478 // DrawWithImageFinished.
479 ContextProvider::ScopedContextLock context_lock(context_provider.get());
480 DecodedDrawImage decoded_draw_image =
481 controller.GetDecodedImageForDraw(draw_image);
482 EXPECT_FALSE(decoded_draw_image.image());
483
484 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
485}
486
487TEST(GpuImageDecodeControllerTest, NonOverlappingSrcRectImagesAreSkipped) {
488 auto context_provider = TestContextProvider::Create();
489 context_provider->BindToCurrentThread();
490 GpuImageDecodeController controller(context_provider.get(),
491 ResourceFormat::RGBA_8888);
492 bool is_decomposable = true;
493 uint64_t prepare_tiles_id = 1;
494 SkFilterQuality quality = kHigh_SkFilterQuality;
495
496 skia::RefPtr<SkImage> image = CreateImage(100, 100);
497 DrawImage draw_image(
498 image.get(), SkIRect::MakeXYWH(150, 150, image->width(), image->height()),
499 quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable));
500
prashant.n49b3e64652016-04-19 07:04:49501 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00502 bool need_unref =
503 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
504 EXPECT_FALSE(task);
505 EXPECT_FALSE(need_unref);
506
507 // Must hold context lock before calling GetDecodedImageForDraw /
508 // DrawWithImageFinished.
509 ContextProvider::ScopedContextLock context_lock(context_provider.get());
510 DecodedDrawImage decoded_draw_image =
511 controller.GetDecodedImageForDraw(draw_image);
512 EXPECT_FALSE(decoded_draw_image.image());
513
514 controller.DrawWithImageFinished(draw_image, decoded_draw_image);
515}
516
517TEST(GpuImageDecodeControllerTest, CanceledTasksDoNotCountAgainstBudget) {
518 auto context_provider = TestContextProvider::Create();
519 context_provider->BindToCurrentThread();
520 GpuImageDecodeController controller(context_provider.get(),
521 ResourceFormat::RGBA_8888);
522 bool is_decomposable = true;
523 uint64_t prepare_tiles_id = 1;
524 SkFilterQuality quality = kHigh_SkFilterQuality;
525
526 skia::RefPtr<SkImage> image = CreateImage(100, 100);
527 DrawImage draw_image(
528 image.get(), SkIRect::MakeXYWH(0, 0, image->width(), image->height()),
529 quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable));
530
prashant.n49b3e64652016-04-19 07:04:49531 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00532 bool need_unref =
533 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
534 EXPECT_NE(0u, controller.GetBytesUsedForTesting());
535 EXPECT_TRUE(task);
536 EXPECT_TRUE(need_unref);
537
prashant.n49b3e64652016-04-19 07:04:49538 ScheduleTask(task->dependencies()[0].get());
539 CompleteTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00540 ScheduleTask(task.get());
541 CompleteTask(task.get());
542
543 controller.UnrefImage(draw_image);
544 EXPECT_EQ(0u, controller.GetBytesUsedForTesting());
545}
546
547TEST(GpuImageDecodeControllerTest, ShouldAggressivelyFreeResources) {
548 auto context_provider = TestContextProvider::Create();
549 context_provider->BindToCurrentThread();
550 GpuImageDecodeController controller(context_provider.get(),
551 ResourceFormat::RGBA_8888);
552 bool is_decomposable = true;
553 uint64_t prepare_tiles_id = 1;
554 SkFilterQuality quality = kHigh_SkFilterQuality;
555
556 skia::RefPtr<SkImage> image = CreateImage(100, 100);
557 DrawImage draw_image(
558 image.get(), SkIRect::MakeWH(image->width(), image->height()), quality,
559 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable));
prashant.n49b3e64652016-04-19 07:04:49560 scoped_refptr<TileTask> task;
ericrkd2ff2a132016-04-11 22:16:00561 {
562 bool need_unref =
563 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
564 EXPECT_TRUE(need_unref);
565 EXPECT_TRUE(task);
566 }
567
prashant.n49b3e64652016-04-19 07:04:49568 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00569 ProcessTask(task.get());
570
571 controller.UnrefImage(draw_image);
572
573 // We should now have data image in our cache.
574 DCHECK_GT(controller.GetBytesUsedForTesting(), 0u);
575
576 // Tell our controller to aggressively free resources.
577 controller.SetShouldAggressivelyFreeResources(true);
578 DCHECK_EQ(0u, controller.GetBytesUsedForTesting());
579
580 // Attempting to upload a new image should result in at-raster decode.
581 {
582 bool need_unref =
583 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
584 EXPECT_FALSE(need_unref);
585 EXPECT_FALSE(task);
586 }
587
588 // We now tell the controller to not aggressively free resources. Uploads
589 // should work again.
590 controller.SetShouldAggressivelyFreeResources(false);
591 {
592 bool need_unref =
593 controller.GetTaskForImageAndRef(draw_image, prepare_tiles_id, &task);
594 EXPECT_TRUE(need_unref);
595 EXPECT_TRUE(task);
596 }
597
prashant.n49b3e64652016-04-19 07:04:49598 ProcessTask(task->dependencies()[0].get());
ericrkd2ff2a132016-04-11 22:16:00599 ProcessTask(task.get());
600
601 // The image should be in our cache after un-ref.
602 controller.UnrefImage(draw_image);
603 DCHECK_GT(controller.GetBytesUsedForTesting(), 0u);
604}
605
606} // namespace
607} // namespace cc