blob: f98aaf1a4d0e78ae011d55eefe514eecc599dfcd [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"
bsalomon33435572014-11-05 14:47:41 -080013#include "GrResourceCache2.h"
bsalomonbcf0a522014-10-08 08:40:09 -070014#include "SkCanvas.h"
bsalomon71cb0c22014-11-14 12:10:14 -080015#include "SkGr.h"
16#include "SkMessageBus.h"
reed69f6f002014-09-18 06:09:44 -070017#include "SkSurface.h"
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +000018#include "Test.h"
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000019
20static const int gWidth = 640;
21static const int gHeight = 480;
22
23////////////////////////////////////////////////////////////////////////////////
bsalomon33435572014-11-05 14:47:41 -080024static void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) {
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000025 const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
26
27 SkBitmap src;
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000028 src.allocN32Pixels(size.width(), size.height());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000029 src.eraseColor(SK_ColorBLACK);
30 size_t srcSize = src.getSize();
31
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000032 size_t initialCacheSize;
33 context->getResourceCacheUsage(NULL, &initialCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000034
35 int oldMaxNum;
36 size_t oldMaxBytes;
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000037 context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);
skia.committer@gmail.com17f1ae62013-08-09 07:01:22 +000038
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000039 // Set the cache limits so we can fit 10 "src" images and the
40 // max number of textures doesn't matter
41 size_t maxCacheSize = initialCacheSize + 10*srcSize;
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000042 context->setResourceCacheLimits(1000, maxCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000043
44 SkBitmap readback;
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000045 readback.allocN32Pixels(size.width(), size.height());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000046
47 for (int i = 0; i < 100; ++i) {
48 canvas->drawBitmap(src, 0, 0);
49 canvas->readPixels(size, &readback);
50
51 // "modify" the src texture
52 src.notifyPixelsChanged();
53
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000054 size_t curCacheSize;
55 context->getResourceCacheUsage(NULL, &curCacheSize);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000056
57 // we should never go over the size limit
58 REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
59 }
60
commit-bot@chromium.org95c20032014-05-09 14:29:32 +000061 context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +000062}
63
bsalomon6d3fe022014-07-25 08:35:45 -070064class TestResource : public GrGpuResource {
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000065 static const size_t kDefaultSize = 100;
bsalomon1c60dfe2015-01-21 09:32:40 -080066 enum ScratchConstructor { kScratchConstructor };
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +000067public:
68 SK_DECLARE_INST_COUNT(TestResource);
bsalomon1c60dfe2015-01-21 09:32:40 -080069 /** Property that distinctly categorizes the resource.
70 * For example, textures have width, height, ... */
71 enum SimulatedProperty { kProperty1_SimulatedProperty, kProperty2_SimulatedProperty };
72
bsalomon5236cf42015-01-14 10:42:08 -080073 TestResource(GrGpu* gpu, size_t size, GrGpuResource::LifeCycle lifeCycle)
74 : INHERITED(gpu, lifeCycle)
75 , fToDelete(NULL)
bsalomon1c60dfe2015-01-21 09:32:40 -080076 , fSize(size)
77 , fProperty(kProperty1_SimulatedProperty) {
bsalomon5236cf42015-01-14 10:42:08 -080078 ++fNumAlive;
79 this->registerWithCache();
80 }
81
82 TestResource(GrGpu* gpu, GrGpuResource::LifeCycle lifeCycle)
83 : INHERITED(gpu, lifeCycle)
bsalomondace19e2014-11-17 07:34:06 -080084 , fToDelete(NULL)
bsalomon1c60dfe2015-01-21 09:32:40 -080085 , fSize(kDefaultSize)
86 , fProperty(kProperty1_SimulatedProperty) {
bsalomondace19e2014-11-17 07:34:06 -080087 ++fNumAlive;
88 this->registerWithCache();
89 }
90
bsalomon8b79d232014-11-10 10:19:06 -080091 TestResource(GrGpu* gpu)
bsalomon5236cf42015-01-14 10:42:08 -080092 : INHERITED(gpu, kCached_LifeCycle)
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +000093 , fToDelete(NULL)
bsalomon1c60dfe2015-01-21 09:32:40 -080094 , fSize(kDefaultSize)
95 , fProperty(kProperty1_SimulatedProperty) {
bsalomon8b79d232014-11-10 10:19:06 -080096 ++fNumAlive;
97 this->registerWithCache();
98 }
99
bsalomonc2f35b72015-01-23 07:19:22 -0800100 static TestResource* CreateScratchTestResource(GrGpu* gpu,
101 SimulatedProperty property,
102 bool cached = true) {
103 return SkNEW_ARGS(TestResource, (gpu, property, cached, kScratchConstructor));
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000104 }
105
106 ~TestResource() {
bsalomon33435572014-11-05 14:47:41 -0800107 --fNumAlive;
bsalomon71cb0c22014-11-14 12:10:14 -0800108 SkSafeUnref(fToDelete);
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000109 }
110
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000111 void setSize(size_t size) {
112 fSize = size;
113 this->didChangeGpuMemorySize();
114 }
115
bsalomon33435572014-11-05 14:47:41 -0800116 static int NumAlive() { return fNumAlive; }
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000117
bsalomon71cb0c22014-11-14 12:10:14 -0800118 void setUnrefWhenDestroyed(TestResource* resource) {
119 SkRefCnt_SafeAssign(fToDelete, resource);
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000120 }
121
bsalomon1c60dfe2015-01-21 09:32:40 -0800122 static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
123 static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
124 GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
bsalomon24db3b12015-01-23 04:24:04 -0800125 for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
126 builder[i] = static_cast<uint32_t>(i + property);
bsalomon1c60dfe2015-01-21 09:32:40 -0800127 }
128 }
129
130 static size_t ExpectedScratchKeySize() {
131 return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
132 }
133
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000134private:
bsalomon24db3b12015-01-23 04:24:04 -0800135 static const int kScratchKeyFieldCnt = 6;
bsalomon1c60dfe2015-01-21 09:32:40 -0800136
bsalomonc2f35b72015-01-23 07:19:22 -0800137 TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor)
138 : INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle)
bsalomon1c60dfe2015-01-21 09:32:40 -0800139 , fToDelete(NULL)
140 , fSize(kDefaultSize)
141 , fProperty(property) {
142 GrScratchKey scratchKey;
143 ComputeScratchKey(fProperty, &scratchKey);
144 this->setScratchKey(scratchKey);
145 ++fNumAlive;
146 this->registerWithCache();
147 }
148
bsalomon69ed47f2014-11-12 11:13:39 -0800149 size_t onGpuMemorySize() const SK_OVERRIDE { return fSize; }
150
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000151 TestResource* fToDelete;
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000152 size_t fSize;
bsalomon33435572014-11-05 14:47:41 -0800153 static int fNumAlive;
bsalomon1c60dfe2015-01-21 09:32:40 -0800154 SimulatedProperty fProperty;
bsalomon6d3fe022014-07-25 08:35:45 -0700155 typedef GrGpuResource INHERITED;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000156};
bsalomon33435572014-11-05 14:47:41 -0800157int TestResource::fNumAlive = 0;
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000158
bsalomonc2f35b72015-01-23 07:19:22 -0800159class Mock {
160public:
161 Mock(int maxCnt, size_t maxBytes) {
162 fContext.reset(GrContext::CreateMockContext());
163 SkASSERT(fContext);
164 fContext->setResourceCacheLimits(maxCnt, maxBytes);
165 GrResourceCache2* cache2 = fContext->getResourceCache2();
166 cache2->purgeAllUnlocked();
167 SkASSERT(0 == cache2->getResourceCount() && 0 == cache2->getResourceBytes());
bsalomon71cb0c22014-11-14 12:10:14 -0800168 }
bsalomonc2f35b72015-01-23 07:19:22 -0800169
170 GrResourceCache2* cache() { return fContext->getResourceCache2(); }
171
172 GrContext* context() { return fContext; }
173
174private:
175 SkAutoTUnref<GrContext> fContext;
176};
177
178static void test_no_key(skiatest::Reporter* reporter) {
179 Mock mock(10, 30000);
180 GrContext* context = mock.context();
181 GrResourceCache2* cache2 = mock.cache();
bsalomon71cb0c22014-11-14 12:10:14 -0800182
183 // Create a bunch of resources with no keys
bsalomon5236cf42015-01-14 10:42:08 -0800184 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
185 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
186 TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
187 TestResource* d = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon71cb0c22014-11-14 12:10:14 -0800188 a->setSize(11);
189 b->setSize(12);
190 c->setSize(13);
191 d->setSize(14);
192
193 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
194 REPORTER_ASSERT(reporter, 4 == cache2->getResourceCount());
195 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
196 d->gpuMemorySize() == cache2->getResourceBytes());
197
198 // Should be safe to purge without deleting the resources since we still have refs.
199 cache2->purgeAllUnlocked();
200 REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
201
202 // Since the resources have neither content nor scratch keys, delete immediately upon unref.
203
204 a->unref();
205 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
206 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
207 REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
208 cache2->getResourceBytes());
209
210 c->unref();
211 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
212 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
213 REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
214 cache2->getResourceBytes());
215
216 d->unref();
217 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
218 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
219 REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache2->getResourceBytes());
220
221 b->unref();
222 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
223 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
224 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
225}
226
bsalomon24db3b12015-01-23 04:24:04 -0800227// Each integer passed as a template param creates a new domain.
228template <int> static void make_content_key(GrContentKey* key, int data) {
229 static GrContentKey::Domain d = GrContentKey::GenerateDomain();
230 GrContentKey::Builder builder(key, d, 1);
231 builder[0] = data;
232}
233
bsalomon84c8e622014-11-17 09:33:27 -0800234static void test_budgeting(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800235 Mock mock(10, 300);
236 GrContext* context = mock.context();
237 GrResourceCache2* cache2 = mock.cache();
bsalomondace19e2014-11-17 07:34:06 -0800238
bsalomon24db3b12015-01-23 04:24:04 -0800239 GrContentKey contentKey;
240 make_content_key<0>(&contentKey, 0);
bsalomondace19e2014-11-17 07:34:06 -0800241
242 // Create a scratch, a content, and a wrapped resource
bsalomon1c60dfe2015-01-21 09:32:40 -0800243 TestResource* scratch =
244 TestResource::CreateScratchTestResource(context->getGpu(),
245 TestResource::kProperty2_SimulatedProperty);
bsalomondace19e2014-11-17 07:34:06 -0800246 scratch->setSize(10);
bsalomon5236cf42015-01-14 10:42:08 -0800247 TestResource* content = SkNEW_ARGS(TestResource, (context->getGpu()));
248 content->setSize(11);
bsalomondace19e2014-11-17 07:34:06 -0800249 REPORTER_ASSERT(reporter, content->cacheAccess().setContentKey(contentKey));
bsalomon5236cf42015-01-14 10:42:08 -0800250 TestResource* wrapped = SkNEW_ARGS(TestResource,
251 (context->getGpu(), GrGpuResource::kWrapped_LifeCycle));
252 wrapped->setSize(12);
253 TestResource* unbudgeted = SkNEW_ARGS(TestResource,
254 (context->getGpu(), GrGpuResource::kUncached_LifeCycle));
bsalomon84c8e622014-11-17 09:33:27 -0800255 unbudgeted->setSize(13);
bsalomondace19e2014-11-17 07:34:06 -0800256
257 // Make sure we can't add a content key to the wrapped resource
bsalomon24db3b12015-01-23 04:24:04 -0800258 GrContentKey contentKey2;
259 make_content_key<0>(&contentKey2, 1);
bsalomondace19e2014-11-17 07:34:06 -0800260 REPORTER_ASSERT(reporter, !wrapped->cacheAccess().setContentKey(contentKey2));
261 REPORTER_ASSERT(reporter, NULL == cache2->findAndRefContentResource(contentKey2));
262
263 // Make sure sizes are as we expect
bsalomon84c8e622014-11-17 09:33:27 -0800264 REPORTER_ASSERT(reporter, 4 == cache2->getResourceCount());
bsalomondace19e2014-11-17 07:34:06 -0800265 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() +
bsalomon84c8e622014-11-17 09:33:27 -0800266 wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
267 cache2->getResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800268 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
269 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() ==
270 cache2->getBudgetedResourceBytes());
271
272 // Our refs mean that the resources are non purgable.
273 cache2->purgeAllUnlocked();
bsalomon84c8e622014-11-17 09:33:27 -0800274 REPORTER_ASSERT(reporter, 4 == cache2->getResourceCount());
bsalomondace19e2014-11-17 07:34:06 -0800275 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() +
bsalomon84c8e622014-11-17 09:33:27 -0800276 wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
277 cache2->getResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800278 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
279 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() ==
280 cache2->getBudgetedResourceBytes());
281
282 // Unreffing the wrapped resource should free it right away.
283 wrapped->unref();
bsalomon84c8e622014-11-17 09:33:27 -0800284 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
285 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + content->gpuMemorySize() +
286 unbudgeted->gpuMemorySize() == cache2->getResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800287
bsalomon84c8e622014-11-17 09:33:27 -0800288 // Now try freeing the budgeted resources first
bsalomon5236cf42015-01-14 10:42:08 -0800289 wrapped = SkNEW_ARGS(TestResource, (context->getGpu(), GrGpuResource::kWrapped_LifeCycle));
bsalomondace19e2014-11-17 07:34:06 -0800290 scratch->setSize(12);
291 content->unref();
292 cache2->purgeAllUnlocked();
bsalomon84c8e622014-11-17 09:33:27 -0800293 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
294 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() +
295 unbudgeted->gpuMemorySize() == cache2->getResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800296 REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
297 REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache2->getBudgetedResourceBytes());
298
299 scratch->unref();
300 cache2->purgeAllUnlocked();
bsalomon84c8e622014-11-17 09:33:27 -0800301 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
302 REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() ==
303 cache2->getResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800304 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
305 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
306
307 wrapped->unref();
bsalomon84c8e622014-11-17 09:33:27 -0800308 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
309 REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache2->getResourceBytes());
310 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
311 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
312
313 unbudgeted->unref();
bsalomondace19e2014-11-17 07:34:06 -0800314 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
315 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
bsalomon84c8e622014-11-17 09:33:27 -0800316 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
317 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
bsalomondace19e2014-11-17 07:34:06 -0800318}
319
bsalomon5236cf42015-01-14 10:42:08 -0800320static void test_unbudgeted(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800321 Mock mock(10, 30000);
322 GrContext* context = mock.context();
323 GrResourceCache2* cache2 = mock.cache();
bsalomon5236cf42015-01-14 10:42:08 -0800324
bsalomon24db3b12015-01-23 04:24:04 -0800325 GrContentKey contentKey;
326 make_content_key<0>(&contentKey, 0);
bsalomon5236cf42015-01-14 10:42:08 -0800327
328 TestResource* scratch;
329 TestResource* content;
330 TestResource* wrapped;
331 TestResource* unbudgeted;
332
333 // A large uncached or wrapped resource shouldn't evict anything.
bsalomon1c60dfe2015-01-21 09:32:40 -0800334 scratch = TestResource::CreateScratchTestResource(context->getGpu(),
335 TestResource::kProperty2_SimulatedProperty);
bsalomon5236cf42015-01-14 10:42:08 -0800336 scratch->setSize(10);
337 scratch->unref();
338 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
339 REPORTER_ASSERT(reporter, 10 == cache2->getResourceBytes());
340 REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
341 REPORTER_ASSERT(reporter, 10 == cache2->getBudgetedResourceBytes());
342
343 content = SkNEW_ARGS(TestResource, (context->getGpu()));
344 content->setSize(11);
345 REPORTER_ASSERT(reporter, content->cacheAccess().setContentKey(contentKey));
346 content->unref();
347 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
348 REPORTER_ASSERT(reporter, 21 == cache2->getResourceBytes());
349 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
350 REPORTER_ASSERT(reporter, 21 == cache2->getBudgetedResourceBytes());
351
352 size_t large = 2 * cache2->getResourceBytes();
353 unbudgeted = SkNEW_ARGS(TestResource,
354 (context->getGpu(), large, GrGpuResource::kUncached_LifeCycle));
355 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
356 REPORTER_ASSERT(reporter, 21 + large == cache2->getResourceBytes());
357 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
358 REPORTER_ASSERT(reporter, 21 == cache2->getBudgetedResourceBytes());
359
360 unbudgeted->unref();
361 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
362 REPORTER_ASSERT(reporter, 21 == cache2->getResourceBytes());
363 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
364 REPORTER_ASSERT(reporter, 21 == cache2->getBudgetedResourceBytes());
365
366 wrapped = SkNEW_ARGS(TestResource,
367 (context->getGpu(), large, GrGpuResource::kWrapped_LifeCycle));
368 REPORTER_ASSERT(reporter, 3 == cache2->getResourceCount());
369 REPORTER_ASSERT(reporter, 21 + large == cache2->getResourceBytes());
370 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
371 REPORTER_ASSERT(reporter, 21 == cache2->getBudgetedResourceBytes());
372
373 wrapped->unref();
374 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
375 REPORTER_ASSERT(reporter, 21 == cache2->getResourceBytes());
376 REPORTER_ASSERT(reporter, 2 == cache2->getBudgetedResourceCount());
377 REPORTER_ASSERT(reporter, 21 == cache2->getBudgetedResourceBytes());
378
379 cache2->purgeAllUnlocked();
380 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
381 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
382 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
383 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
384}
385
bsalomonc2f35b72015-01-23 07:19:22 -0800386static void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
387 Mock mock(10, 300);
388 GrContext* context = mock.context();
389 GrResourceCache2* cache2 = mock.cache();
390
391 TestResource* resource =
392 TestResource::CreateScratchTestResource(context->getGpu(),
393 TestResource::kProperty1_SimulatedProperty, false);
394 GrScratchKey key;
395 TestResource::ComputeScratchKey(TestResource::kProperty1_SimulatedProperty, &key);
396
397 size_t size = resource->gpuMemorySize();
398 for (int i = 0; i < 2; ++i) {
399 // Since this resource is unbudgeted, it should not be reachable as scratch.
400 REPORTER_ASSERT(reporter, resource->cacheAccess().getScratchKey() == key);
401 REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
402 REPORTER_ASSERT(reporter, !resource->cacheAccess().isBudgeted());
403 REPORTER_ASSERT(reporter, NULL == cache2->findAndRefScratchResource(key));
404 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
405 REPORTER_ASSERT(reporter, size == cache2->getResourceBytes());
406 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
407 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
408
409 // Once it is unrefed, it should become available as scratch.
410 resource->unref();
411 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
412 REPORTER_ASSERT(reporter, size == cache2->getResourceBytes());
413 REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
414 REPORTER_ASSERT(reporter, size == cache2->getBudgetedResourceBytes());
415 resource = static_cast<TestResource*>(cache2->findAndRefScratchResource(key));
416 REPORTER_ASSERT(reporter, resource);
417 REPORTER_ASSERT(reporter, resource->cacheAccess().getScratchKey() == key);
418 REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
419 REPORTER_ASSERT(reporter, resource->cacheAccess().isBudgeted());
420
421 if (0 == i) {
422 // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
423 // the above tests again.
424 resource->cacheAccess().makeUnbudgeted();
425 } else {
426 // After the second time around, try removing the scratch key
427 resource->cacheAccess().removeScratchKey();
428 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
429 REPORTER_ASSERT(reporter, size == cache2->getResourceBytes());
430 REPORTER_ASSERT(reporter, 1 == cache2->getBudgetedResourceCount());
431 REPORTER_ASSERT(reporter, size == cache2->getBudgetedResourceBytes());
432 REPORTER_ASSERT(reporter, !resource->cacheAccess().getScratchKey().isValid());
433 REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
434 REPORTER_ASSERT(reporter, resource->cacheAccess().isBudgeted());
435
436 // now when it is unrefed it should die since it has no key.
437 resource->unref();
438 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
439 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
440 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceCount());
441 REPORTER_ASSERT(reporter, 0 == cache2->getBudgetedResourceBytes());
442 }
bsalomon8b79d232014-11-10 10:19:06 -0800443 }
bsalomonc2f35b72015-01-23 07:19:22 -0800444}
445
446static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
447 Mock mock(5, 30000);
448 GrContext* context = mock.context();
449 GrResourceCache2* cache2 = mock.cache();
bsalomon8b79d232014-11-10 10:19:06 -0800450
bsalomon8b79d232014-11-10 10:19:06 -0800451 // Create two resources that have the same scratch key.
bsalomon1c60dfe2015-01-21 09:32:40 -0800452 TestResource* a =
453 TestResource::CreateScratchTestResource(context->getGpu(),
454 TestResource::kProperty2_SimulatedProperty);
455 TestResource* b =
456 TestResource::CreateScratchTestResource(context->getGpu(),
457 TestResource::kProperty2_SimulatedProperty);
bsalomon8b79d232014-11-10 10:19:06 -0800458 a->setSize(11);
459 b->setSize(12);
bsalomon1c60dfe2015-01-21 09:32:40 -0800460 GrScratchKey scratchKey1;
461 TestResource::ComputeScratchKey(TestResource::kProperty1_SimulatedProperty, &scratchKey1);
462 // Check for negative case consistency. (leaks upon test failure.)
463 REPORTER_ASSERT(reporter, NULL == cache2->findAndRefScratchResource(scratchKey1));
464
465 GrScratchKey scratchKey;
466 TestResource::ComputeScratchKey(TestResource::kProperty2_SimulatedProperty, &scratchKey);
467
bsalomon8b79d232014-11-10 10:19:06 -0800468 // Scratch resources are registered with GrResourceCache2 just by existing. There are 2.
bsalomon8b79d232014-11-10 10:19:06 -0800469 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
470 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey(scratchKey));)
bsalomon71cb0c22014-11-14 12:10:14 -0800471 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
472 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
473 cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800474
475 // Our refs mean that the resources are non purgable.
bsalomon71cb0c22014-11-14 12:10:14 -0800476 cache2->purgeAllUnlocked();
bsalomon8b79d232014-11-10 10:19:06 -0800477 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon71cb0c22014-11-14 12:10:14 -0800478 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800479
480 // Unref but don't purge
481 a->unref();
482 b->unref();
483 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
484 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey(scratchKey));)
485
486 // Purge again. This time resources should be purgable.
bsalomon71cb0c22014-11-14 12:10:14 -0800487 cache2->purgeAllUnlocked();
bsalomon8b79d232014-11-10 10:19:06 -0800488 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
bsalomon71cb0c22014-11-14 12:10:14 -0800489 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800490 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));)
491}
492
bsalomon10e23ca2014-11-25 05:52:06 -0800493static void test_remove_scratch_key(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800494 Mock mock(5, 30000);
495 GrContext* context = mock.context();
496 GrResourceCache2* cache2 = mock.cache();
bsalomon10e23ca2014-11-25 05:52:06 -0800497
bsalomon10e23ca2014-11-25 05:52:06 -0800498 // Create two resources that have the same scratch key.
bsalomon1c60dfe2015-01-21 09:32:40 -0800499 TestResource* a =
500 TestResource::CreateScratchTestResource(context->getGpu(),
501 TestResource::kProperty2_SimulatedProperty);
502 TestResource* b =
503 TestResource::CreateScratchTestResource(context->getGpu(),
504 TestResource::kProperty2_SimulatedProperty);
bsalomon10e23ca2014-11-25 05:52:06 -0800505 a->unref();
506 b->unref();
507
bsalomon1c60dfe2015-01-21 09:32:40 -0800508
509 GrScratchKey scratchKey;
510 // Ensure that scratch key lookup is correct for negative case.
511 TestResource::ComputeScratchKey(TestResource::kProperty1_SimulatedProperty, &scratchKey);
512 // (following leaks upon test failure).
513 REPORTER_ASSERT(reporter, cache2->findAndRefScratchResource(scratchKey) == NULL);
514
bsalomon10e23ca2014-11-25 05:52:06 -0800515 // Scratch resources are registered with GrResourceCache2 just by existing. There are 2.
bsalomon1c60dfe2015-01-21 09:32:40 -0800516 TestResource::ComputeScratchKey(TestResource::kProperty2_SimulatedProperty, &scratchKey);
bsalomon10e23ca2014-11-25 05:52:06 -0800517 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
518 SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache2->countScratchEntriesForKey(scratchKey));)
519 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
520
521 // Find the first resource and remove its scratch key
522 GrGpuResource* find;
523 find = cache2->findAndRefScratchResource(scratchKey);
524 find->cacheAccess().removeScratchKey();
525 // It's still alive, but not cached by scratch key anymore
526 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
527 SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache2->countScratchEntriesForKey(scratchKey));)
528 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
529
530 // The cache should immediately delete it when it's unrefed since it isn't accessible.
531 find->unref();
532 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
533 SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache2->countScratchEntriesForKey(scratchKey));)
534 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
535
536 // Repeat for the second resource.
537 find = cache2->findAndRefScratchResource(scratchKey);
538 find->cacheAccess().removeScratchKey();
539 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
540 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));)
541 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
542
543 // Should be able to call this multiple times with no problem.
544 find->cacheAccess().removeScratchKey();
545 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
546 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));)
547 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
548
549 find->unref();
550 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
551 SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache2->countScratchEntriesForKey(scratchKey));)
552 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
553}
554
bsalomon1c60dfe2015-01-21 09:32:40 -0800555static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800556 Mock mock(5, 30000);
557 GrContext* context = mock.context();
558 GrResourceCache2* cache2 = mock.cache();
bsalomon1c60dfe2015-01-21 09:32:40 -0800559
560 // Create two resources that have the same scratch key.
561 TestResource* a =
562 TestResource::CreateScratchTestResource(context->getGpu(),
563 TestResource::kProperty2_SimulatedProperty);
564 TestResource* b =
565 TestResource::CreateScratchTestResource(context->getGpu(),
566 TestResource::kProperty2_SimulatedProperty);
567 a->unref();
568 b->unref();
569
570 GrScratchKey scratchKey;
571 // Ensure that scratch key comparison and assignment is consistent.
572 GrScratchKey scratchKey1;
573 TestResource::ComputeScratchKey(TestResource::kProperty1_SimulatedProperty, &scratchKey1);
574 GrScratchKey scratchKey2;
575 TestResource::ComputeScratchKey(TestResource::kProperty2_SimulatedProperty, &scratchKey2);
576 REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize());
577 REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2);
578 REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1);
579 scratchKey = scratchKey1;
580 REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
581 REPORTER_ASSERT(reporter, scratchKey1 == scratchKey);
582 REPORTER_ASSERT(reporter, scratchKey == scratchKey1);
583 REPORTER_ASSERT(reporter, scratchKey2 != scratchKey);
584 REPORTER_ASSERT(reporter, scratchKey != scratchKey2);
585 scratchKey = scratchKey2;
586 REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
587 REPORTER_ASSERT(reporter, scratchKey1 != scratchKey);
588 REPORTER_ASSERT(reporter, scratchKey != scratchKey1);
589 REPORTER_ASSERT(reporter, scratchKey2 == scratchKey);
590 REPORTER_ASSERT(reporter, scratchKey == scratchKey2);
591
592 // Ensure that scratch key lookup is correct for negative case.
593 TestResource::ComputeScratchKey(TestResource::kProperty1_SimulatedProperty, &scratchKey);
594 // (following leaks upon test failure).
595 REPORTER_ASSERT(reporter, cache2->findAndRefScratchResource(scratchKey) == NULL);
596
597 // Find the first resource with a scratch key and a copy of a scratch key.
598 TestResource::ComputeScratchKey(TestResource::kProperty2_SimulatedProperty, &scratchKey);
599 GrGpuResource* find = cache2->findAndRefScratchResource(scratchKey);
600 REPORTER_ASSERT(reporter, find != NULL);
601 find->unref();
602
603 scratchKey2 = scratchKey;
604 find = cache2->findAndRefScratchResource(scratchKey2);
605 REPORTER_ASSERT(reporter, find != NULL);
606 REPORTER_ASSERT(reporter, find == a || find == b);
607
608 GrGpuResource* find2 = cache2->findAndRefScratchResource(scratchKey2);
609 REPORTER_ASSERT(reporter, find2 != NULL);
610 REPORTER_ASSERT(reporter, find2 == a || find2 == b);
611 REPORTER_ASSERT(reporter, find2 != find);
612 find2->unref();
613 find->unref();
614}
615
bsalomon8b79d232014-11-10 10:19:06 -0800616static void test_duplicate_content_key(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800617 Mock mock(5, 30000);
618 GrContext* context = mock.context();
619 GrResourceCache2* cache2 = mock.cache();
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000620
bsalomon24db3b12015-01-23 04:24:04 -0800621 GrContentKey key;
622 make_content_key<0>(&key, 0);
bsalomon8b79d232014-11-10 10:19:06 -0800623
bsalomon8b79d232014-11-10 10:19:06 -0800624 // Create two resources that we will attempt to register with the same content key.
bsalomon5236cf42015-01-14 10:42:08 -0800625 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
626 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8b79d232014-11-10 10:19:06 -0800627 a->setSize(11);
628 b->setSize(12);
bsalomon71cb0c22014-11-14 12:10:14 -0800629
630 // Can't set the same content key on two resources.
631 REPORTER_ASSERT(reporter, a->cacheAccess().setContentKey(key));
632 REPORTER_ASSERT(reporter, !b->cacheAccess().setContentKey(key));
633
634 // Still have two resources because b is still reffed.
635 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
636 REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
637 cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800638 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
639
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000640 b->unref();
bsalomon71cb0c22014-11-14 12:10:14 -0800641 // Now b should be gone.
642 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
643 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800644 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000645
bsalomon71cb0c22014-11-14 12:10:14 -0800646 cache2->purgeAllUnlocked();
647 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
648 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes());
649 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
650
651 // Drop the ref on a but it isn't immediately purged as it still has a valid scratch key.
bsalomon8b79d232014-11-10 10:19:06 -0800652 a->unref();
bsalomon71cb0c22014-11-14 12:10:14 -0800653 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
654 REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache2->getResourceBytes());
655 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
656
657 cache2->purgeAllUnlocked();
658 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
659 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
bsalomon33435572014-11-05 14:47:41 -0800660 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000661}
662
bsalomon8b79d232014-11-10 10:19:06 -0800663static void test_purge_invalidated(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800664 Mock mock(5, 30000);
665 GrContext* context = mock.context();
666 GrResourceCache2* cache2 = mock.cache();
bsalomon8b79d232014-11-10 10:19:06 -0800667
bsalomon24db3b12015-01-23 04:24:04 -0800668 GrContentKey key1, key2, key3;
669 make_content_key<0>(&key1, 1);
670 make_content_key<0>(&key2, 2);
671 make_content_key<0>(&key3, 3);
bsalomon8b79d232014-11-10 10:19:06 -0800672
bsalomon8b79d232014-11-10 10:19:06 -0800673 // Add three resources to the cache.
bsalomon5236cf42015-01-14 10:42:08 -0800674 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
675 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
676 TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon71cb0c22014-11-14 12:10:14 -0800677 a->cacheAccess().setContentKey(key1);
678 b->cacheAccess().setContentKey(key2);
679 c->cacheAccess().setContentKey(key3);
bsalomon8b79d232014-11-10 10:19:06 -0800680 a->unref();
681 b->unref();
682 c->unref();
683
684 REPORTER_ASSERT(reporter, cache2->hasContentKey(key1));
685 REPORTER_ASSERT(reporter, cache2->hasContentKey(key2));
686 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3));
687
688 // Invalidate two of the three, they should be purged and destroyed.
689 REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
690 const GrResourceInvalidatedMessage msg1 = { key1 };
691 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg1);
692 const GrResourceInvalidatedMessage msg2 = { key2 };
693 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg2);
bsalomon6d4488c2014-11-11 07:27:16 -0800694#if 0 // Disabled until reimplemented in GrResourceCache2.
bsalomon71cb0c22014-11-14 12:10:14 -0800695 cache2->purgeAsNeeded();
bsalomon8b79d232014-11-10 10:19:06 -0800696 REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
697 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1));
698 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key2));
699 REPORTER_ASSERT(reporter, cache2->hasContentKey(key3));
bsalomon6d4488c2014-11-11 07:27:16 -0800700#endif
bsalomon8b79d232014-11-10 10:19:06 -0800701
702 // Invalidate the third.
703 const GrResourceInvalidatedMessage msg3 = { key3 };
704 SkMessageBus<GrResourceInvalidatedMessage>::Post(msg3);
bsalomon6d4488c2014-11-11 07:27:16 -0800705#if 0 // Disabled until reimplemented in GrResourceCache2.
bsalomon71cb0c22014-11-14 12:10:14 -0800706 cache2->purgeAsNeeded();
bsalomon8b79d232014-11-10 10:19:06 -0800707 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
708 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key3));
bsalomon6d4488c2014-11-11 07:27:16 -0800709#endif
bsalomon71cb0c22014-11-14 12:10:14 -0800710
711 cache2->purgeAllUnlocked();
712 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
713 REPORTER_ASSERT(reporter, 0 == cache2->getResourceCount());
714 REPORTER_ASSERT(reporter, 0 == cache2->getResourceBytes());
bsalomon8b79d232014-11-10 10:19:06 -0800715}
716
bsalomon71cb0c22014-11-14 12:10:14 -0800717static void test_cache_chained_purge(skiatest::Reporter* reporter) {
bsalomonc2f35b72015-01-23 07:19:22 -0800718 Mock mock(3, 30000);
719 GrContext* context = mock.context();
720 GrResourceCache2* cache2 = mock.cache();
bsalomon8b79d232014-11-10 10:19:06 -0800721
bsalomon24db3b12015-01-23 04:24:04 -0800722 GrContentKey key1, key2;
723 make_content_key<0>(&key1, 1);
724 make_content_key<0>(&key2, 2);
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000725
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000726
bsalomonc2f35b72015-01-23 07:19:22 -0800727 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
728 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
729 a->cacheAccess().setContentKey(key1);
730 b->cacheAccess().setContentKey(key2);
bsalomon820dd6c2014-11-05 12:09:45 -0800731
bsalomonc2f35b72015-01-23 07:19:22 -0800732 // Make a cycle
733 a->setUnrefWhenDestroyed(b);
734 b->setUnrefWhenDestroyed(a);
bsalomon71cb0c22014-11-14 12:10:14 -0800735
bsalomonc2f35b72015-01-23 07:19:22 -0800736 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon33435572014-11-05 14:47:41 -0800737
bsalomonc2f35b72015-01-23 07:19:22 -0800738 a->unref();
739 b->unref();
bsalomon8b79d232014-11-10 10:19:06 -0800740
bsalomonc2f35b72015-01-23 07:19:22 -0800741 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8b79d232014-11-10 10:19:06 -0800742
bsalomonc2f35b72015-01-23 07:19:22 -0800743 cache2->purgeAllUnlocked();
744 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon8b79d232014-11-10 10:19:06 -0800745
bsalomonc2f35b72015-01-23 07:19:22 -0800746 // Break the cycle
747 a->setUnrefWhenDestroyed(NULL);
748 REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
bsalomon33435572014-11-05 14:47:41 -0800749
bsalomonc2f35b72015-01-23 07:19:22 -0800750 cache2->purgeAllUnlocked();
751 REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
commit-bot@chromium.orgbd58feb2014-01-17 17:56:21 +0000752}
753
bsalomon8b79d232014-11-10 10:19:06 -0800754static void test_resource_size_changed(skiatest::Reporter* reporter) {
bsalomon24db3b12015-01-23 04:24:04 -0800755 GrContentKey key1, key2;
756 make_content_key<0>(&key1, 1);
757 make_content_key<0>(&key2, 2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000758
759 // Test changing resources sizes (both increase & decrease).
760 {
bsalomonc2f35b72015-01-23 07:19:22 -0800761 Mock mock(3, 30000);
762 GrContext* context = mock.context();
763 GrResourceCache2* cache2 = mock.cache();
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000764
bsalomon5236cf42015-01-14 10:42:08 -0800765 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon71cb0c22014-11-14 12:10:14 -0800766 a->cacheAccess().setContentKey(key1);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000767 a->unref();
768
bsalomon5236cf42015-01-14 10:42:08 -0800769 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon71cb0c22014-11-14 12:10:14 -0800770 b->cacheAccess().setContentKey(key2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000771 b->unref();
772
bsalomon71cb0c22014-11-14 12:10:14 -0800773 REPORTER_ASSERT(reporter, 200 == cache2->getResourceBytes());
774 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
bsalomon8b79d232014-11-10 10:19:06 -0800775 {
776 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->findAndRefContentResource(key2)));
777 find2->setSize(200);
778 SkAutoTUnref<TestResource> find1(static_cast<TestResource*>(cache2->findAndRefContentResource(key1)));
779 find1->setSize(50);
780 }
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000781
bsalomon71cb0c22014-11-14 12:10:14 -0800782 REPORTER_ASSERT(reporter, 250 == cache2->getResourceBytes());
783 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000784 }
785
786 // Test increasing a resources size beyond the cache budget.
787 {
bsalomonc2f35b72015-01-23 07:19:22 -0800788 Mock mock(2, 300);
789 GrContext* context = mock.context();
790 GrResourceCache2* cache2 = mock.cache();
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000791
bsalomon5236cf42015-01-14 10:42:08 -0800792 TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8b79d232014-11-10 10:19:06 -0800793 a->setSize(100);
bsalomon71cb0c22014-11-14 12:10:14 -0800794 a->cacheAccess().setContentKey(key1);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000795 a->unref();
796
bsalomon5236cf42015-01-14 10:42:08 -0800797 TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon8b79d232014-11-10 10:19:06 -0800798 b->setSize(100);
bsalomon71cb0c22014-11-14 12:10:14 -0800799 b->cacheAccess().setContentKey(key2);
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000800 b->unref();
801
bsalomon71cb0c22014-11-14 12:10:14 -0800802 REPORTER_ASSERT(reporter, 200 == cache2->getResourceBytes());
803 REPORTER_ASSERT(reporter, 2 == cache2->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000804
bsalomon8b79d232014-11-10 10:19:06 -0800805 {
806 SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(cache2->findAndRefContentResource(key2)));
807 find2->setSize(201);
808 }
809 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1));
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000810
bsalomon71cb0c22014-11-14 12:10:14 -0800811 REPORTER_ASSERT(reporter, 201 == cache2->getResourceBytes());
812 REPORTER_ASSERT(reporter, 1 == cache2->getResourceCount());
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000813 }
commit-bot@chromium.org11c6b392014-05-05 19:09:13 +0000814}
815
bsalomon10e23ca2014-11-25 05:52:06 -0800816static void test_large_resource_count(skiatest::Reporter* reporter) {
bsalomon10e23ca2014-11-25 05:52:06 -0800817 // Set the cache size to double the resource count because we're going to create 2x that number
818 // resources, using two different key domains. Add a little slop to the bytes because we resize
819 // down to 1 byte after creating the resource.
bsalomonc2f35b72015-01-23 07:19:22 -0800820 static const int kResourceCnt = 2000;
bsalomon10e23ca2014-11-25 05:52:06 -0800821
bsalomonc2f35b72015-01-23 07:19:22 -0800822 Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
823 GrContext* context = mock.context();
824 GrResourceCache2* cache2 = mock.cache();
bsalomon10e23ca2014-11-25 05:52:06 -0800825
826 for (int i = 0; i < kResourceCnt; ++i) {
bsalomon24db3b12015-01-23 04:24:04 -0800827 GrContentKey key1, key2;
828 make_content_key<1>(&key1, i);
829 make_content_key<2>(&key2, i);
bsalomon10e23ca2014-11-25 05:52:06 -0800830
bsalomon24db3b12015-01-23 04:24:04 -0800831 TestResource* resource;
832
bsalomon10e23ca2014-11-25 05:52:06 -0800833 resource = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon24db3b12015-01-23 04:24:04 -0800834 resource->cacheAccess().setContentKey(key1);
bsalomon10e23ca2014-11-25 05:52:06 -0800835 resource->setSize(1);
836 resource->unref();
837
bsalomon10e23ca2014-11-25 05:52:06 -0800838 resource = SkNEW_ARGS(TestResource, (context->getGpu()));
bsalomon24db3b12015-01-23 04:24:04 -0800839 resource->cacheAccess().setContentKey(key2);
bsalomon10e23ca2014-11-25 05:52:06 -0800840 resource->setSize(1);
841 resource->unref();
842 }
843
844 REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt);
845 REPORTER_ASSERT(reporter, cache2->getBudgetedResourceBytes() == 2 * kResourceCnt);
846 REPORTER_ASSERT(reporter, cache2->getBudgetedResourceCount() == 2 * kResourceCnt);
847 REPORTER_ASSERT(reporter, cache2->getResourceBytes() == 2 * kResourceCnt);
848 REPORTER_ASSERT(reporter, cache2->getResourceCount() == 2 * kResourceCnt);
849 for (int i = 0; i < kResourceCnt; ++i) {
bsalomon24db3b12015-01-23 04:24:04 -0800850 GrContentKey key1, key2;
851 make_content_key<1>(&key1, i);
852 make_content_key<2>(&key2, i);
853
bsalomon10e23ca2014-11-25 05:52:06 -0800854 REPORTER_ASSERT(reporter, cache2->hasContentKey(key1));
bsalomon24db3b12015-01-23 04:24:04 -0800855 REPORTER_ASSERT(reporter, cache2->hasContentKey(key2));
bsalomon10e23ca2014-11-25 05:52:06 -0800856 }
857
858 cache2->purgeAllUnlocked();
859 REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0);
860 REPORTER_ASSERT(reporter, cache2->getBudgetedResourceBytes() == 0);
861 REPORTER_ASSERT(reporter, cache2->getBudgetedResourceCount() == 0);
862 REPORTER_ASSERT(reporter, cache2->getResourceBytes() == 0);
863 REPORTER_ASSERT(reporter, cache2->getResourceCount() == 0);
864
865 for (int i = 0; i < kResourceCnt; ++i) {
bsalomon24db3b12015-01-23 04:24:04 -0800866 GrContentKey key1, key2;
867 make_content_key<1>(&key1, i);
868 make_content_key<2>(&key2, i);
869
bsalomon10e23ca2014-11-25 05:52:06 -0800870 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key1));
bsalomon24db3b12015-01-23 04:24:04 -0800871 REPORTER_ASSERT(reporter, !cache2->hasContentKey(key2));
bsalomon10e23ca2014-11-25 05:52:06 -0800872 }
873}
874
875
commit-bot@chromium.orgc6658042014-01-15 23:09:01 +0000876////////////////////////////////////////////////////////////////////////////////
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +0000877DEF_GPUTEST(ResourceCache, reporter, factory) {
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000878 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
879 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
880 if (!GrContextFactory::IsRenderingGLContext(glType)) {
881 continue;
882 }
883 GrContext* context = factory->get(glType);
bsalomonfdcf2c02014-11-05 12:30:32 -0800884 if (NULL == context) {
885 continue;
886 }
bsalomonf2703d82014-10-28 14:33:06 -0700887 GrSurfaceDesc desc;
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000888 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomonf2703d82014-10-28 14:33:06 -0700889 desc.fFlags = kRenderTarget_GrSurfaceFlag;
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000890 desc.fWidth = gWidth;
891 desc.fHeight = gHeight;
reed69f6f002014-09-18 06:09:44 -0700892 SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
bsalomonafe30052015-01-16 07:32:33 -0800893 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
894 SkSurface::kNo_Budgeted, info));
reed69f6f002014-09-18 06:09:44 -0700895 test_cache(reporter, context, surface->getCanvas());
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000896 }
bsalomon33435572014-11-05 14:47:41 -0800897
bsalomon8b79d232014-11-10 10:19:06 -0800898 // The below tests create their own mock contexts.
bsalomon71cb0c22014-11-14 12:10:14 -0800899 test_no_key(reporter);
bsalomon84c8e622014-11-17 09:33:27 -0800900 test_budgeting(reporter);
bsalomon5236cf42015-01-14 10:42:08 -0800901 test_unbudgeted(reporter);
bsalomonc2f35b72015-01-23 07:19:22 -0800902 test_unbudgeted_to_scratch(reporter);
bsalomon8b79d232014-11-10 10:19:06 -0800903 test_duplicate_content_key(reporter);
904 test_duplicate_scratch_key(reporter);
bsalomon10e23ca2014-11-25 05:52:06 -0800905 test_remove_scratch_key(reporter);
bsalomon1c60dfe2015-01-21 09:32:40 -0800906 test_scratch_key_consistency(reporter);
bsalomon8b79d232014-11-10 10:19:06 -0800907 test_purge_invalidated(reporter);
bsalomon71cb0c22014-11-14 12:10:14 -0800908 test_cache_chained_purge(reporter);
bsalomon8b79d232014-11-10 10:19:06 -0800909 test_resource_size_changed(reporter);
bsalomon10e23ca2014-11-25 05:52:06 -0800910 test_large_resource_count(reporter);
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000911}
912
commit-bot@chromium.orgc28f5552013-08-08 22:55:21 +0000913#endif