OLD | NEW |
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/gpu_image_decode_cache.h" | 5 #include "cc/tiles/gpu_image_decode_cache.h" |
6 | 6 |
7 #include "cc/paint/draw_image.h" | 7 #include "cc/paint/draw_image.h" |
8 #include "cc/test/test_context_provider.h" | 8 #include "cc/test/test_context_provider.h" |
9 #include "cc/test/test_tile_task_runner.h" | 9 #include "cc/test/test_tile_task_runner.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 #include "third_party/skia/include/core/SkRefCnt.h" | 11 #include "third_party/skia/include/core/SkRefCnt.h" |
12 | 12 |
13 namespace cc { | 13 namespace cc { |
14 namespace { | 14 namespace { |
15 | 15 |
16 size_t kGpuMemoryLimitBytes = 96 * 1024 * 1024; | 16 size_t kGpuMemoryLimitBytes = 96 * 1024 * 1024; |
17 class TestGpuImageDecodeCache : public GpuImageDecodeCache { | 17 class TestGpuImageDecodeCache : public GpuImageDecodeCache { |
18 public: | 18 public: |
19 explicit TestGpuImageDecodeCache(ContextProvider* context) | 19 explicit TestGpuImageDecodeCache(ContextProvider* context) |
20 : GpuImageDecodeCache(context, | 20 : GpuImageDecodeCache(context, |
21 ResourceFormat::RGBA_8888, | 21 ResourceFormat::RGBA_8888, |
| 22 kGpuMemoryLimitBytes, |
22 kGpuMemoryLimitBytes) {} | 23 kGpuMemoryLimitBytes) {} |
23 }; | 24 }; |
24 | 25 |
25 sk_sp<SkImage> CreateImage(int width, int height) { | 26 sk_sp<SkImage> CreateImage(int width, int height) { |
26 SkBitmap bitmap; | 27 SkBitmap bitmap; |
27 bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); | 28 bitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); |
28 return SkImage::MakeFromBitmap(bitmap); | 29 return SkImage::MakeFromBitmap(bitmap); |
29 } | 30 } |
30 | 31 |
31 SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) { | 32 SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) { |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image)); | 634 EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image)); |
634 } | 635 } |
635 | 636 |
636 TEST(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) { | 637 TEST(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) { |
637 auto context_provider = TestContextProvider::Create(); | 638 auto context_provider = TestContextProvider::Create(); |
638 context_provider->BindToCurrentThread(); | 639 context_provider->BindToCurrentThread(); |
639 TestGpuImageDecodeCache cache(context_provider.get()); | 640 TestGpuImageDecodeCache cache(context_provider.get()); |
640 bool is_decomposable = true; | 641 bool is_decomposable = true; |
641 SkFilterQuality quality = kHigh_SkFilterQuality; | 642 SkFilterQuality quality = kHigh_SkFilterQuality; |
642 | 643 |
643 cache.SetCachedBytesLimitForTesting(0); | 644 cache.SetAllByteLimitsForTesting(0); |
644 | 645 |
645 sk_sp<SkImage> image = CreateImage(100, 100); | 646 sk_sp<SkImage> image = CreateImage(100, 100); |
646 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), | 647 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), |
647 quality, | 648 quality, |
648 CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable)); | 649 CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable)); |
649 | 650 |
650 scoped_refptr<TileTask> task; | 651 scoped_refptr<TileTask> task; |
651 bool need_unref = cache.GetTaskForImageAndRef( | 652 bool need_unref = cache.GetTaskForImageAndRef( |
652 draw_image, ImageDecodeCache::TracingInfo(), &task); | 653 draw_image, ImageDecodeCache::TracingInfo(), &task); |
653 EXPECT_FALSE(need_unref); | 654 EXPECT_FALSE(need_unref); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image)); | 855 EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image)); |
855 } | 856 } |
856 | 857 |
857 TEST(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) { | 858 TEST(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) { |
858 auto context_provider = TestContextProvider::Create(); | 859 auto context_provider = TestContextProvider::Create(); |
859 context_provider->BindToCurrentThread(); | 860 context_provider->BindToCurrentThread(); |
860 TestGpuImageDecodeCache cache(context_provider.get()); | 861 TestGpuImageDecodeCache cache(context_provider.get()); |
861 bool is_decomposable = true; | 862 bool is_decomposable = true; |
862 SkFilterQuality quality = kHigh_SkFilterQuality; | 863 SkFilterQuality quality = kHigh_SkFilterQuality; |
863 | 864 |
864 cache.SetCachedBytesLimitForTesting(0); | 865 cache.SetAllByteLimitsForTesting(0); |
865 | 866 |
866 sk_sp<SkImage> image = CreateImage(100, 100); | 867 sk_sp<SkImage> image = CreateImage(100, 100); |
867 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), | 868 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), |
868 quality, | 869 quality, |
869 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); | 870 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); |
870 | 871 |
871 scoped_refptr<TileTask> task; | 872 scoped_refptr<TileTask> task; |
872 bool need_unref = cache.GetTaskForImageAndRef( | 873 bool need_unref = cache.GetTaskForImageAndRef( |
873 draw_image, ImageDecodeCache::TracingInfo(), &task); | 874 draw_image, ImageDecodeCache::TracingInfo(), &task); |
874 EXPECT_FALSE(need_unref); | 875 EXPECT_FALSE(need_unref); |
875 EXPECT_FALSE(task); | 876 EXPECT_FALSE(task); |
876 | 877 |
877 // Must hold context lock before calling GetDecodedImageForDraw / | 878 // Must hold context lock before calling GetDecodedImageForDraw / |
878 // DrawWithImageFinished. | 879 // DrawWithImageFinished. |
879 ContextProvider::ScopedContextLock context_lock(context_provider.get()); | 880 ContextProvider::ScopedContextLock context_lock(context_provider.get()); |
880 DecodedDrawImage decoded_draw_image = | 881 DecodedDrawImage decoded_draw_image = |
881 cache.GetDecodedImageForDraw(draw_image); | 882 cache.GetDecodedImageForDraw(draw_image); |
882 EXPECT_TRUE(decoded_draw_image.image()); | 883 EXPECT_TRUE(decoded_draw_image.image()); |
883 EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked()); | 884 EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked()); |
884 EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); | 885 EXPECT_TRUE(decoded_draw_image.is_at_raster_decode()); |
885 EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image)); | 886 EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image)); |
886 | 887 |
887 cache.SetCachedBytesLimitForTesting(96 * 1024 * 1024); | 888 cache.SetAllByteLimitsForTesting(96 * 1024 * 1024); |
888 | 889 |
889 // Finish our draw after increasing the memory limit, image should be added to | 890 // Finish our draw after increasing the memory limit, image should be added to |
890 // cache. | 891 // cache. |
891 cache.DrawWithImageFinished(draw_image, decoded_draw_image); | 892 cache.DrawWithImageFinished(draw_image, decoded_draw_image); |
892 | 893 |
893 scoped_refptr<TileTask> another_task; | 894 scoped_refptr<TileTask> another_task; |
894 bool another_task_needs_unref = cache.GetTaskForImageAndRef( | 895 bool another_task_needs_unref = cache.GetTaskForImageAndRef( |
895 draw_image, ImageDecodeCache::TracingInfo(), &task); | 896 draw_image, ImageDecodeCache::TracingInfo(), &task); |
896 EXPECT_TRUE(another_task_needs_unref); | 897 EXPECT_TRUE(another_task_needs_unref); |
897 EXPECT_FALSE(another_task); | 898 EXPECT_FALSE(another_task); |
898 cache.UnrefImage(draw_image); | 899 cache.UnrefImage(draw_image); |
899 } | 900 } |
900 | 901 |
901 TEST(GpuImageDecodeCacheTest, | 902 TEST(GpuImageDecodeCacheTest, |
902 GetDecodedImageForDrawAtRasterDecodeMultipleTimes) { | 903 GetDecodedImageForDrawAtRasterDecodeMultipleTimes) { |
903 auto context_provider = TestContextProvider::Create(); | 904 auto context_provider = TestContextProvider::Create(); |
904 context_provider->BindToCurrentThread(); | 905 context_provider->BindToCurrentThread(); |
905 TestGpuImageDecodeCache cache(context_provider.get()); | 906 TestGpuImageDecodeCache cache(context_provider.get()); |
906 bool is_decomposable = true; | 907 bool is_decomposable = true; |
907 SkFilterQuality quality = kHigh_SkFilterQuality; | 908 SkFilterQuality quality = kHigh_SkFilterQuality; |
908 | 909 |
909 cache.SetCachedBytesLimitForTesting(0); | 910 cache.SetAllByteLimitsForTesting(0); |
910 | 911 |
911 sk_sp<SkImage> image = CreateImage(100, 100); | 912 sk_sp<SkImage> image = CreateImage(100, 100); |
912 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), | 913 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), |
913 quality, | 914 quality, |
914 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); | 915 CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable)); |
915 | 916 |
916 // Must hold context lock before calling GetDecodedImageForDraw / | 917 // Must hold context lock before calling GetDecodedImageForDraw / |
917 // DrawWithImageFinished. | 918 // DrawWithImageFinished. |
918 ContextProvider::ScopedContextLock context_lock(context_provider.get()); | 919 ContextProvider::ScopedContextLock context_lock(context_provider.get()); |
919 DecodedDrawImage decoded_draw_image = | 920 DecodedDrawImage decoded_draw_image = |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 EXPECT_TRUE(need_unref); | 1072 EXPECT_TRUE(need_unref); |
1072 EXPECT_TRUE(task); | 1073 EXPECT_TRUE(task); |
1073 } | 1074 } |
1074 | 1075 |
1075 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); | 1076 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
1076 TestTileTaskRunner::ProcessTask(task.get()); | 1077 TestTileTaskRunner::ProcessTask(task.get()); |
1077 | 1078 |
1078 cache.UnrefImage(draw_image); | 1079 cache.UnrefImage(draw_image); |
1079 | 1080 |
1080 // We should now have data image in our cache. | 1081 // We should now have data image in our cache. |
1081 DCHECK_GT(cache.GetBytesUsedForTesting(), 0u); | 1082 EXPECT_GT(cache.GetBytesUsedForTesting(), 0u); |
1082 | 1083 |
1083 // Tell our cache to aggressively free resources. | 1084 // Tell our cache to aggressively free resources. |
1084 cache.SetShouldAggressivelyFreeResources(true); | 1085 cache.SetShouldAggressivelyFreeResources(true); |
1085 DCHECK_EQ(0u, cache.GetBytesUsedForTesting()); | 1086 EXPECT_EQ(0u, cache.GetBytesUsedForTesting()); |
1086 | 1087 |
1087 // Attempting to upload a new image should result in at-raster decode. | 1088 // Attempting to upload a new image should succeed, but the image should not |
| 1089 // be cached past its use. |
1088 { | 1090 { |
1089 bool need_unref = cache.GetTaskForImageAndRef( | 1091 bool need_unref = cache.GetTaskForImageAndRef( |
1090 draw_image, ImageDecodeCache::TracingInfo(), &task); | 1092 draw_image, ImageDecodeCache::TracingInfo(), &task); |
1091 EXPECT_FALSE(need_unref); | 1093 EXPECT_TRUE(need_unref); |
1092 EXPECT_FALSE(task); | 1094 EXPECT_TRUE(task); |
| 1095 |
| 1096 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1097 TestTileTaskRunner::ProcessTask(task.get()); |
| 1098 cache.UnrefImage(draw_image); |
| 1099 |
| 1100 EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u); |
1093 } | 1101 } |
1094 | 1102 |
1095 // We now tell the cache to not aggressively free resources. Uploads | 1103 // We now tell the cache to not aggressively free resources. The image may |
1096 // should work again. | 1104 // now be cached past its use. |
1097 cache.SetShouldAggressivelyFreeResources(false); | 1105 cache.SetShouldAggressivelyFreeResources(false); |
1098 { | 1106 { |
1099 bool need_unref = cache.GetTaskForImageAndRef( | 1107 bool need_unref = cache.GetTaskForImageAndRef( |
1100 draw_image, ImageDecodeCache::TracingInfo(), &task); | 1108 draw_image, ImageDecodeCache::TracingInfo(), &task); |
1101 EXPECT_TRUE(need_unref); | 1109 EXPECT_TRUE(need_unref); |
1102 EXPECT_TRUE(task); | 1110 EXPECT_TRUE(task); |
| 1111 |
| 1112 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1113 TestTileTaskRunner::ProcessTask(task.get()); |
| 1114 cache.UnrefImage(draw_image); |
| 1115 |
| 1116 EXPECT_GT(cache.GetBytesUsedForTesting(), 0u); |
1103 } | 1117 } |
1104 | |
1105 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); | |
1106 TestTileTaskRunner::ProcessTask(task.get()); | |
1107 | |
1108 // The image should be in our cache after un-ref. | |
1109 cache.UnrefImage(draw_image); | |
1110 DCHECK_GT(cache.GetBytesUsedForTesting(), 0u); | |
1111 } | 1118 } |
1112 | 1119 |
1113 TEST(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) { | 1120 TEST(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) { |
1114 auto context_provider = TestContextProvider::Create(); | 1121 auto context_provider = TestContextProvider::Create(); |
1115 context_provider->BindToCurrentThread(); | 1122 context_provider->BindToCurrentThread(); |
1116 TestGpuImageDecodeCache cache(context_provider.get()); | 1123 TestGpuImageDecodeCache cache(context_provider.get()); |
1117 bool is_decomposable = true; | 1124 bool is_decomposable = true; |
1118 SkFilterQuality quality = kHigh_SkFilterQuality; | 1125 SkFilterQuality quality = kHigh_SkFilterQuality; |
1119 | 1126 |
1120 // Create a downscaled image. | 1127 // Create a downscaled image. |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 bool need_unref = cache.GetTaskForImageAndRef( | 1326 bool need_unref = cache.GetTaskForImageAndRef( |
1320 draw_image, ImageDecodeCache::TracingInfo(), &task); | 1327 draw_image, ImageDecodeCache::TracingInfo(), &task); |
1321 EXPECT_TRUE(need_unref); | 1328 EXPECT_TRUE(need_unref); |
1322 EXPECT_TRUE(task); | 1329 EXPECT_TRUE(task); |
1323 | 1330 |
1324 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); | 1331 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
1325 TestTileTaskRunner::ProcessTask(task.get()); | 1332 TestTileTaskRunner::ProcessTask(task.get()); |
1326 cache.UnrefImage(draw_image); | 1333 cache.UnrefImage(draw_image); |
1327 | 1334 |
1328 // The image should be cached. | 1335 // The image should be cached. |
1329 DCHECK_GT(cache.GetBytesUsedForTesting(), 0u); | 1336 EXPECT_GT(cache.GetBytesUsedForTesting(), 0u); |
1330 DCHECK_EQ(cache.GetNumCacheEntriesForTesting(), 1u); | 1337 EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 1u); |
1331 | 1338 |
1332 // Set us to the not visible state (prerequisite for SUSPENDED). | 1339 // Set us to the not visible state (prerequisite for SUSPENDED). |
1333 cache.SetShouldAggressivelyFreeResources(true); | 1340 cache.SetShouldAggressivelyFreeResources(true); |
1334 | 1341 |
1335 // Image should be cached, but not using memory budget. | 1342 // Image should be cached, but not using memory budget. |
1336 DCHECK_EQ(cache.GetBytesUsedForTesting(), 0u); | 1343 EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u); |
1337 DCHECK_EQ(cache.GetNumCacheEntriesForTesting(), 1u); | 1344 EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 1u); |
1338 | 1345 |
1339 // Set us to the SUSPENDED state with purging. | 1346 // Set us to the SUSPENDED state with purging. |
1340 cache.OnPurgeMemory(); | 1347 cache.OnPurgeMemory(); |
1341 cache.OnMemoryStateChange(base::MemoryState::SUSPENDED); | 1348 cache.OnMemoryStateChange(base::MemoryState::SUSPENDED); |
1342 | 1349 |
1343 // Nothing should be cached. | 1350 // Nothing should be cached. |
1344 DCHECK_EQ(cache.GetBytesUsedForTesting(), 0u); | 1351 EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u); |
1345 DCHECK_EQ(cache.GetNumCacheEntriesForTesting(), 0u); | 1352 EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 0u); |
1346 | 1353 |
1347 // Attempts to get a task for the image should fail, as we have no space (at | 1354 // Attempts to get a task for the image will still succeed, as SUSPENDED |
1348 // raster only). | 1355 // doesn't impact working set size. |
1349 need_unref = cache.GetTaskForImageAndRef( | 1356 need_unref = cache.GetTaskForImageAndRef( |
1350 draw_image, ImageDecodeCache::TracingInfo(), &task); | 1357 draw_image, ImageDecodeCache::TracingInfo(), &task); |
1351 EXPECT_FALSE(need_unref); | 1358 EXPECT_TRUE(need_unref); |
1352 EXPECT_FALSE(task); | 1359 EXPECT_TRUE(task); |
| 1360 |
| 1361 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1362 TestTileTaskRunner::ProcessTask(task.get()); |
| 1363 cache.UnrefImage(draw_image); |
| 1364 |
| 1365 // Nothing should be cached. |
| 1366 EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u); |
| 1367 EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 0u); |
1353 | 1368 |
1354 // Restore us to visible and NORMAL memory state. | 1369 // Restore us to visible and NORMAL memory state. |
1355 cache.OnMemoryStateChange(base::MemoryState::NORMAL); | 1370 cache.OnMemoryStateChange(base::MemoryState::NORMAL); |
1356 cache.SetShouldAggressivelyFreeResources(false); | 1371 cache.SetShouldAggressivelyFreeResources(false); |
1357 | 1372 |
1358 // We should now be able to create a task again (space available). | 1373 // We should now be able to create a task again (space available). |
1359 need_unref = cache.GetTaskForImageAndRef( | 1374 need_unref = cache.GetTaskForImageAndRef( |
1360 draw_image, ImageDecodeCache::TracingInfo(), &task); | 1375 draw_image, ImageDecodeCache::TracingInfo(), &task); |
1361 EXPECT_TRUE(need_unref); | 1376 EXPECT_TRUE(need_unref); |
1362 EXPECT_TRUE(task); | 1377 EXPECT_TRUE(task); |
(...skipping 22 matching lines...) Expand all Loading... |
1385 EXPECT_TRUE(cache.IsInInUseCacheForTesting(draw_image)); | 1400 EXPECT_TRUE(cache.IsInInUseCacheForTesting(draw_image)); |
1386 | 1401 |
1387 // Run the decode task. | 1402 // Run the decode task. |
1388 TestTileTaskRunner::ProcessTask(task.get()); | 1403 TestTileTaskRunner::ProcessTask(task.get()); |
1389 | 1404 |
1390 // The image should remain in the cache till we unref it. | 1405 // The image should remain in the cache till we unref it. |
1391 EXPECT_TRUE(cache.IsInInUseCacheForTesting(draw_image)); | 1406 EXPECT_TRUE(cache.IsInInUseCacheForTesting(draw_image)); |
1392 cache.UnrefImage(draw_image); | 1407 cache.UnrefImage(draw_image); |
1393 } | 1408 } |
1394 | 1409 |
| 1410 TEST(GpuImageDecodeCacheTest, ZeroCacheNormalWorkingSet) { |
| 1411 // Setup - Image cache has a normal working set, but zero cache size. |
| 1412 auto context_provider = TestContextProvider::Create(); |
| 1413 context_provider->BindToCurrentThread(); |
| 1414 GpuImageDecodeCache cache(context_provider.get(), ResourceFormat::RGBA_8888, |
| 1415 kGpuMemoryLimitBytes, 0); |
| 1416 bool is_decomposable = true; |
| 1417 SkFilterQuality quality = kHigh_SkFilterQuality; |
| 1418 |
| 1419 // Add an image to the cache. Due to normal working set, this should produce |
| 1420 // a task and a ref. |
| 1421 sk_sp<SkImage> image = CreateImage(100, 100); |
| 1422 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), |
| 1423 quality, |
| 1424 CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable)); |
| 1425 scoped_refptr<TileTask> task; |
| 1426 bool need_unref = cache.GetTaskForImageAndRef( |
| 1427 draw_image, ImageDecodeCache::TracingInfo(), &task); |
| 1428 EXPECT_TRUE(need_unref); |
| 1429 EXPECT_TRUE(task); |
| 1430 EXPECT_EQ(task->dependencies().size(), 1u); |
| 1431 EXPECT_TRUE(task->dependencies()[0]); |
| 1432 |
| 1433 // Run the task. |
| 1434 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1435 TestTileTaskRunner::ProcessTask(task.get()); |
| 1436 |
| 1437 // Request the same image - it should be cached. |
| 1438 scoped_refptr<TileTask> task2; |
| 1439 need_unref = cache.GetTaskForImageAndRef( |
| 1440 draw_image, ImageDecodeCache::TracingInfo(), &task2); |
| 1441 EXPECT_TRUE(need_unref); |
| 1442 EXPECT_FALSE(task2); |
| 1443 |
| 1444 // Unref both images. |
| 1445 cache.UnrefImage(draw_image); |
| 1446 cache.UnrefImage(draw_image); |
| 1447 |
| 1448 // Get the image again. As it was fully unreffed, it is no longer in the |
| 1449 // working set and will be evicted due to 0 cache size. |
| 1450 scoped_refptr<TileTask> task3; |
| 1451 need_unref = cache.GetTaskForImageAndRef( |
| 1452 draw_image, ImageDecodeCache::TracingInfo(), &task3); |
| 1453 EXPECT_TRUE(need_unref); |
| 1454 EXPECT_TRUE(task3); |
| 1455 EXPECT_EQ(task3->dependencies().size(), 1u); |
| 1456 EXPECT_TRUE(task->dependencies()[0]); |
| 1457 |
| 1458 TestTileTaskRunner::ProcessTask(task3->dependencies()[0].get()); |
| 1459 TestTileTaskRunner::ProcessTask(task3.get()); |
| 1460 |
| 1461 cache.UnrefImage(draw_image); |
| 1462 } |
| 1463 |
| 1464 TEST(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) { |
| 1465 // Cache will fit one (but not two) 100x100 images. |
| 1466 size_t cache_size = 190 * 100 * 4; |
| 1467 |
| 1468 auto context_provider = TestContextProvider::Create(); |
| 1469 context_provider->BindToCurrentThread(); |
| 1470 GpuImageDecodeCache cache(context_provider.get(), ResourceFormat::RGBA_8888, |
| 1471 kGpuMemoryLimitBytes, cache_size); |
| 1472 bool is_decomposable = true; |
| 1473 SkFilterQuality quality = kHigh_SkFilterQuality; |
| 1474 |
| 1475 sk_sp<SkImage> image = CreateImage(100, 100); |
| 1476 DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()), |
| 1477 quality, |
| 1478 CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable)); |
| 1479 |
| 1480 sk_sp<SkImage> image2 = CreateImage(100, 100); |
| 1481 DrawImage draw_image2( |
| 1482 image2, SkIRect::MakeWH(image2->width(), image2->height()), quality, |
| 1483 CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable)); |
| 1484 |
| 1485 // Add an image to the cache and un-ref it. |
| 1486 { |
| 1487 scoped_refptr<TileTask> task; |
| 1488 bool need_unref = cache.GetTaskForImageAndRef( |
| 1489 draw_image, ImageDecodeCache::TracingInfo(), &task); |
| 1490 EXPECT_TRUE(need_unref); |
| 1491 EXPECT_TRUE(task); |
| 1492 EXPECT_EQ(task->dependencies().size(), 1u); |
| 1493 EXPECT_TRUE(task->dependencies()[0]); |
| 1494 |
| 1495 // Run the task and unref the image. |
| 1496 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1497 TestTileTaskRunner::ProcessTask(task.get()); |
| 1498 cache.UnrefImage(draw_image); |
| 1499 } |
| 1500 |
| 1501 // Request the same image - it should be cached. |
| 1502 { |
| 1503 scoped_refptr<TileTask> task; |
| 1504 bool need_unref = cache.GetTaskForImageAndRef( |
| 1505 draw_image, ImageDecodeCache::TracingInfo(), &task); |
| 1506 EXPECT_TRUE(need_unref); |
| 1507 EXPECT_FALSE(task); |
| 1508 cache.UnrefImage(draw_image); |
| 1509 } |
| 1510 |
| 1511 // Add a new image to the cache. It should push out the old one. |
| 1512 { |
| 1513 scoped_refptr<TileTask> task; |
| 1514 bool need_unref = cache.GetTaskForImageAndRef( |
| 1515 draw_image2, ImageDecodeCache::TracingInfo(), &task); |
| 1516 EXPECT_TRUE(need_unref); |
| 1517 EXPECT_TRUE(task); |
| 1518 EXPECT_EQ(task->dependencies().size(), 1u); |
| 1519 EXPECT_TRUE(task->dependencies()[0]); |
| 1520 |
| 1521 // Run the task and unref the image. |
| 1522 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1523 TestTileTaskRunner::ProcessTask(task.get()); |
| 1524 cache.UnrefImage(draw_image2); |
| 1525 } |
| 1526 |
| 1527 // Request the second image - it should be cached. |
| 1528 { |
| 1529 scoped_refptr<TileTask> task; |
| 1530 bool need_unref = cache.GetTaskForImageAndRef( |
| 1531 draw_image2, ImageDecodeCache::TracingInfo(), &task); |
| 1532 EXPECT_TRUE(need_unref); |
| 1533 EXPECT_FALSE(task); |
| 1534 cache.UnrefImage(draw_image2); |
| 1535 } |
| 1536 |
| 1537 // Request the first image - it should have been evicted and return a new |
| 1538 // task. |
| 1539 { |
| 1540 scoped_refptr<TileTask> task; |
| 1541 bool need_unref = cache.GetTaskForImageAndRef( |
| 1542 draw_image, ImageDecodeCache::TracingInfo(), &task); |
| 1543 EXPECT_TRUE(need_unref); |
| 1544 EXPECT_TRUE(task); |
| 1545 EXPECT_EQ(task->dependencies().size(), 1u); |
| 1546 EXPECT_TRUE(task->dependencies()[0]); |
| 1547 |
| 1548 // Run the task and unref the image. |
| 1549 TestTileTaskRunner::ProcessTask(task->dependencies()[0].get()); |
| 1550 TestTileTaskRunner::ProcessTask(task.get()); |
| 1551 cache.UnrefImage(draw_image); |
| 1552 } |
| 1553 } |
| 1554 |
1395 } // namespace | 1555 } // namespace |
1396 } // namespace cc | 1556 } // namespace cc |
OLD | NEW |