blob: d9e4c18a7d41bd1eceb8299ac68f599322151cb8 [file] [log] [blame]
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00008#if SK_SUPPORT_GPU
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +00009
bsalomonbcf0a522014-10-08 08:40:09 -070010#include "GrContext.h"
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000011#include "GrContextFactory.h"
bsalomonbcf0a522014-10-08 08:40:09 -070012#include "GrGpu.h"
bsalomon3582d3e2015-02-13 14:20:05 -080013#include "GrGpuResourceCacheAccess.h"
14#include "GrGpuResourcePriv.h"
bsalomon0ea80f42015-02-11 10:49:59 -080015#include "GrResourceCache.h"
bsalomonbcf0a522014-10-08 08:40:09 -070016#include "SkCanvas.h"
bsalomon71cb0c22014-11-14 12:10:14 -080017#include "SkGr.h"
18#include "SkMessageBus.h"
reed69f6f002014-09-18 06:09:44 -070019#include "SkSurface.h"
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +000020#include "Test.h"
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000021
22static const int gWidth = 640;
23static const int gHeight = 480;
24
25////////////////////////////////////////////////////////////////////////////////
bsalomon33435572014-11-05 14:47:41 -080026static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) {
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000027 const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
28
29 SkBitmap src;
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000030 src.allocN32Pixels(size.width(), size.height());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000031 src.eraseColor(SK_ColorBLACK);
32 size_t srcSize = src.getSize();
33
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000034 size_t initialCacheSize;
35 context->getResourceCacheUsage(NULL, &initialCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000036
37 int oldMaxNum;
38 size_t oldMaxBytes;
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000039 context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);
skia.committer@gmail.com17f1ae62013-08-09 07:01:22 +000040
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000041 // Set the cache limits so we can fit 10 "src" images and the
42 // max number of textures doesn't matter
43 size_t maxCacheSize = initialCacheSize + 10*srcSize;
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000044 context->setResourceCacheLimits(1000, maxCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000045
46 SkBitmap readback;
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000047 readback.allocN32Pixels(size.width(), size.height());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000048
49 for (int i = 0; i < 100; ++i) {
50 canvas->drawBitmap(src, 0, 0);
51 canvas->readPixels(size, &readback);
52
53 // "modify" the src texture
54 src.notifyPixelsChanged();
55
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000056 size_t curCacheSize;
57 context->getResourceCacheUsage(NULL, &curCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000058
59 // we should never go over the size limit
60 REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
61 }
62
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000063 context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000064}
65
bsalomon02a44a42015-02-19 09:09:00 -080066static void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* context) {
67 GrSurfaceDesc smallDesc;
68 smallDesc.fFlags = kRenderTarget_GrSurfaceFlag;
69 smallDesc.fConfig = kSkia8888_GrPixelConfig;
70 smallDesc.fWidth = 4;
71 smallDesc.fHeight = 4;
72 smallDesc.fSampleCnt = 0;
73
74 // Test that two budgeted RTs with the same desc share a stencil buffer.
75 SkAutoTUnref<GrTexture> smallRT0(context->createTexture(smallDesc, true));
76 SkAutoTUnref<GrTexture> smallRT1(context->createTexture(smallDesc, true));
77 REPORTER_ASSERT(reporter, smallRT0 && smallRT1 &&
78 smallRT0->asRenderTarget() && smallRT1->asRenderTarget() &&
79 smallRT0->asRenderTarget()->getStencilBuffer() ==
80 smallRT1->asRenderTarget()->getStencilBuffer());
81
82 // An unbudgeted RT with the same desc should also share.
83 SkAutoTUnref<GrTexture> smallRT2(context->createTexture(smallDesc, false));
84 REPORTER_ASSERT(reporter, smallRT0 && smallRT2 &&
85 smallRT0->asRenderTarget() && smallRT2->asRenderTarget() &&
86 smallRT0->asRenderTarget()->getStencilBuffer() ==
87 smallRT2->asRenderTarget()->getStencilBuffer());
88
89 // An RT with a much larger size should not share.
90 GrSurfaceDesc bigDesc;
91 bigDesc.fFlags = kRenderTarget_GrSurfaceFlag;
92 bigDesc.fConfig = kSkia8888_GrPixelConfig;
93 bigDesc.fWidth = 400;
94 bigDesc.fHeight = 200;
95 bigDesc.fSampleCnt = 0;
96 SkAutoTUnref<GrTexture> bigRT(context->createTexture(bigDesc, false));
97 REPORTER_ASSERT(reporter, smallRT0 && bigRT &&
98 smallRT0->asRenderTarget() && bigRT->asRenderTarget() &&
99 smallRT0->asRenderTarget()->getStencilBuffer() !=
100 bigRT->asRenderTarget()->getStencilBuffer());
101
102 if (context->getMaxSampleCount() >= 4) {
103 // An RT with a different sample count should not share.
104 GrSurfaceDesc smallMSAADesc = smallDesc;
105 smallMSAADesc.fSampleCnt = 4;
106 SkAutoTUnref<GrTexture> smallMSAART0(context->createTexture(smallMSAADesc, false));
107 REPORTER_ASSERT(reporter, smallRT0 && smallMSAART0 &&
108 smallRT0->asRenderTarget() && smallMSAART0->asRenderTarget() &&
109 smallRT0->asRenderTarget()->getStencilBuffer() !=
110 smallMSAART0->asRenderTarget()->getStencilBuffer());
111 // A second MSAA RT should share with the first MSAA RT.
112 SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false));
113 REPORTER_ASSERT(reporter, smallMSAART0 && smallMSAART1 &&
114 smallMSAART0->asRenderTarget() &&
115 smallMSAART1->asRenderTarget() &&
116 smallMSAART0->asRenderTarget()->getStencilBuffer() ==
117 smallMSAART1->asRenderTarget()->getStencilBuffer());
118 // But not one with a larger sample count should not. (Also check that the request for 4
119 // samples didn't get rounded up to >= 8 or else they could share.).
120 if (context->getMaxSampleCount() >= 8 && smallMSAART0 && smallMSAART0->asRenderTarget() &&
121 smallMSAART0->asRenderTarget()->numSamples() < 8) {
122 smallMSAADesc.fSampleCnt = 8;
123 smallMSAART1.reset(context->createTexture(smallMSAADesc, false));
124 REPORTER_ASSERT(reporter, smallMSAART0 && smallMSAART1 &&
125 smallMSAART0->asRenderTarget() &&
126 smallMSAART1->asRenderTarget() &&
127 smallMSAART0->asRenderTarget()->getStencilBuffer() !=
128 smallMSAART1->asRenderTarget()->getStencilBuffer());
129 }
130 }
131}
132
bsalomon6d3fe022014-07-25 08:35:45 -0700133class TestResource : public GrGpuResource {
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000134 static const size_t kDefaultSize = 100;
bsalomon1c60dfe2015-01-21 09:32:40 -0800135 enum ScratchConstructor { kScratchConstructor };
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000136public:
137 SK_DECLARE_INST_COUNT(TestResource);
bsalomon1c60dfe2015-01-21 09:32:40 -0800138 /** Property that distinctly categorizes the resource.
139 * For example, textures have width, height, ... */
bsalomon23e619c2015-02-06 11:54:28 -0800140 enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty };
bsalomon1c60dfe2015-01-21 09:32:40 -0800141
bsalomon5236cf42015-01-14 10:42:08 -0800142 TestResource(GrGpu* gpu, size_t size, GrGpuResource::LifeCycle lifeCycle)
143 : INHERITED(gpu, lifeCycle)
144 , fToDelete(NULL)
bsalomon1c60dfe2015-01-21 09:32:40 -0800145 , fSize(size)
bsalomon23e619c2015-02-06 11:54:28 -0800146 , fProperty(kA_SimulatedProperty) {
bsalomon5236cf42015-01-14 10:42:08 -0800147 ++fNumAlive;
148 this->registerWithCache();
149 }
150
151 TestResource(GrGpu* gpu, GrGpuResource::LifeCycle lifeCycle)
152 : INHERITED(gpu, lifeCycle)
bsalomondace19e2014-11-17 07:34:06 -0800153 , fToDelete(NULL)
bsalomon1c60dfe2015-01-21 09:32:40 -0800154 , fSize(kDefaultSize)
bsalomon23e619c2015-02-06 11:54:28 -0800155 , fProperty(kA_SimulatedProperty) {
bsalomondace19e2014-11-17 07:34:06 -0800156 ++fNumAlive;
157 this->registerWithCache();
158 }
159
bsalomon8b79d232014-11-10 10:19:06 -0800160 TestResource(GrGpu* gpu)
bsalomon5236cf42015-01-14 10:42:08 -0800161 : INHERITED(gpu, kCached_LifeCycle)
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000162 , fToDelete(NULL)
bsalomon1c60dfe2015-01-21 09:32:40 -0800163 , fSize(kDefaultSize)
bsalomon23e619c2015-02-06 11:54:28 -0800164 , fProperty(kA_SimulatedProperty) {
bsalomon8b79d232014-11-10 10:19:06 -0800165 ++fNumAlive;
166 this->registerWithCache();
167 }
168
bsalomon23e619c2015-02-06 11:54:28 -0800169 static TestResource* CreateScratch(GrGpu* gpu, SimulatedProperty property, bool cached = true) {
bsalomonc2f35b72015-01-23 07:19:22 -0800170 return SkNEW_ARGS(TestResource, (gpu, property, cached, kScratchConstructor));
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000171 }
172
173 ~TestResource() {
bsalomon33435572014-11-05 14:47:41 -0800174 --fNumAlive;
bsalomon71cb0c22014-11-14 12:10:14 -0800175 SkSafeUnref(fToDelete);
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000176 }
177
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000178 void setSize(size_t size) {
179 fSize = size;
180 this->didChangeGpuMemorySize();
181 }
182
bsalomon33435572014-11-05 14:47:41 -0800183 static int NumAlive() { return fNumAlive; }
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000184
bsalomon71cb0c22014-11-14 12:10:14 -0800185 void setUnrefWhenDestroyed(TestResource* resource) {
186 SkRefCnt_SafeAssign(fToDelete, resource);
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000187 }
188
bsalomon1c60dfe2015-01-21 09:32:40 -0800189 static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
190 static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
191 GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
bsalomon24db3b12015-01-23 04:24:04 -0800192 for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
193 builder[i] = static_cast<uint32_t>(i + property);
bsalomon1c60dfe2015-01-21 09:32:40 -0800194 }
195 }
196
197 static size_t ExpectedScratchKeySize() {
198 return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
199 }
200
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000201private:
bsalomon24db3b12015-01-23 04:24:04 -0800202 static const int kScratchKeyFieldCnt = 6;
bsalomon1c60dfe2015-01-21 09:32:40 -0800203
bsalomonc2f35b72015-01-23 07:19:22 -0800204 TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor)
205 : INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle)
bsalomon1c60dfe2015-01-21 09:32:40 -0800206 , fToDelete(NULL)
207 , fSize(kDefaultSize)
208 , fProperty(property) {
209 GrScratchKey scratchKey;
210 ComputeScratchKey(fProperty, &scratchKey);
211 this->setScratchKey(scratchKey);
212 ++fNumAlive;
213 this->registerWithCache();
214 }
215
bsalomon69ed47f2014-11-12 11:13:39 -0800216 size_t onGpuMemorySize() const SK_OVERRIDE { return fSize; }
217
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000218 TestResource* fToDelete;
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000219 size_t fSize;
bsalomon33435572014-11-05 14:47:41 -0800220 static int fNumAlive;
bsalomon1c60dfe2015-01-21 09:32:40 -0800221 SimulatedProperty fProperty;
bsalomon6d3fe022014-07-25 08:35:45 -0700222 typedef GrGpuResource INHERITED;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000223};
bsalomon33435572014-11-05 14:47:41 -0800224int TestResource::fNumAlive = 0;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000225
bsalomonc2f35b72015-01-23 07:19:22 -0800226class Mock {
227public:
228 Mock(int maxCnt, size_t maxBytes) {
229 fContext.reset(GrContext::CreateMockContext());
230 SkASSERT(fContext);
231 fContext->setResourceCacheLimits(maxCnt, maxBytes);
bsalomon0ea80f42015-02-11 10:49:59 -0800232 GrResourceCache* cache = fContext->getResourceCache();
233 cache->purgeAllUnlocked();
234 SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800235 }
bsalomonc2f35b72015-01-23 07:19:22 -0800236
bsalomon0ea80f42015-02-11 10:49:59 -0800237 GrResourceCache* cache() { return fContext->getResourceCache(); }
bsalomonc2f35b72015-01-23 07:19:22 -0800238
239 GrContext* context() { return fContext; }
240
241private:
242 SkAutoTUnref<GrContext> fContext;
243};
244
245static void test_no_key(skiatest::Reporter* reporter) {
246 Mock mock(10, 30000);
247 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800248 GrResourceCache* cache = mock.cache();
bsalomon71cb0c22014-11-14 12:10:14 -0800249
250 // Create a bunch of resources with no keys
bsalomon5236cf42015-01-14 10:42:08 -0800251 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
252 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
253 TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
254 TestResource* d = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon71cb0c22014-11-14 12:10:14 -0800255 a->setSize(11);
256 b->setSize(12);
257 c->setSize(13);
258 d->setSize(14);
259
260 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800261 REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
bsalomon71cb0c22014-11-14 12:10:14 -0800262 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
bsalomon0ea80f42015-02-11 10:49:59 -0800263 d->gpuMemorySize() == cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800264
265 // Should be safe to purge without deleting the resources since we still have refs.
bsalomon0ea80f42015-02-11 10:49:59 -0800266 cache->purgeAllUnlocked();
bsalomon71cb0c22014-11-14 12:10:14 -0800267 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
268
bsalomon8718aaf2015-02-19 07:24:21 -0800269 // Since the resources have neither unique nor scratch keys, delete immediately upon unref.
bsalomon71cb0c22014-11-14 12:10:14 -0800270
271 a->unref();
272 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800273 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
bsalomon71cb0c22014-11-14 12:10:14 -0800274 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800275 cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800276
277 c->unref();
278 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800279 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon71cb0c22014-11-14 12:10:14 -0800280 REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800281 cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800282
283 d->unref();
284 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800285 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
286 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800287
288 b->unref();
289 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800290 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
291 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800292}
293
bsalomon24db3b12015-01-23 04:24:04 -0800294// Each integer passed as a template param creates a new domain.
bsalomon8718aaf2015-02-19 07:24:21 -0800295template <int> static void make_unique_key(GrUniqueKey* key, int data) {
296 static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
297 GrUniqueKey::Builder builder(key, d, 1);
bsalomon24db3b12015-01-23 04:24:04 -0800298 builder[0] = data;
299}
300
bsalomon84c8e622014-11-17 09:33:27 -0800301static void test_budgeting(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800302 Mock mock(10, 300);
303 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800304 GrResourceCache* cache = mock.cache();
bsalomondace19e2014-11-17 07:34:06 -0800305
bsalomon8718aaf2015-02-19 07:24:21 -0800306 GrUniqueKey uniqueKey;
307 make_unique_key<0>(&uniqueKey, 0);
bsalomondace19e2014-11-17 07:34:06 -0800308
bsalomon8718aaf2015-02-19 07:24:21 -0800309 // Create a scratch, a unique, and a wrapped resource
bsalomon1c60dfe2015-01-21 09:32:40 -0800310 TestResource* scratch =
bsalomon23e619c2015-02-06 11:54:28 -0800311 TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
bsalomondace19e2014-11-17 07:34:06 -0800312 scratch->setSize(10);
bsalomon8718aaf2015-02-19 07:24:21 -0800313 TestResource* unique = SkNEW_ARGS(TestResource, (context->getGpu()));
314 unique->setSize(11);
bsalomonf99e9612015-02-19 08:24:16 -0800315 unique->resourcePriv().setUniqueKey(uniqueKey);
bsalomon5236cf42015-01-14 10:42:08 -0800316 TestResource* wrapped = SkNEW_ARGS(TestResource,
317 (context->getGpu(), GrGpuResource::kWrapped_LifeCycle));
318 wrapped->setSize(12);
319 TestResource* unbudgeted = SkNEW_ARGS(TestResource,
320 (context->getGpu(), GrGpuResource::kUncached_LifeCycle));
bsalomon84c8e622014-11-17 09:33:27 -0800321 unbudgeted->setSize(13);
bsalomondace19e2014-11-17 07:34:06 -0800322
bsalomon8718aaf2015-02-19 07:24:21 -0800323 // Make sure we can't add a unique key to the wrapped resource
324 GrUniqueKey uniqueKey2;
325 make_unique_key<0>(&uniqueKey2, 1);
bsalomonf99e9612015-02-19 08:24:16 -0800326 wrapped->resourcePriv().setUniqueKey(uniqueKey2);
bsalomon8718aaf2015-02-19 07:24:21 -0800327 REPORTER_ASSERT(reporter, NULL == cache->findAndRefUniqueResource(uniqueKey2));
bsalomondace19e2014-11-17 07:34:06 -0800328
329 // Make sure sizes are as we expect
bsalomon0ea80f42015-02-11 10:49:59 -0800330 REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
bsalomon8718aaf2015-02-19 07:24:21 -0800331 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
bsalomon84c8e622014-11-17 09:33:27 -0800332 wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800333 cache->getResourceBytes());
334 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
bsalomon8718aaf2015-02-19 07:24:21 -0800335 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800336 cache->getBudgetedResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800337
bsalomon63c992f2015-01-23 12:47:59 -0800338 // Our refs mean that the resources are non purgeable.
bsalomon0ea80f42015-02-11 10:49:59 -0800339 cache->purgeAllUnlocked();
340 REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
bsalomon8718aaf2015-02-19 07:24:21 -0800341 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
bsalomon84c8e622014-11-17 09:33:27 -0800342 wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800343 cache->getResourceBytes());
344 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
bsalomon8718aaf2015-02-19 07:24:21 -0800345 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800346 cache->getBudgetedResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800347
348 // Unreffing the wrapped resource should free it right away.
349 wrapped->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800350 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
bsalomon8718aaf2015-02-19 07:24:21 -0800351 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
bsalomon0ea80f42015-02-11 10:49:59 -0800352 unbudgeted->gpuMemorySize() == cache->getResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800353
bsalomon84c8e622014-11-17 09:33:27 -0800354 // Now try freeing the budgeted resources first
bsalomon5236cf42015-01-14 10:42:08 -0800355 wrapped = SkNEW_ARGS(TestResource, (context->getGpu(), GrGpuResource::kWrapped_LifeCycle));
bsalomondace19e2014-11-17 07:34:06 -0800356 scratch->setSize(12);
bsalomon8718aaf2015-02-19 07:24:21 -0800357 unique->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800358 cache->purgeAllUnlocked();
359 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
bsalomon84c8e622014-11-17 09:33:27 -0800360 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() +
bsalomon0ea80f42015-02-11 10:49:59 -0800361 unbudgeted->gpuMemorySize() == cache->getResourceBytes());
362 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
363 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800364
365 scratch->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800366 cache->purgeAllUnlocked();
367 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon84c8e622014-11-17 09:33:27 -0800368 REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800369 cache->getResourceBytes());
370 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
371 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800372
373 wrapped->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800374 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
375 REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes());
376 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
377 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
bsalomon84c8e622014-11-17 09:33:27 -0800378
379 unbudgeted->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800380 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
381 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
382 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
383 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800384}
385
bsalomon5236cf42015-01-14 10:42:08 -0800386static void test_unbudgeted(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800387 Mock mock(10, 30000);
388 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800389 GrResourceCache* cache = mock.cache();
bsalomon5236cf42015-01-14 10:42:08 -0800390
bsalomon8718aaf2015-02-19 07:24:21 -0800391 GrUniqueKey uniqueKey;
392 make_unique_key<0>(&uniqueKey, 0);
bsalomon5236cf42015-01-14 10:42:08 -0800393
394 TestResource* scratch;
bsalomon8718aaf2015-02-19 07:24:21 -0800395 TestResource* unique;
bsalomon5236cf42015-01-14 10:42:08 -0800396 TestResource* wrapped;
397 TestResource* unbudgeted;
398
399 // A large uncached or wrapped resource shouldn't evict anything.
bsalomon23e619c2015-02-06 11:54:28 -0800400 scratch = TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
bsalomon5236cf42015-01-14 10:42:08 -0800401 scratch->setSize(10);
402 scratch->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800403 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
404 REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes());
405 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
406 REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800407
bsalomon8718aaf2015-02-19 07:24:21 -0800408 unique = SkNEW_ARGS(TestResource, (context->getGpu()));
409 unique->setSize(11);
bsalomonf99e9612015-02-19 08:24:16 -0800410 unique->resourcePriv().setUniqueKey(uniqueKey);
bsalomon8718aaf2015-02-19 07:24:21 -0800411 unique->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800412 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
413 REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
414 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
415 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800416
bsalomon0ea80f42015-02-11 10:49:59 -0800417 size_t large = 2 * cache->getResourceBytes();
bsalomon5236cf42015-01-14 10:42:08 -0800418 unbudgeted = SkNEW_ARGS(TestResource,
419 (context->getGpu(), large, GrGpuResource::kUncached_LifeCycle));
bsalomon0ea80f42015-02-11 10:49:59 -0800420 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
421 REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
422 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
423 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800424
425 unbudgeted->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800426 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
427 REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
428 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
429 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800430
431 wrapped = SkNEW_ARGS(TestResource,
432 (context->getGpu(), large, GrGpuResource::kWrapped_LifeCycle));
bsalomon0ea80f42015-02-11 10:49:59 -0800433 REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
434 REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
435 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
436 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800437
438 wrapped->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800439 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
440 REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
441 REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
442 REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800443
bsalomon0ea80f42015-02-11 10:49:59 -0800444 cache->purgeAllUnlocked();
445 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
446 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
447 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
448 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
bsalomon5236cf42015-01-14 10:42:08 -0800449}
450
bsalomon3582d3e2015-02-13 14:20:05 -0800451// This method can't be static because it needs to friended in GrGpuResource::CacheAccess.
452void test_unbudgeted_to_scratch(skiatest::Reporter* reporter);
453/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800454 Mock mock(10, 300);
455 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800456 GrResourceCache* cache = mock.cache();
bsalomonc2f35b72015-01-23 07:19:22 -0800457
458 TestResource* resource =
bsalomon23e619c2015-02-06 11:54:28 -0800459 TestResource::CreateScratch(context->getGpu(), TestResource::kA_SimulatedProperty, false);
bsalomonc2f35b72015-01-23 07:19:22 -0800460 GrScratchKey key;
bsalomon23e619c2015-02-06 11:54:28 -0800461 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key);
bsalomonc2f35b72015-01-23 07:19:22 -0800462
463 size_t size = resource->gpuMemorySize();
464 for (int i = 0; i < 2; ++i) {
465 // Since this resource is unbudgeted, it should not be reachable as scratch.
bsalomon3582d3e2015-02-13 14:20:05 -0800466 REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
bsalomonc2f35b72015-01-23 07:19:22 -0800467 REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
bsalomon3582d3e2015-02-13 14:20:05 -0800468 REPORTER_ASSERT(reporter, !resource->resourcePriv().isBudgeted());
bsalomon0ea80f42015-02-11 10:49:59 -0800469 REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(key));
470 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
471 REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
472 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
473 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
bsalomonc2f35b72015-01-23 07:19:22 -0800474
475 // Once it is unrefed, it should become available as scratch.
476 resource->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800477 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
478 REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
479 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
480 REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
481 resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key));
bsalomonc2f35b72015-01-23 07:19:22 -0800482 REPORTER_ASSERT(reporter, resource);
bsalomon3582d3e2015-02-13 14:20:05 -0800483 REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
bsalomonc2f35b72015-01-23 07:19:22 -0800484 REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
bsalomon3582d3e2015-02-13 14:20:05 -0800485 REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted());
bsalomonc2f35b72015-01-23 07:19:22 -0800486
487 if (0 == i) {
488 // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
489 // the above tests again.
bsalomon3582d3e2015-02-13 14:20:05 -0800490 resource->resourcePriv().makeUnbudgeted();
bsalomonc2f35b72015-01-23 07:19:22 -0800491 } else {
492 // After the second time around, try removing the scratch key
bsalomon3582d3e2015-02-13 14:20:05 -0800493 resource->resourcePriv().removeScratchKey();
bsalomon0ea80f42015-02-11 10:49:59 -0800494 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
495 REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
496 REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
497 REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
bsalomon3582d3e2015-02-13 14:20:05 -0800498 REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid());
bsalomonc2f35b72015-01-23 07:19:22 -0800499 REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
bsalomon3582d3e2015-02-13 14:20:05 -0800500 REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted());
bsalomonc2f35b72015-01-23 07:19:22 -0800501
502 // now when it is unrefed it should die since it has no key.
503 resource->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800504 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
505 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
506 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
507 REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
bsalomonc2f35b72015-01-23 07:19:22 -0800508 }
bsalomon8b79d232014-11-10 10:19:06 -0800509 }
bsalomonc2f35b72015-01-23 07:19:22 -0800510}
511
512static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
513 Mock mock(5, 30000);
514 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800515 GrResourceCache* cache = mock.cache();
bsalomon8b79d232014-11-10 10:19:06 -0800516
bsalomon8b79d232014-11-10 10:19:06 -0800517 // Create two resources that have the same scratch key.
bsalomon23e619c2015-02-06 11:54:28 -0800518 TestResource* a = TestResource::CreateScratch(context->getGpu(),
519 TestResource::kB_SimulatedProperty);
520 TestResource* b = TestResource::CreateScratch(context->getGpu(),
521 TestResource::kB_SimulatedProperty);
bsalomon8b79d232014-11-10 10:19:06 -0800522 a->setSize(11);
523 b->setSize(12);
bsalomon1c60dfe2015-01-21 09:32:40 -0800524 GrScratchKey scratchKey1;
bsalomon23e619c2015-02-06 11:54:28 -0800525 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
bsalomon1c60dfe2015-01-21 09:32:40 -0800526 // Check for negative case consistency. (leaks upon test failure.)
bsalomon0ea80f42015-02-11 10:49:59 -0800527 REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(scratchKey1));
bsalomon1c60dfe2015-01-21 09:32:40 -0800528
529 GrScratchKey scratchKey;
bsalomon23e619c2015-02-06 11:54:28 -0800530 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
bsalomon1c60dfe2015-01-21 09:32:40 -0800531
bsalomon0ea80f42015-02-11 10:49:59 -0800532 // Scratch resources are registered with GrResourceCache just by existing. There are 2.
bsalomon8b79d232014-11-10 10:19:06 -0800533 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800534 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
535 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon71cb0c22014-11-14 12:10:14 -0800536 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
bsalomon0ea80f42015-02-11 10:49:59 -0800537 cache->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800538
bsalomon63c992f2015-01-23 12:47:59 -0800539 // Our refs mean that the resources are non purgeable.
bsalomon0ea80f42015-02-11 10:49:59 -0800540 cache->purgeAllUnlocked();
bsalomon8b79d232014-11-10 10:19:06 -0800541 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800542 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800543
544 // Unref but don't purge
545 a->unref();
546 b->unref();
547 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800548 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
bsalomon8b79d232014-11-10 10:19:06 -0800549
bsalomon63c992f2015-01-23 12:47:59 -0800550 // Purge again. This time resources should be purgeable.
bsalomon0ea80f42015-02-11 10:49:59 -0800551 cache->purgeAllUnlocked();
bsalomon8b79d232014-11-10 10:19:06 -0800552 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800553 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
554 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
bsalomon8b79d232014-11-10 10:19:06 -0800555}
556
bsalomon10e23ca2014-11-25 05:52:06 -0800557static void test_remove_scratch_key(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800558 Mock mock(5, 30000);
559 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800560 GrResourceCache* cache = mock.cache();
bsalomon10e23ca2014-11-25 05:52:06 -0800561
bsalomon10e23ca2014-11-25 05:52:06 -0800562 // Create two resources that have the same scratch key.
bsalomon23e619c2015-02-06 11:54:28 -0800563 TestResource* a = TestResource::CreateScratch(context->getGpu(),
564 TestResource::kB_SimulatedProperty);
565 TestResource* b = TestResource::CreateScratch(context->getGpu(),
566 TestResource::kB_SimulatedProperty);
bsalomon10e23ca2014-11-25 05:52:06 -0800567 a->unref();
568 b->unref();
569
bsalomon1c60dfe2015-01-21 09:32:40 -0800570 GrScratchKey scratchKey;
571 // Ensure that scratch key lookup is correct for negative case.
bsalomon23e619c2015-02-06 11:54:28 -0800572 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
bsalomon1c60dfe2015-01-21 09:32:40 -0800573 // (following leaks upon test failure).
bsalomon0ea80f42015-02-11 10:49:59 -0800574 REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL);
bsalomon1c60dfe2015-01-21 09:32:40 -0800575
bsalomon0ea80f42015-02-11 10:49:59 -0800576 // Scratch resources are registered with GrResourceCache just by existing. There are 2.
bsalomon23e619c2015-02-06 11:54:28 -0800577 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
bsalomon10e23ca2014-11-25 05:52:06 -0800578 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800579 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
580 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon10e23ca2014-11-25 05:52:06 -0800581
582 // Find the first resource and remove its scratch key
583 GrGpuResource* find;
bsalomon0ea80f42015-02-11 10:49:59 -0800584 find = cache->findAndRefScratchResource(scratchKey);
bsalomon3582d3e2015-02-13 14:20:05 -0800585 find->resourcePriv().removeScratchKey();
bsalomon10e23ca2014-11-25 05:52:06 -0800586 // It's still alive, but not cached by scratch key anymore
587 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800588 SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
589 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon10e23ca2014-11-25 05:52:06 -0800590
591 // The cache should immediately delete it when it's unrefed since it isn't accessible.
592 find->unref();
593 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800594 SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
595 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
bsalomon10e23ca2014-11-25 05:52:06 -0800596
597 // Repeat for the second resource.
bsalomon0ea80f42015-02-11 10:49:59 -0800598 find = cache->findAndRefScratchResource(scratchKey);
bsalomon3582d3e2015-02-13 14:20:05 -0800599 find->resourcePriv().removeScratchKey();
bsalomon10e23ca2014-11-25 05:52:06 -0800600 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800601 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
602 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
bsalomon10e23ca2014-11-25 05:52:06 -0800603
604 // Should be able to call this multiple times with no problem.
bsalomon3582d3e2015-02-13 14:20:05 -0800605 find->resourcePriv().removeScratchKey();
bsalomon10e23ca2014-11-25 05:52:06 -0800606 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800607 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
608 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
bsalomon10e23ca2014-11-25 05:52:06 -0800609
610 find->unref();
611 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800612 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
613 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
bsalomon10e23ca2014-11-25 05:52:06 -0800614}
615
bsalomon1c60dfe2015-01-21 09:32:40 -0800616static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800617 Mock mock(5, 30000);
618 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800619 GrResourceCache* cache = mock.cache();
bsalomon1c60dfe2015-01-21 09:32:40 -0800620
621 // Create two resources that have the same scratch key.
bsalomon23e619c2015-02-06 11:54:28 -0800622 TestResource* a = TestResource::CreateScratch(context->getGpu(),
623 TestResource::kB_SimulatedProperty);
624 TestResource* b = TestResource::CreateScratch(context->getGpu(),
625 TestResource::kB_SimulatedProperty);
bsalomon1c60dfe2015-01-21 09:32:40 -0800626 a->unref();
627 b->unref();
628
629 GrScratchKey scratchKey;
630 // Ensure that scratch key comparison and assignment is consistent.
631 GrScratchKey scratchKey1;
bsalomon23e619c2015-02-06 11:54:28 -0800632 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
bsalomon1c60dfe2015-01-21 09:32:40 -0800633 GrScratchKey scratchKey2;
bsalomon23e619c2015-02-06 11:54:28 -0800634 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2);
bsalomon1c60dfe2015-01-21 09:32:40 -0800635 REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize());
636 REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2);
637 REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1);
638 scratchKey = scratchKey1;
639 REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
640 REPORTER_ASSERT(reporter, scratchKey1 == scratchKey);
641 REPORTER_ASSERT(reporter, scratchKey == scratchKey1);
642 REPORTER_ASSERT(reporter, scratchKey2 != scratchKey);
643 REPORTER_ASSERT(reporter, scratchKey != scratchKey2);
644 scratchKey = scratchKey2;
645 REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
646 REPORTER_ASSERT(reporter, scratchKey1 != scratchKey);
647 REPORTER_ASSERT(reporter, scratchKey != scratchKey1);
648 REPORTER_ASSERT(reporter, scratchKey2 == scratchKey);
649 REPORTER_ASSERT(reporter, scratchKey == scratchKey2);
650
651 // Ensure that scratch key lookup is correct for negative case.
bsalomon23e619c2015-02-06 11:54:28 -0800652 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
bsalomon1c60dfe2015-01-21 09:32:40 -0800653 // (following leaks upon test failure).
bsalomon0ea80f42015-02-11 10:49:59 -0800654 REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL);
bsalomon1c60dfe2015-01-21 09:32:40 -0800655
656 // Find the first resource with a scratch key and a copy of a scratch key.
bsalomon23e619c2015-02-06 11:54:28 -0800657 TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
bsalomon0ea80f42015-02-11 10:49:59 -0800658 GrGpuResource* find = cache->findAndRefScratchResource(scratchKey);
bsalomon1c60dfe2015-01-21 09:32:40 -0800659 REPORTER_ASSERT(reporter, find != NULL);
660 find->unref();
661
662 scratchKey2 = scratchKey;
bsalomon0ea80f42015-02-11 10:49:59 -0800663 find = cache->findAndRefScratchResource(scratchKey2);
bsalomon1c60dfe2015-01-21 09:32:40 -0800664 REPORTER_ASSERT(reporter, find != NULL);
665 REPORTER_ASSERT(reporter, find == a || find == b);
666
bsalomon0ea80f42015-02-11 10:49:59 -0800667 GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2);
bsalomon1c60dfe2015-01-21 09:32:40 -0800668 REPORTER_ASSERT(reporter, find2 != NULL);
669 REPORTER_ASSERT(reporter, find2 == a || find2 == b);
670 REPORTER_ASSERT(reporter, find2 != find);
671 find2->unref();
672 find->unref();
673}
674
bsalomon8718aaf2015-02-19 07:24:21 -0800675static void test_duplicate_unique_key(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800676 Mock mock(5, 30000);
677 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800678 GrResourceCache* cache = mock.cache();
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000679
bsalomon8718aaf2015-02-19 07:24:21 -0800680 GrUniqueKey key;
681 make_unique_key<0>(&key, 0);
bsalomon8b79d232014-11-10 10:19:06 -0800682
bsalomon8718aaf2015-02-19 07:24:21 -0800683 // Create two resources that we will attempt to register with the same unique key.
bsalomon5236cf42015-01-14 10:42:08 -0800684 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8b79d232014-11-10 10:19:06 -0800685 a->setSize(11);
bsalomon71cb0c22014-11-14 12:10:14 -0800686
bsalomonf99e9612015-02-19 08:24:16 -0800687 // Set key on resource a.
688 a->resourcePriv().setUniqueKey(key);
689 REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
690 a->unref();
bsalomon71cb0c22014-11-14 12:10:14 -0800691
bsalomonf99e9612015-02-19 08:24:16 -0800692 // Make sure that redundantly setting a's key works.
693 a->resourcePriv().setUniqueKey(key);
694 REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
bsalomon8b79d232014-11-10 10:19:06 -0800695 a->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800696 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
697 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800698 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
699
bsalomonf99e9612015-02-19 08:24:16 -0800700 // Create resource b and set the same key. It should replace a's unique key cache entry.
701 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
702 b->setSize(12);
703 b->resourcePriv().setUniqueKey(key);
704 REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key));
705 b->unref();
706
707 // Still have two resources because a is still reffed.
708 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
709 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes());
710 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
711
712 a->unref();
713 // Now a should be gone.
714 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
715 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
716 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
717
718 // Now replace b with c, but make sure c can start with one unique key and change it to b's key.
719 // Also make b be unreffed when replacement occurs.
720 b->unref();
721 TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
722 GrUniqueKey differentKey;
723 make_unique_key<0>(&differentKey, 1);
724 c->setSize(13);
725 c->resourcePriv().setUniqueKey(differentKey);
726 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
727 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes());
728 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
729 // c replaces b and b should be immediately purged.
730 c->resourcePriv().setUniqueKey(key);
731 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
732 REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
733 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
734
735 // c shouldn't be purged because it is ref'ed.
bsalomon0ea80f42015-02-11 10:49:59 -0800736 cache->purgeAllUnlocked();
bsalomonf99e9612015-02-19 08:24:16 -0800737 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
738 REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
739 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
740
741 // Drop the ref on c, it should be kept alive because it has a unique key.
742 c->unref();
743 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
744 REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
745 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
746
747 // Verify that we can find c, then remove its unique key. It should get purged immediately.
748 REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key));
749 c->resourcePriv().removeUniqueKey();
750 c->unref();
bsalomon0ea80f42015-02-11 10:49:59 -0800751 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
752 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
bsalomon33435572014-11-05 14:47:41 -0800753 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000754}
755
bsalomon8b79d232014-11-10 10:19:06 -0800756static void test_purge_invalidated(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800757 Mock mock(5, 30000);
758 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800759 GrResourceCache* cache = mock.cache();
bsalomon8b79d232014-11-10 10:19:06 -0800760
bsalomon8718aaf2015-02-19 07:24:21 -0800761 GrUniqueKey key1, key2, key3;
762 make_unique_key<0>(&key1, 1);
763 make_unique_key<0>(&key2, 2);
764 make_unique_key<0>(&key3, 3);
bsalomon8b79d232014-11-10 10:19:06 -0800765
bsalomon23e619c2015-02-06 11:54:28 -0800766 // Add three resources to the cache. Only c is usable as scratch.
bsalomon5236cf42015-01-14 10:42:08 -0800767 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
768 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon23e619c2015-02-06 11:54:28 -0800769 TestResource* c = TestResource::CreateScratch(context->getGpu(),
770 TestResource::kA_SimulatedProperty);
bsalomon8718aaf2015-02-19 07:24:21 -0800771 a->resourcePriv().setUniqueKey(key1);
772 b->resourcePriv().setUniqueKey(key2);
773 c->resourcePriv().setUniqueKey(key3);
bsalomon8b79d232014-11-10 10:19:06 -0800774 a->unref();
bsalomon23e619c2015-02-06 11:54:28 -0800775 // hold b until *after* the message is sent.
bsalomon8b79d232014-11-10 10:19:06 -0800776 c->unref();
777
bsalomon8718aaf2015-02-19 07:24:21 -0800778 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
779 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
780 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
bsalomon8b79d232014-11-10 10:19:06 -0800781 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
bsalomon23e619c2015-02-06 11:54:28 -0800782
bsalomon8718aaf2015-02-19 07:24:21 -0800783 typedef GrUniqueKeyInvalidatedMessage Msg;
784 typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus;
bsalomon23e619c2015-02-06 11:54:28 -0800785
786 // Invalidate two of the three, they should be purged and no longer accessible via their keys.
787 Bus::Post(Msg(key1));
788 Bus::Post(Msg(key2));
bsalomon0ea80f42015-02-11 10:49:59 -0800789 cache->purgeAsNeeded();
bsalomon23e619c2015-02-06 11:54:28 -0800790 // a should be deleted now, but we still have a ref on b.
bsalomon8718aaf2015-02-19 07:24:21 -0800791 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
792 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
bsalomon23e619c2015-02-06 11:54:28 -0800793 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8718aaf2015-02-19 07:24:21 -0800794 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
bsalomon8b79d232014-11-10 10:19:06 -0800795
796 // Invalidate the third.
bsalomon23e619c2015-02-06 11:54:28 -0800797 Bus::Post(Msg(key3));
bsalomon0ea80f42015-02-11 10:49:59 -0800798 cache->purgeAsNeeded();
bsalomon23e619c2015-02-06 11:54:28 -0800799 // we still have a ref on b, c should be recycled as scratch.
800 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8718aaf2015-02-19 07:24:21 -0800801 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3));
bsalomon71cb0c22014-11-14 12:10:14 -0800802
bsalomon23e619c2015-02-06 11:54:28 -0800803 // make b purgeable. It should be immediately deleted since it has no key.
804 b->unref();
805 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
806
807 // Make sure we actually get to c via it's scratch key, before we say goodbye.
808 GrScratchKey scratchKey;
809 TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
bsalomon0ea80f42015-02-11 10:49:59 -0800810 GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey);
bsalomon23e619c2015-02-06 11:54:28 -0800811 REPORTER_ASSERT(reporter, scratch == c);
812 SkSafeUnref(scratch);
813
814 // Get rid of c.
bsalomon0ea80f42015-02-11 10:49:59 -0800815 cache->purgeAllUnlocked();
816 scratch = cache->findAndRefScratchResource(scratchKey);
bsalomon71cb0c22014-11-14 12:10:14 -0800817 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
bsalomon0ea80f42015-02-11 10:49:59 -0800818 REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
819 REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
bsalomon23e619c2015-02-06 11:54:28 -0800820 REPORTER_ASSERT(reporter, !scratch);
821 SkSafeUnref(scratch);
bsalomon8b79d232014-11-10 10:19:06 -0800822}
823
bsalomon71cb0c22014-11-14 12:10:14 -0800824static void test_cache_chained_purge(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800825 Mock mock(3, 30000);
826 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800827 GrResourceCache* cache = mock.cache();
bsalomon8b79d232014-11-10 10:19:06 -0800828
bsalomon8718aaf2015-02-19 07:24:21 -0800829 GrUniqueKey key1, key2;
830 make_unique_key<0>(&key1, 1);
831 make_unique_key<0>(&key2, 2);
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000832
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000833
bsalomonc2f35b72015-01-23 07:19:22 -0800834 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
835 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8718aaf2015-02-19 07:24:21 -0800836 a->resourcePriv().setUniqueKey(key1);
837 b->resourcePriv().setUniqueKey(key2);
bsalomon820dd6c2014-11-05 12:09:45 -0800838
bsalomonc2f35b72015-01-23 07:19:22 -0800839 // Make a cycle
840 a->setUnrefWhenDestroyed(b);
841 b->setUnrefWhenDestroyed(a);
bsalomon71cb0c22014-11-14 12:10:14 -0800842
bsalomonc2f35b72015-01-23 07:19:22 -0800843 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon33435572014-11-05 14:47:41 -0800844
bsalomonc2f35b72015-01-23 07:19:22 -0800845 a->unref();
846 b->unref();
bsalomon8b79d232014-11-10 10:19:06 -0800847
bsalomonc2f35b72015-01-23 07:19:22 -0800848 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8b79d232014-11-10 10:19:06 -0800849
bsalomon0ea80f42015-02-11 10:49:59 -0800850 cache->purgeAllUnlocked();
bsalomonc2f35b72015-01-23 07:19:22 -0800851 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8b79d232014-11-10 10:19:06 -0800852
bsalomonc2f35b72015-01-23 07:19:22 -0800853 // Break the cycle
854 a->setUnrefWhenDestroyed(NULL);
855 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon33435572014-11-05 14:47:41 -0800856
bsalomon0ea80f42015-02-11 10:49:59 -0800857 cache->purgeAllUnlocked();
bsalomonc2f35b72015-01-23 07:19:22 -0800858 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000859}
860
bsalomon8b79d232014-11-10 10:19:06 -0800861static void test_resource_size_changed(skiatest::Reporter* reporter) {
bsalomon8718aaf2015-02-19 07:24:21 -0800862 GrUniqueKey key1, key2;
863 make_unique_key<0>(&key1, 1);
864 make_unique_key<0>(&key2, 2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000865
866 // Test changing resources sizes (both increase & decrease).
867 {
bsalomonc2f35b72015-01-23 07:19:22 -0800868 Mock mock(3, 30000);
869 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800870 GrResourceCache* cache = mock.cache();
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000871
bsalomon5236cf42015-01-14 10:42:08 -0800872 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8718aaf2015-02-19 07:24:21 -0800873 a->resourcePriv().setUniqueKey(key1);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000874 a->unref();
875
bsalomon5236cf42015-01-14 10:42:08 -0800876 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8718aaf2015-02-19 07:24:21 -0800877 b->resourcePriv().setUniqueKey(key2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000878 b->unref();
879
bsalomon0ea80f42015-02-11 10:49:59 -0800880 REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
881 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800882 {
bsalomon8718aaf2015-02-19 07:24:21 -0800883 SkAutoTUnref<TestResource> find2(
884 static_cast<TestResource*>(cache->findAndRefUniqueResource(key2)));
bsalomon8b79d232014-11-10 10:19:06 -0800885 find2->setSize(200);
bsalomon8718aaf2015-02-19 07:24:21 -0800886 SkAutoTUnref<TestResource> find1(
887 static_cast<TestResource*>(cache->findAndRefUniqueResource(key1)));
bsalomon8b79d232014-11-10 10:19:06 -0800888 find1->setSize(50);
889 }
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000890
bsalomon0ea80f42015-02-11 10:49:59 -0800891 REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes());
892 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000893 }
894
895 // Test increasing a resources size beyond the cache budget.
896 {
bsalomonc2f35b72015-01-23 07:19:22 -0800897 Mock mock(2, 300);
898 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800899 GrResourceCache* cache = mock.cache();
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000900
bsalomon5236cf42015-01-14 10:42:08 -0800901 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8b79d232014-11-10 10:19:06 -0800902 a->setSize(100);
bsalomon8718aaf2015-02-19 07:24:21 -0800903 a->resourcePriv().setUniqueKey(key1);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000904 a->unref();
905
bsalomon5236cf42015-01-14 10:42:08 -0800906 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8b79d232014-11-10 10:19:06 -0800907 b->setSize(100);
bsalomon8718aaf2015-02-19 07:24:21 -0800908 b->resourcePriv().setUniqueKey(key2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000909 b->unref();
910
bsalomon0ea80f42015-02-11 10:49:59 -0800911 REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
912 REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000913
bsalomon8b79d232014-11-10 10:19:06 -0800914 {
bsalomon8718aaf2015-02-19 07:24:21 -0800915 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(
916 cache->findAndRefUniqueResource(key2)));
bsalomon8b79d232014-11-10 10:19:06 -0800917 find2->setSize(201);
918 }
bsalomon8718aaf2015-02-19 07:24:21 -0800919 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000920
bsalomon0ea80f42015-02-11 10:49:59 -0800921 REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes());
922 REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000923 }
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000924}
925
bsalomon10e23ca2014-11-25 05:52:06 -0800926static void test_large_resource_count(skiatest::Reporter* reporter) {
bsalomon10e23ca2014-11-25 05:52:06 -0800927 // Set the cache size to double the resource count because we're going to create 2x that number
928 // resources, using two different key domains. Add a little slop to the bytes because we resize
929 // down to 1 byte after creating the resource.
bsalomonc2f35b72015-01-23 07:19:22 -0800930 static const int kResourceCnt = 2000;
bsalomon10e23ca2014-11-25 05:52:06 -0800931
bsalomonc2f35b72015-01-23 07:19:22 -0800932 Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
933 GrContext* context = mock.context();
bsalomon0ea80f42015-02-11 10:49:59 -0800934 GrResourceCache* cache = mock.cache();
bsalomon10e23ca2014-11-25 05:52:06 -0800935
936 for (int i = 0; i < kResourceCnt; ++i) {
bsalomon8718aaf2015-02-19 07:24:21 -0800937 GrUniqueKey key1, key2;
938 make_unique_key<1>(&key1, i);
939 make_unique_key<2>(&key2, i);
bsalomon10e23ca2014-11-25 05:52:06 -0800940
bsalomon24db3b12015-01-23 04:24:04 -0800941 TestResource* resource;
942
bsalomon10e23ca2014-11-25 05:52:06 -0800943 resource = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8718aaf2015-02-19 07:24:21 -0800944 resource->resourcePriv().setUniqueKey(key1);
bsalomon10e23ca2014-11-25 05:52:06 -0800945 resource->setSize(1);
946 resource->unref();
947
bsalomon10e23ca2014-11-25 05:52:06 -0800948 resource = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8718aaf2015-02-19 07:24:21 -0800949 resource->resourcePriv().setUniqueKey(key2);
bsalomon10e23ca2014-11-25 05:52:06 -0800950 resource->setSize(1);
951 resource->unref();
952 }
953
954 REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt);
bsalomon0ea80f42015-02-11 10:49:59 -0800955 REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt);
956 REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt);
957 REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt);
958 REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt);
bsalomon10e23ca2014-11-25 05:52:06 -0800959 for (int i = 0; i < kResourceCnt; ++i) {
bsalomon8718aaf2015-02-19 07:24:21 -0800960 GrUniqueKey key1, key2;
961 make_unique_key<1>(&key1, i);
962 make_unique_key<2>(&key2, i);
bsalomon24db3b12015-01-23 04:24:04 -0800963
bsalomon8718aaf2015-02-19 07:24:21 -0800964 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
965 REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
bsalomon10e23ca2014-11-25 05:52:06 -0800966 }
967
bsalomon0ea80f42015-02-11 10:49:59 -0800968 cache->purgeAllUnlocked();
bsalomon10e23ca2014-11-25 05:52:06 -0800969 REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0);
bsalomon0ea80f42015-02-11 10:49:59 -0800970 REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0);
971 REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0);
972 REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0);
973 REPORTER_ASSERT(reporter, cache->getResourceCount() == 0);
bsalomon10e23ca2014-11-25 05:52:06 -0800974
975 for (int i = 0; i < kResourceCnt; ++i) {
bsalomon8718aaf2015-02-19 07:24:21 -0800976 GrUniqueKey key1, key2;
977 make_unique_key<1>(&key1, i);
978 make_unique_key<2>(&key2, i);
bsalomon24db3b12015-01-23 04:24:04 -0800979
bsalomon8718aaf2015-02-19 07:24:21 -0800980 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
981 REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
bsalomon10e23ca2014-11-25 05:52:06 -0800982 }
983}
984
985
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000986////////////////////////////////////////////////////////////////////////////////
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +0000987DEF_GPUTEST(ResourceCache, reporter, factory) {
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000988 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
989 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
990 if (!GrContextFactory::IsRenderingGLContext(glType)) {
991 continue;
992 }
993 GrContext* context = factory->get(glType);
bsalomonfdcf2c02014-11-05 12:30:32 -0800994 if (NULL == context) {
995 continue;
996 }
bsalomonf2703d82014-10-28 14:33:06 -0700997 GrSurfaceDesc desc;
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000998 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomonf2703d82014-10-28 14:33:06 -0700999 desc.fFlags = kRenderTarget_GrSurfaceFlag;
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00001000 desc.fWidth = gWidth;
1001 desc.fHeight = gHeight;
reed69f6f002014-09-18 06:09:44 -07001002 SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
bsalomonafe30052015-01-16 07:32:33 -08001003 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
1004 SkSurface::kNo_Budgeted, info));
reed69f6f002014-09-18 06:09:44 -07001005 test_cache(reporter, context, surface->getCanvas());
bsalomon02a44a42015-02-19 09:09:00 -08001006 test_stencil_buffers(reporter, context);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00001007 }
bsalomon33435572014-11-05 14:47:41 -08001008
bsalomon8b79d232014-11-10 10:19:06 -08001009 // The below tests create their own mock contexts.
bsalomon71cb0c22014-11-14 12:10:14 -08001010 test_no_key(reporter);
bsalomon84c8e622014-11-17 09:33:27 -08001011 test_budgeting(reporter);
bsalomon5236cf42015-01-14 10:42:08 -08001012 test_unbudgeted(reporter);
bsalomonc2f35b72015-01-23 07:19:22 -08001013 test_unbudgeted_to_scratch(reporter);
bsalomon8718aaf2015-02-19 07:24:21 -08001014 test_duplicate_unique_key(reporter);
bsalomon8b79d232014-11-10 10:19:06 -08001015 test_duplicate_scratch_key(reporter);
bsalomon10e23ca2014-11-25 05:52:06 -08001016 test_remove_scratch_key(reporter);
bsalomon1c60dfe2015-01-21 09:32:40 -08001017 test_scratch_key_consistency(reporter);
bsalomon8b79d232014-11-10 10:19:06 -08001018 test_purge_invalidated(reporter);
bsalomon71cb0c22014-11-14 12:10:14 -08001019 test_cache_chained_purge(reporter);
bsalomon8b79d232014-11-10 10:19:06 -08001020 test_resource_size_changed(reporter);
bsalomon10e23ca2014-11-25 05:52:06 -08001021 test_large_resource_count(reporter);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00001022}
1023
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +00001024#endif