blob: b22809c553fc7b94ad55f57f1023349186200f50 [file] [log] [blame]
robertphillips952841b2014-06-30 08:26:50 -07001/*
2* Copyright 2014 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
egdaniel37535c92016-06-30 08:23:30 -07008// Disabling this test since it is for the layer hoister which is current disabled.
9// The test fails when we add a discard to a newly created render target.
10#if 0
11
robertphillips952841b2014-06-30 08:26:50 -070012#include "GrContext.h"
robertphillips952841b2014-06-30 08:26:50 -070013#include "GrLayerCache.h"
robertphillips60029a52015-11-09 13:51:06 -080014#include "GrResourceCache.h"
Robert Phillipscfaeec42014-07-13 12:00:50 -040015#include "SkPictureRecorder.h"
robertphillips952841b2014-06-30 08:26:50 -070016#include "Test.h"
17
robertphillipsd771f6b2014-07-22 10:18:06 -070018class TestingAccess {
robertphillips952841b2014-06-30 08:26:50 -070019public:
robertphillips60029a52015-11-09 13:51:06 -080020 static int NumPlots() {
21 return GrLayerCache::kNumPlotsX * GrLayerCache::kNumPlotsY;
22 }
23 static SkISize PlotSize() {
24 return SkISize::Make(GrLayerCache::kAtlasTextureWidth / GrLayerCache::kNumPlotsX,
25 GrLayerCache::kAtlasTextureHeight / GrLayerCache::kNumPlotsY);
26 }
27
28 static GrTexture* GetBackingTexture(GrLayerCache* cache) {
29 return cache->fAtlas->getTextureOrNull();
30 }
31
mtkleinc6ad06a2015-08-19 09:51:00 -070032 static int NumLayers(GrLayerCache* cache) {
robertphillips952841b2014-06-30 08:26:50 -070033 return cache->numLayers();
34 }
robertphillipsd771f6b2014-07-22 10:18:06 -070035 static void Purge(GrLayerCache* cache, uint32_t pictureID) {
36 cache->purge(pictureID);
37 }
robertphillips7bb9ed72014-10-10 11:38:29 -070038 static int Uses(GrCachedLayer* layer) {
39 return layer->uses();
40 }
robertphillips01d6e5f2014-12-01 09:09:27 -080041 static GrCachedLayer* Find(GrLayerCache* cache, uint32_t pictureID,
mtkleinc6ad06a2015-08-19 09:51:00 -070042 const SkMatrix& initialMat,
43 const int* key, int keySize) {
robertphillips01d6e5f2014-12-01 09:09:27 -080044 return cache->findLayer(pictureID, initialMat, key, keySize);
45 }
robertphillips952841b2014-06-30 08:26:50 -070046};
47
48// Add several layers to the cache
49static void create_layers(skiatest::Reporter* reporter,
50 GrLayerCache* cache,
robertphillips320c9232014-07-29 06:07:19 -070051 const SkPicture& picture,
mtkleinc6ad06a2015-08-19 09:51:00 -070052 int numToAdd,
53 int idOffset) {
robertphillips952841b2014-06-30 08:26:50 -070054
mtkleinc6ad06a2015-08-19 09:51:00 -070055 for (int i = 0; i < numToAdd; ++i) {
robertphillips60029a52015-11-09 13:51:06 -080056 int key[1] = { idOffset+i+1 };
mtkleinc6ad06a2015-08-19 09:51:00 -070057 GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(),
58 idOffset+i+1, idOffset+i+2,
robertphillips3aac6e02014-10-20 08:52:40 -070059 SkIRect::MakeEmpty(),
robertphillips478dd722014-12-16 08:25:55 -080060 SkIRect::MakeEmpty(),
robertphillips4aa6dfc2014-09-17 07:50:47 -070061 SkMatrix::I(),
robertphillips60029a52015-11-09 13:51:06 -080062 key, 1,
halcanary96fcdcc2015-08-27 07:41:13 -070063 nullptr);
bsalomon49f085d2014-09-05 13:34:00 -070064 REPORTER_ASSERT(reporter, layer);
mtkleinc6ad06a2015-08-19 09:51:00 -070065 GrCachedLayer* temp = TestingAccess::Find(cache, picture.uniqueID(), SkMatrix::I(),
robertphillips60029a52015-11-09 13:51:06 -080066 key, 1);
robertphillips320c9232014-07-29 06:07:19 -070067 REPORTER_ASSERT(reporter, temp == layer);
robertphillips952841b2014-06-30 08:26:50 -070068
robertphillips320c9232014-07-29 06:07:19 -070069 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1);
robertphillips952841b2014-06-30 08:26:50 -070070
robertphillips320c9232014-07-29 06:07:19 -070071 REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID());
robertphillips0c423322014-07-31 11:02:38 -070072 REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1);
73 REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2);
robertphillipsb4511342016-05-03 09:37:08 -070074 REPORTER_ASSERT(reporter, !layer->texture());
75 REPORTER_ASSERT(reporter, !layer->paint());
robertphillips320c9232014-07-29 06:07:19 -070076 REPORTER_ASSERT(reporter, !layer->isAtlased());
robertphillips952841b2014-06-30 08:26:50 -070077 }
robertphillips952841b2014-06-30 08:26:50 -070078}
79
robertphillips320c9232014-07-29 06:07:19 -070080static void lock_layer(skiatest::Reporter* reporter,
81 GrLayerCache* cache,
82 GrCachedLayer* layer) {
robertphillips60029a52015-11-09 13:51:06 -080083 // Make each layer big enough to consume one whole plot in the atlas
bsalomonf2703d82014-10-28 14:33:06 -070084 GrSurfaceDesc desc;
robertphillips60029a52015-11-09 13:51:06 -080085 desc.fFlags = kRenderTarget_GrSurfaceFlag;
86 desc.fWidth = TestingAccess::PlotSize().fWidth;
87 desc.fHeight = TestingAccess::PlotSize().fHeight;
robertphillips320c9232014-07-29 06:07:19 -070088 desc.fConfig = kSkia8888_GrPixelConfig;
89
robertphillipsfd61ed02014-10-28 07:21:44 -070090 bool needsRerendering;
91 bool inAtlas = cache->tryToAtlas(layer, desc, &needsRerendering);
92 if (!inAtlas) {
93 cache->lock(layer, desc, &needsRerendering);
94 }
robertphillips6f294af2014-08-18 08:50:03 -070095 REPORTER_ASSERT(reporter, needsRerendering);
robertphillips320c9232014-07-29 06:07:19 -070096
robertphillipsfd61ed02014-10-28 07:21:44 -070097 cache->lock(layer, desc, &needsRerendering);
robertphillips6f294af2014-08-18 08:50:03 -070098 REPORTER_ASSERT(reporter, !needsRerendering);
robertphillips320c9232014-07-29 06:07:19 -070099
bsalomon49f085d2014-09-05 13:34:00 -0700100 REPORTER_ASSERT(reporter, layer->texture());
robertphillips320c9232014-07-29 06:07:19 -0700101 REPORTER_ASSERT(reporter, layer->locked());
robertphillips7bb9ed72014-10-10 11:38:29 -0700102
103 cache->addUse(layer);
104
105 REPORTER_ASSERT(reporter, 1 == TestingAccess::Uses(layer));
robertphillips320c9232014-07-29 06:07:19 -0700106}
107
robertphillips952841b2014-06-30 08:26:50 -0700108// This test case exercises the public API of the GrLayerCache class.
109// In particular it checks its interaction with the resource cache (w.r.t.
110// locking & unlocking textures).
111// TODO: need to add checks on VRAM usage!
bsalomon68d91342016-04-12 09:59:58 -0700112DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GpuLayerCache, reporter, ctxInfo) {
robertphillips60029a52015-11-09 13:51:06 -0800113 // Add one more layer than can fit in the atlas
114 static const int kInitialNumLayers = TestingAccess::NumPlots() + 1;
robertphillips320c9232014-07-29 06:07:19 -0700115
robertphillips60029a52015-11-09 13:51:06 -0800116#if GR_CACHE_STATS
117 GrResourceCache::Stats stats;
118#endif
119
reedca2622b2016-03-18 07:25:55 -0700120 sk_sp<SkPicture> picture;
robertphillips952841b2014-06-30 08:26:50 -0700121
kkinnunen15302832015-12-01 04:35:26 -0800122 {
123 SkPictureRecorder recorder;
124 SkCanvas* c = recorder.beginRecording(1, 1);
125 // Draw something, anything, to prevent an empty-picture optimization,
126 // which is a singleton and never purged.
127 c->drawRect(SkRect::MakeWH(1,1), SkPaint());
reedca2622b2016-03-18 07:25:55 -0700128 picture = recorder.finishRecordingAsPicture();
kkinnunen15302832015-12-01 04:35:26 -0800129 }
robertphillips952841b2014-06-30 08:26:50 -0700130
bsalomon8b7451a2016-05-11 06:33:06 -0700131 GrResourceCache* resourceCache = ctxInfo.grContext()->getResourceCache();
robertphillips952841b2014-06-30 08:26:50 -0700132
bsalomon8b7451a2016-05-11 06:33:06 -0700133 GrLayerCache cache(ctxInfo.grContext());
robertphillips952841b2014-06-30 08:26:50 -0700134
kkinnunen15302832015-12-01 04:35:26 -0800135 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
robertphillips60029a52015-11-09 13:51:06 -0800136
kkinnunen15302832015-12-01 04:35:26 -0800137 for (int i = 0; i < kInitialNumLayers; ++i) {
138 int key[1] = { i + 1 };
139 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
140 key, 1);
141 REPORTER_ASSERT(reporter, layer);
robertphillips60029a52015-11-09 13:51:06 -0800142
kkinnunen15302832015-12-01 04:35:26 -0800143 lock_layer(reporter, &cache, layer);
bsalomone904c092014-07-17 10:50:59 -0700144
robertphillips60029a52015-11-09 13:51:06 -0800145#if GR_CACHE_STATS
146 resourceCache->getStats(&stats);
robertphillips60029a52015-11-09 13:51:06 -0800147#endif
148
kkinnunen15302832015-12-01 04:35:26 -0800149 // The first 4 layers should be in the atlas (and thus have non-empty rects)
150 if (i < TestingAccess::NumPlots()) {
151 REPORTER_ASSERT(reporter, layer->isAtlased());
152#if GR_CACHE_STATS
153 REPORTER_ASSERT(reporter, 1 == stats.fTotal);
154#endif
155 } else {
156 // The 5th layer couldn't fit in the atlas
157 REPORTER_ASSERT(reporter, !layer->isAtlased());
158#if GR_CACHE_STATS
159 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
160#endif
161 }
162 }
robertphillips01d6e5f2014-12-01 09:09:27 -0800163
kkinnunen15302832015-12-01 04:35:26 -0800164 // Unlock the textures
165 for (int i = 0; i < kInitialNumLayers; ++i) {
166 int key[1] = { i+1 };
bsalomone904c092014-07-17 10:50:59 -0700167
kkinnunen15302832015-12-01 04:35:26 -0800168 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
169 key, 1);
170 REPORTER_ASSERT(reporter, layer);
171 cache.removeUse(layer);
172 }
robertphillips7bb9ed72014-10-10 11:38:29 -0700173
kkinnunen15302832015-12-01 04:35:26 -0800174#if GR_CACHE_STATS
175 resourceCache->getStats(&stats);
176 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
177 // The floating layer is purgeable the cache is not
178 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
179 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
180#endif
181
182 for (int i = 0; i < kInitialNumLayers; ++i) {
183 int key[1] = { i+1 };
184
185 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
186 key, 1);
187 REPORTER_ASSERT(reporter, layer);
188
189 // All the layers should be unlocked
190 REPORTER_ASSERT(reporter, !layer->locked());
191
192 // When hoisted layers aren't cached they are aggressively removed
193 // from the atlas
robertphillips4ab5a902014-10-29 13:56:02 -0700194#if GR_CACHE_HOISTED_LAYERS
kkinnunen15302832015-12-01 04:35:26 -0800195 // The first 4 layers should still be in the atlas.
196 if (i < 4) {
197 REPORTER_ASSERT(reporter, layer->texture());
198 REPORTER_ASSERT(reporter, layer->isAtlased());
199 } else {
robertphillips4ab5a902014-10-29 13:56:02 -0700200#endif
kkinnunen15302832015-12-01 04:35:26 -0800201 // The final layer should not be atlased.
robertphillipsb4511342016-05-03 09:37:08 -0700202 REPORTER_ASSERT(reporter, !layer->texture());
kkinnunen15302832015-12-01 04:35:26 -0800203 REPORTER_ASSERT(reporter, !layer->isAtlased());
robertphillips4ab5a902014-10-29 13:56:02 -0700204#if GR_CACHE_HOISTED_LAYERS
bsalomone904c092014-07-17 10:50:59 -0700205 }
robertphillips60029a52015-11-09 13:51:06 -0800206#endif
robertphillips952841b2014-06-30 08:26:50 -0700207 }
kkinnunen15302832015-12-01 04:35:26 -0800208
209 // Let go of the backing texture
210 cache.end();
211 REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
212
213#if GR_CACHE_STATS
214 resourceCache->getStats(&stats);
215 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
216 // Now both the floater and the atlas are purgeable
217 REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
218#endif
219
220 // re-attach to the backing texture
221 cache.begin();
222 REPORTER_ASSERT(reporter, TestingAccess::GetBackingTexture(&cache));
223
224#if GR_CACHE_STATS
225 resourceCache->getStats(&stats);
226 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
227 // The atlas is restored to being non-purgeable
228 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
229 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
230#endif
231
232 {
233 int key[1] = { kInitialNumLayers+1 };
234
235 // Add an additional layer. Since all the layers are unlocked this
236 // will force out the first atlased layer
237 create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
238 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
239 key, 1);
240 REPORTER_ASSERT(reporter, layer);
241
242 lock_layer(reporter, &cache, layer);
243 cache.removeUse(layer);
244 }
245
246 for (int i = 0; i < kInitialNumLayers+1; ++i) {
247 int key[1] = { i+1 };
248
249 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
250 key, 1);
251#if GR_CACHE_HOISTED_LAYERS
252 // 3 old layers plus the new one should be in the atlas.
253 if (1 == i || 2 == i || 3 == i || 5 == i) {
254 REPORTER_ASSERT(reporter, layer);
255 REPORTER_ASSERT(reporter, !layer->locked());
256 REPORTER_ASSERT(reporter, layer->texture());
257 REPORTER_ASSERT(reporter, layer->isAtlased());
258 } else if (4 == i) {
259#endif
260 // The one that was never atlased should still be around
261 REPORTER_ASSERT(reporter, layer);
262
robertphillipsb4511342016-05-03 09:37:08 -0700263 REPORTER_ASSERT(reporter, !layer->texture());
kkinnunen15302832015-12-01 04:35:26 -0800264 REPORTER_ASSERT(reporter, !layer->isAtlased());
265#if GR_CACHE_HOISTED_LAYERS
266 } else {
267 // The one bumped out of the atlas (i.e., 0) should be gone
268 REPORTER_ASSERT(reporter, nullptr == layer);
269 }
270#endif
271 }
272
273 //--------------------------------------------------------------------
274 // Free them all SkGpuDevice-style. This will not free up the
275 // atlas' texture but will eliminate all the layers.
276 TestingAccess::Purge(&cache, picture->uniqueID());
277
278 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
279
280#if GR_CACHE_STATS
281 resourceCache->getStats(&stats);
282 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
283 // Atlas isn't purgeable
284 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
285 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
286#endif
287
288 //--------------------------------------------------------------------
289 // Test out the GrContext-style purge. This should remove all the layers
290 // and the atlas.
291 // Re-create the layers
292 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
293
294 // Free them again GrContext-style. This should free up everything.
295 cache.freeAll();
296
297 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
298
299 REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
300
301#if GR_CACHE_STATS
302 resourceCache->getStats(&stats);
303 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
304 REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
305#endif
306
307 // Purge the resource cache ...
308 resourceCache->purgeAllUnlocked();
309
310#if GR_CACHE_STATS
311 resourceCache->getStats(&stats);
312 REPORTER_ASSERT(reporter, 0 == stats.fTotal);
313#endif
314
315 // and try to re-attach to the backing texture. This should fail
316 cache.begin();
317 REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
318
319 //--------------------------------------------------------------------
320 // Test out the MessageBus-style purge. This will not free the atlas
321 // but should eliminate the free-floating layers.
322 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
323
324 // Allocate/use the layers
325 for (int i = 0; i < kInitialNumLayers; ++i) {
326 int key[1] = { i + 1 };
327 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
328 key, 1);
329 REPORTER_ASSERT(reporter, layer);
330
331 lock_layer(reporter, &cache, layer);
332 }
333
334#if GR_CACHE_STATS
335 resourceCache->getStats(&stats);
336 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
337 REPORTER_ASSERT(reporter, 2 == stats.fNumNonPurgeable);
338#endif
339
340 // Unlock the textures
341 for (int i = 0; i < kInitialNumLayers; ++i) {
342 int key[1] = { i+1 };
343
344 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
345 key, 1);
346 REPORTER_ASSERT(reporter, layer);
347 cache.removeUse(layer);
348 }
349
350 picture.reset(nullptr);
351 cache.processDeletedPictures();
352
353 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
354
355#if GR_CACHE_STATS
356 resourceCache->getStats(&stats);
357 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
358 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
359 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
360#endif
361
362 cache.end();
363
364#if GR_CACHE_STATS
365 resourceCache->getStats(&stats);
366 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
367 REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
368#endif
robertphillips952841b2014-06-30 08:26:50 -0700369}
370
371#endif