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

Unified Diff: cc/tiles/gpu_image_decode_cache_unittest.cc

Issue 2780843002: Split image decode cache limits into "working set" vs "cache" limits (Closed)
Patch Set: comments 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/tiles/gpu_image_decode_cache.cc ('k') | cc/trees/layer_tree_host_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/tiles/gpu_image_decode_cache_unittest.cc
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index b1c73cf26380e82b53b3efa53e5bad80de483f0e..82ca3b207acc5010a73db38df5dbe2f901ff39a3 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -19,6 +19,7 @@ class TestGpuImageDecodeCache : public GpuImageDecodeCache {
explicit TestGpuImageDecodeCache(ContextProvider* context)
: GpuImageDecodeCache(context,
ResourceFormat::RGBA_8888,
+ kGpuMemoryLimitBytes,
kGpuMemoryLimitBytes) {}
};
@@ -640,7 +641,7 @@ TEST(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- cache.SetCachedBytesLimitForTesting(0);
+ cache.SetAllByteLimitsForTesting(0);
sk_sp<SkImage> image = CreateImage(100, 100);
DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()),
@@ -861,7 +862,7 @@ TEST(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- cache.SetCachedBytesLimitForTesting(0);
+ cache.SetAllByteLimitsForTesting(0);
sk_sp<SkImage> image = CreateImage(100, 100);
DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()),
@@ -884,7 +885,7 @@ TEST(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {
EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
EXPECT_FALSE(cache.DiscardableIsLockedForTesting(draw_image));
- cache.SetCachedBytesLimitForTesting(96 * 1024 * 1024);
+ cache.SetAllByteLimitsForTesting(96 * 1024 * 1024);
// Finish our draw after increasing the memory limit, image should be added to
// cache.
@@ -906,7 +907,7 @@ TEST(GpuImageDecodeCacheTest,
bool is_decomposable = true;
SkFilterQuality quality = kHigh_SkFilterQuality;
- cache.SetCachedBytesLimitForTesting(0);
+ cache.SetAllByteLimitsForTesting(0);
sk_sp<SkImage> image = CreateImage(100, 100);
DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()),
@@ -1078,36 +1079,42 @@ TEST(GpuImageDecodeCacheTest, ShouldAggressivelyFreeResources) {
cache.UnrefImage(draw_image);
// We should now have data image in our cache.
- DCHECK_GT(cache.GetBytesUsedForTesting(), 0u);
+ EXPECT_GT(cache.GetBytesUsedForTesting(), 0u);
// Tell our cache to aggressively free resources.
cache.SetShouldAggressivelyFreeResources(true);
- DCHECK_EQ(0u, cache.GetBytesUsedForTesting());
+ EXPECT_EQ(0u, cache.GetBytesUsedForTesting());
- // Attempting to upload a new image should result in at-raster decode.
+ // Attempting to upload a new image should succeed, but the image should not
+ // be cached past its use.
{
bool need_unref = cache.GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo(), &task);
- EXPECT_FALSE(need_unref);
- EXPECT_FALSE(task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task);
+
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+ cache.UnrefImage(draw_image);
+
+ EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u);
}
- // We now tell the cache to not aggressively free resources. Uploads
- // should work again.
+ // We now tell the cache to not aggressively free resources. The image may
+ // now be cached past its use.
cache.SetShouldAggressivelyFreeResources(false);
{
bool need_unref = cache.GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo(), &task);
EXPECT_TRUE(need_unref);
EXPECT_TRUE(task);
- }
- TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
- TestTileTaskRunner::ProcessTask(task.get());
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+ cache.UnrefImage(draw_image);
- // The image should be in our cache after un-ref.
- cache.UnrefImage(draw_image);
- DCHECK_GT(cache.GetBytesUsedForTesting(), 0u);
+ EXPECT_GT(cache.GetBytesUsedForTesting(), 0u);
+ }
}
TEST(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {
@@ -1326,30 +1333,38 @@ TEST(GpuImageDecodeCacheTest, MemoryStateSuspended) {
cache.UnrefImage(draw_image);
// The image should be cached.
- DCHECK_GT(cache.GetBytesUsedForTesting(), 0u);
- DCHECK_EQ(cache.GetNumCacheEntriesForTesting(), 1u);
+ EXPECT_GT(cache.GetBytesUsedForTesting(), 0u);
+ EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 1u);
// Set us to the not visible state (prerequisite for SUSPENDED).
cache.SetShouldAggressivelyFreeResources(true);
// Image should be cached, but not using memory budget.
- DCHECK_EQ(cache.GetBytesUsedForTesting(), 0u);
- DCHECK_EQ(cache.GetNumCacheEntriesForTesting(), 1u);
+ EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u);
+ EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 1u);
// Set us to the SUSPENDED state with purging.
cache.OnPurgeMemory();
cache.OnMemoryStateChange(base::MemoryState::SUSPENDED);
// Nothing should be cached.
- DCHECK_EQ(cache.GetBytesUsedForTesting(), 0u);
- DCHECK_EQ(cache.GetNumCacheEntriesForTesting(), 0u);
+ EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u);
+ EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 0u);
- // Attempts to get a task for the image should fail, as we have no space (at
- // raster only).
+ // Attempts to get a task for the image will still succeed, as SUSPENDED
+ // doesn't impact working set size.
need_unref = cache.GetTaskForImageAndRef(
draw_image, ImageDecodeCache::TracingInfo(), &task);
- EXPECT_FALSE(need_unref);
- EXPECT_FALSE(task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task);
+
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+ cache.UnrefImage(draw_image);
+
+ // Nothing should be cached.
+ EXPECT_EQ(cache.GetBytesUsedForTesting(), 0u);
+ EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 0u);
// Restore us to visible and NORMAL memory state.
cache.OnMemoryStateChange(base::MemoryState::NORMAL);
@@ -1392,5 +1407,150 @@ TEST(GpuImageDecodeCacheTest, OutOfRasterDecodeTask) {
cache.UnrefImage(draw_image);
}
+TEST(GpuImageDecodeCacheTest, ZeroCacheNormalWorkingSet) {
+ // Setup - Image cache has a normal working set, but zero cache size.
+ auto context_provider = TestContextProvider::Create();
+ context_provider->BindToCurrentThread();
+ GpuImageDecodeCache cache(context_provider.get(), ResourceFormat::RGBA_8888,
+ kGpuMemoryLimitBytes, 0);
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ // Add an image to the cache. Due to normal working set, this should produce
+ // a task and a ref.
+ sk_sp<SkImage> image = CreateImage(100, 100);
+ DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()),
+ quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable));
+ scoped_refptr<TileTask> task;
+ bool need_unref = cache.GetTaskForImageAndRef(
+ draw_image, ImageDecodeCache::TracingInfo(), &task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task);
+ EXPECT_EQ(task->dependencies().size(), 1u);
+ EXPECT_TRUE(task->dependencies()[0]);
+
+ // Run the task.
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+
+ // Request the same image - it should be cached.
+ scoped_refptr<TileTask> task2;
+ need_unref = cache.GetTaskForImageAndRef(
+ draw_image, ImageDecodeCache::TracingInfo(), &task2);
+ EXPECT_TRUE(need_unref);
+ EXPECT_FALSE(task2);
+
+ // Unref both images.
+ cache.UnrefImage(draw_image);
+ cache.UnrefImage(draw_image);
+
+ // Get the image again. As it was fully unreffed, it is no longer in the
+ // working set and will be evicted due to 0 cache size.
+ scoped_refptr<TileTask> task3;
+ need_unref = cache.GetTaskForImageAndRef(
+ draw_image, ImageDecodeCache::TracingInfo(), &task3);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task3);
+ EXPECT_EQ(task3->dependencies().size(), 1u);
+ EXPECT_TRUE(task->dependencies()[0]);
+
+ TestTileTaskRunner::ProcessTask(task3->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task3.get());
+
+ cache.UnrefImage(draw_image);
+}
+
+TEST(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) {
+ // Cache will fit one (but not two) 100x100 images.
+ size_t cache_size = 190 * 100 * 4;
+
+ auto context_provider = TestContextProvider::Create();
+ context_provider->BindToCurrentThread();
+ GpuImageDecodeCache cache(context_provider.get(), ResourceFormat::RGBA_8888,
+ kGpuMemoryLimitBytes, cache_size);
+ bool is_decomposable = true;
+ SkFilterQuality quality = kHigh_SkFilterQuality;
+
+ sk_sp<SkImage> image = CreateImage(100, 100);
+ DrawImage draw_image(image, SkIRect::MakeWH(image->width(), image->height()),
+ quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable));
+
+ sk_sp<SkImage> image2 = CreateImage(100, 100);
+ DrawImage draw_image2(
+ image2, SkIRect::MakeWH(image2->width(), image2->height()), quality,
+ CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable));
+
+ // Add an image to the cache and un-ref it.
+ {
+ scoped_refptr<TileTask> task;
+ bool need_unref = cache.GetTaskForImageAndRef(
+ draw_image, ImageDecodeCache::TracingInfo(), &task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task);
+ EXPECT_EQ(task->dependencies().size(), 1u);
+ EXPECT_TRUE(task->dependencies()[0]);
+
+ // Run the task and unref the image.
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+ cache.UnrefImage(draw_image);
+ }
+
+ // Request the same image - it should be cached.
+ {
+ scoped_refptr<TileTask> task;
+ bool need_unref = cache.GetTaskForImageAndRef(
+ draw_image, ImageDecodeCache::TracingInfo(), &task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_FALSE(task);
+ cache.UnrefImage(draw_image);
+ }
+
+ // Add a new image to the cache. It should push out the old one.
+ {
+ scoped_refptr<TileTask> task;
+ bool need_unref = cache.GetTaskForImageAndRef(
+ draw_image2, ImageDecodeCache::TracingInfo(), &task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task);
+ EXPECT_EQ(task->dependencies().size(), 1u);
+ EXPECT_TRUE(task->dependencies()[0]);
+
+ // Run the task and unref the image.
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+ cache.UnrefImage(draw_image2);
+ }
+
+ // Request the second image - it should be cached.
+ {
+ scoped_refptr<TileTask> task;
+ bool need_unref = cache.GetTaskForImageAndRef(
+ draw_image2, ImageDecodeCache::TracingInfo(), &task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_FALSE(task);
+ cache.UnrefImage(draw_image2);
+ }
+
+ // Request the first image - it should have been evicted and return a new
+ // task.
+ {
+ scoped_refptr<TileTask> task;
+ bool need_unref = cache.GetTaskForImageAndRef(
+ draw_image, ImageDecodeCache::TracingInfo(), &task);
+ EXPECT_TRUE(need_unref);
+ EXPECT_TRUE(task);
+ EXPECT_EQ(task->dependencies().size(), 1u);
+ EXPECT_TRUE(task->dependencies()[0]);
+
+ // Run the task and unref the image.
+ TestTileTaskRunner::ProcessTask(task->dependencies()[0].get());
+ TestTileTaskRunner::ProcessTask(task.get());
+ cache.UnrefImage(draw_image);
+ }
+}
+
} // namespace
} // namespace cc
« no previous file with comments | « cc/tiles/gpu_image_decode_cache.cc ('k') | cc/trees/layer_tree_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698