blob: 7419f17eb1d5f1fac9ec652914ad590baedb98af [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#if SK_SUPPORT_GPU
13
14#include "GrContext.h"
robertphillips952841b2014-06-30 08:26:50 -070015#include "GrLayerCache.h"
robertphillips60029a52015-11-09 13:51:06 -080016#include "GrResourceCache.h"
Robert Phillipscfaeec42014-07-13 12:00:50 -040017#include "SkPictureRecorder.h"
robertphillips952841b2014-06-30 08:26:50 -070018#include "Test.h"
19
robertphillipsd771f6b2014-07-22 10:18:06 -070020class TestingAccess {
robertphillips952841b2014-06-30 08:26:50 -070021public:
robertphillips60029a52015-11-09 13:51:06 -080022 static int NumPlots() {
23 return GrLayerCache::kNumPlotsX * GrLayerCache::kNumPlotsY;
24 }
25 static SkISize PlotSize() {
26 return SkISize::Make(GrLayerCache::kAtlasTextureWidth / GrLayerCache::kNumPlotsX,
27 GrLayerCache::kAtlasTextureHeight / GrLayerCache::kNumPlotsY);
28 }
29
30 static GrTexture* GetBackingTexture(GrLayerCache* cache) {
31 return cache->fAtlas->getTextureOrNull();
32 }
33
mtkleinc6ad06a2015-08-19 09:51:00 -070034 static int NumLayers(GrLayerCache* cache) {
robertphillips952841b2014-06-30 08:26:50 -070035 return cache->numLayers();
36 }
robertphillipsd771f6b2014-07-22 10:18:06 -070037 static void Purge(GrLayerCache* cache, uint32_t pictureID) {
38 cache->purge(pictureID);
39 }
robertphillips7bb9ed72014-10-10 11:38:29 -070040 static int Uses(GrCachedLayer* layer) {
41 return layer->uses();
42 }
robertphillips01d6e5f2014-12-01 09:09:27 -080043 static GrCachedLayer* Find(GrLayerCache* cache, uint32_t pictureID,
mtkleinc6ad06a2015-08-19 09:51:00 -070044 const SkMatrix& initialMat,
45 const int* key, int keySize) {
robertphillips01d6e5f2014-12-01 09:09:27 -080046 return cache->findLayer(pictureID, initialMat, key, keySize);
47 }
robertphillips952841b2014-06-30 08:26:50 -070048};
49
50// Add several layers to the cache
51static void create_layers(skiatest::Reporter* reporter,
52 GrLayerCache* cache,
robertphillips320c9232014-07-29 06:07:19 -070053 const SkPicture& picture,
mtkleinc6ad06a2015-08-19 09:51:00 -070054 int numToAdd,
55 int idOffset) {
robertphillips952841b2014-06-30 08:26:50 -070056
mtkleinc6ad06a2015-08-19 09:51:00 -070057 for (int i = 0; i < numToAdd; ++i) {
robertphillips60029a52015-11-09 13:51:06 -080058 int key[1] = { idOffset+i+1 };
mtkleinc6ad06a2015-08-19 09:51:00 -070059 GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(),
60 idOffset+i+1, idOffset+i+2,
robertphillips3aac6e02014-10-20 08:52:40 -070061 SkIRect::MakeEmpty(),
robertphillips478dd722014-12-16 08:25:55 -080062 SkIRect::MakeEmpty(),
robertphillips4aa6dfc2014-09-17 07:50:47 -070063 SkMatrix::I(),
robertphillips60029a52015-11-09 13:51:06 -080064 key, 1,
halcanary96fcdcc2015-08-27 07:41:13 -070065 nullptr);
bsalomon49f085d2014-09-05 13:34:00 -070066 REPORTER_ASSERT(reporter, layer);
mtkleinc6ad06a2015-08-19 09:51:00 -070067 GrCachedLayer* temp = TestingAccess::Find(cache, picture.uniqueID(), SkMatrix::I(),
robertphillips60029a52015-11-09 13:51:06 -080068 key, 1);
robertphillips320c9232014-07-29 06:07:19 -070069 REPORTER_ASSERT(reporter, temp == layer);
robertphillips952841b2014-06-30 08:26:50 -070070
robertphillips320c9232014-07-29 06:07:19 -070071 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1);
robertphillips952841b2014-06-30 08:26:50 -070072
robertphillips320c9232014-07-29 06:07:19 -070073 REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID());
robertphillips0c423322014-07-31 11:02:38 -070074 REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1);
75 REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2);
robertphillipsb4511342016-05-03 09:37:08 -070076 REPORTER_ASSERT(reporter, !layer->texture());
77 REPORTER_ASSERT(reporter, !layer->paint());
robertphillips320c9232014-07-29 06:07:19 -070078 REPORTER_ASSERT(reporter, !layer->isAtlased());
robertphillips952841b2014-06-30 08:26:50 -070079 }
robertphillips952841b2014-06-30 08:26:50 -070080}
81
robertphillips320c9232014-07-29 06:07:19 -070082static void lock_layer(skiatest::Reporter* reporter,
83 GrLayerCache* cache,
84 GrCachedLayer* layer) {
robertphillips60029a52015-11-09 13:51:06 -080085 // Make each layer big enough to consume one whole plot in the atlas
bsalomonf2703d82014-10-28 14:33:06 -070086 GrSurfaceDesc desc;
robertphillips60029a52015-11-09 13:51:06 -080087 desc.fFlags = kRenderTarget_GrSurfaceFlag;
88 desc.fWidth = TestingAccess::PlotSize().fWidth;
89 desc.fHeight = TestingAccess::PlotSize().fHeight;
robertphillips320c9232014-07-29 06:07:19 -070090 desc.fConfig = kSkia8888_GrPixelConfig;
91
robertphillipsfd61ed02014-10-28 07:21:44 -070092 bool needsRerendering;
93 bool inAtlas = cache->tryToAtlas(layer, desc, &needsRerendering);
94 if (!inAtlas) {
95 cache->lock(layer, desc, &needsRerendering);
96 }
robertphillips6f294af2014-08-18 08:50:03 -070097 REPORTER_ASSERT(reporter, needsRerendering);
robertphillips320c9232014-07-29 06:07:19 -070098
robertphillipsfd61ed02014-10-28 07:21:44 -070099 cache->lock(layer, desc, &needsRerendering);
robertphillips6f294af2014-08-18 08:50:03 -0700100 REPORTER_ASSERT(reporter, !needsRerendering);
robertphillips320c9232014-07-29 06:07:19 -0700101
bsalomon49f085d2014-09-05 13:34:00 -0700102 REPORTER_ASSERT(reporter, layer->texture());
robertphillips320c9232014-07-29 06:07:19 -0700103 REPORTER_ASSERT(reporter, layer->locked());
robertphillips7bb9ed72014-10-10 11:38:29 -0700104
105 cache->addUse(layer);
106
107 REPORTER_ASSERT(reporter, 1 == TestingAccess::Uses(layer));
robertphillips320c9232014-07-29 06:07:19 -0700108}
109
robertphillips952841b2014-06-30 08:26:50 -0700110// This test case exercises the public API of the GrLayerCache class.
111// In particular it checks its interaction with the resource cache (w.r.t.
112// locking & unlocking textures).
113// TODO: need to add checks on VRAM usage!
bsalomon68d91342016-04-12 09:59:58 -0700114DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GpuLayerCache, reporter, ctxInfo) {
robertphillips60029a52015-11-09 13:51:06 -0800115 // Add one more layer than can fit in the atlas
116 static const int kInitialNumLayers = TestingAccess::NumPlots() + 1;
robertphillips320c9232014-07-29 06:07:19 -0700117
robertphillips60029a52015-11-09 13:51:06 -0800118#if GR_CACHE_STATS
119 GrResourceCache::Stats stats;
120#endif
121
reedca2622b2016-03-18 07:25:55 -0700122 sk_sp<SkPicture> picture;
robertphillips952841b2014-06-30 08:26:50 -0700123
kkinnunen15302832015-12-01 04:35:26 -0800124 {
125 SkPictureRecorder recorder;
126 SkCanvas* c = recorder.beginRecording(1, 1);
127 // Draw something, anything, to prevent an empty-picture optimization,
128 // which is a singleton and never purged.
129 c->drawRect(SkRect::MakeWH(1,1), SkPaint());
reedca2622b2016-03-18 07:25:55 -0700130 picture = recorder.finishRecordingAsPicture();
kkinnunen15302832015-12-01 04:35:26 -0800131 }
robertphillips952841b2014-06-30 08:26:50 -0700132
bsalomon8b7451a2016-05-11 06:33:06 -0700133 GrResourceCache* resourceCache = ctxInfo.grContext()->getResourceCache();
robertphillips952841b2014-06-30 08:26:50 -0700134
bsalomon8b7451a2016-05-11 06:33:06 -0700135 GrLayerCache cache(ctxInfo.grContext());
robertphillips952841b2014-06-30 08:26:50 -0700136
kkinnunen15302832015-12-01 04:35:26 -0800137 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
robertphillips60029a52015-11-09 13:51:06 -0800138
kkinnunen15302832015-12-01 04:35:26 -0800139 for (int i = 0; i < kInitialNumLayers; ++i) {
140 int key[1] = { i + 1 };
141 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
142 key, 1);
143 REPORTER_ASSERT(reporter, layer);
robertphillips60029a52015-11-09 13:51:06 -0800144
kkinnunen15302832015-12-01 04:35:26 -0800145 lock_layer(reporter, &cache, layer);
bsalomone904c092014-07-17 10:50:59 -0700146
robertphillips60029a52015-11-09 13:51:06 -0800147#if GR_CACHE_STATS
148 resourceCache->getStats(&stats);
robertphillips60029a52015-11-09 13:51:06 -0800149#endif
150
kkinnunen15302832015-12-01 04:35:26 -0800151 // The first 4 layers should be in the atlas (and thus have non-empty rects)
152 if (i < TestingAccess::NumPlots()) {
153 REPORTER_ASSERT(reporter, layer->isAtlased());
154#if GR_CACHE_STATS
155 REPORTER_ASSERT(reporter, 1 == stats.fTotal);
156#endif
157 } else {
158 // The 5th layer couldn't fit in the atlas
159 REPORTER_ASSERT(reporter, !layer->isAtlased());
160#if GR_CACHE_STATS
161 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
162#endif
163 }
164 }
robertphillips01d6e5f2014-12-01 09:09:27 -0800165
kkinnunen15302832015-12-01 04:35:26 -0800166 // Unlock the textures
167 for (int i = 0; i < kInitialNumLayers; ++i) {
168 int key[1] = { i+1 };
bsalomone904c092014-07-17 10:50:59 -0700169
kkinnunen15302832015-12-01 04:35:26 -0800170 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
171 key, 1);
172 REPORTER_ASSERT(reporter, layer);
173 cache.removeUse(layer);
174 }
robertphillips7bb9ed72014-10-10 11:38:29 -0700175
kkinnunen15302832015-12-01 04:35:26 -0800176#if GR_CACHE_STATS
177 resourceCache->getStats(&stats);
178 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
179 // The floating layer is purgeable the cache is not
180 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
181 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
182#endif
183
184 for (int i = 0; i < kInitialNumLayers; ++i) {
185 int key[1] = { i+1 };
186
187 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
188 key, 1);
189 REPORTER_ASSERT(reporter, layer);
190
191 // All the layers should be unlocked
192 REPORTER_ASSERT(reporter, !layer->locked());
193
194 // When hoisted layers aren't cached they are aggressively removed
195 // from the atlas
robertphillips4ab5a902014-10-29 13:56:02 -0700196#if GR_CACHE_HOISTED_LAYERS
kkinnunen15302832015-12-01 04:35:26 -0800197 // The first 4 layers should still be in the atlas.
198 if (i < 4) {
199 REPORTER_ASSERT(reporter, layer->texture());
200 REPORTER_ASSERT(reporter, layer->isAtlased());
201 } else {
robertphillips4ab5a902014-10-29 13:56:02 -0700202#endif
kkinnunen15302832015-12-01 04:35:26 -0800203 // The final layer should not be atlased.
robertphillipsb4511342016-05-03 09:37:08 -0700204 REPORTER_ASSERT(reporter, !layer->texture());
kkinnunen15302832015-12-01 04:35:26 -0800205 REPORTER_ASSERT(reporter, !layer->isAtlased());
robertphillips4ab5a902014-10-29 13:56:02 -0700206#if GR_CACHE_HOISTED_LAYERS
bsalomone904c092014-07-17 10:50:59 -0700207 }
robertphillips60029a52015-11-09 13:51:06 -0800208#endif
robertphillips952841b2014-06-30 08:26:50 -0700209 }
kkinnunen15302832015-12-01 04:35:26 -0800210
211 // Let go of the backing texture
212 cache.end();
213 REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
214
215#if GR_CACHE_STATS
216 resourceCache->getStats(&stats);
217 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
218 // Now both the floater and the atlas are purgeable
219 REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
220#endif
221
222 // re-attach to the backing texture
223 cache.begin();
224 REPORTER_ASSERT(reporter, TestingAccess::GetBackingTexture(&cache));
225
226#if GR_CACHE_STATS
227 resourceCache->getStats(&stats);
228 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
229 // The atlas is restored to being non-purgeable
230 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
231 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
232#endif
233
234 {
235 int key[1] = { kInitialNumLayers+1 };
236
237 // Add an additional layer. Since all the layers are unlocked this
238 // will force out the first atlased layer
239 create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
240 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
241 key, 1);
242 REPORTER_ASSERT(reporter, layer);
243
244 lock_layer(reporter, &cache, layer);
245 cache.removeUse(layer);
246 }
247
248 for (int i = 0; i < kInitialNumLayers+1; ++i) {
249 int key[1] = { i+1 };
250
251 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
252 key, 1);
253#if GR_CACHE_HOISTED_LAYERS
254 // 3 old layers plus the new one should be in the atlas.
255 if (1 == i || 2 == i || 3 == i || 5 == i) {
256 REPORTER_ASSERT(reporter, layer);
257 REPORTER_ASSERT(reporter, !layer->locked());
258 REPORTER_ASSERT(reporter, layer->texture());
259 REPORTER_ASSERT(reporter, layer->isAtlased());
260 } else if (4 == i) {
261#endif
262 // The one that was never atlased should still be around
263 REPORTER_ASSERT(reporter, layer);
264
robertphillipsb4511342016-05-03 09:37:08 -0700265 REPORTER_ASSERT(reporter, !layer->texture());
kkinnunen15302832015-12-01 04:35:26 -0800266 REPORTER_ASSERT(reporter, !layer->isAtlased());
267#if GR_CACHE_HOISTED_LAYERS
268 } else {
269 // The one bumped out of the atlas (i.e., 0) should be gone
270 REPORTER_ASSERT(reporter, nullptr == layer);
271 }
272#endif
273 }
274
275 //--------------------------------------------------------------------
276 // Free them all SkGpuDevice-style. This will not free up the
277 // atlas' texture but will eliminate all the layers.
278 TestingAccess::Purge(&cache, picture->uniqueID());
279
280 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
281
282#if GR_CACHE_STATS
283 resourceCache->getStats(&stats);
284 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
285 // Atlas isn't purgeable
286 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
287 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
288#endif
289
290 //--------------------------------------------------------------------
291 // Test out the GrContext-style purge. This should remove all the layers
292 // and the atlas.
293 // Re-create the layers
294 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
295
296 // Free them again GrContext-style. This should free up everything.
297 cache.freeAll();
298
299 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
300
301 REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
302
303#if GR_CACHE_STATS
304 resourceCache->getStats(&stats);
305 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
306 REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
307#endif
308
309 // Purge the resource cache ...
310 resourceCache->purgeAllUnlocked();
311
312#if GR_CACHE_STATS
313 resourceCache->getStats(&stats);
314 REPORTER_ASSERT(reporter, 0 == stats.fTotal);
315#endif
316
317 // and try to re-attach to the backing texture. This should fail
318 cache.begin();
319 REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));
320
321 //--------------------------------------------------------------------
322 // Test out the MessageBus-style purge. This will not free the atlas
323 // but should eliminate the free-floating layers.
324 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
325
326 // Allocate/use the layers
327 for (int i = 0; i < kInitialNumLayers; ++i) {
328 int key[1] = { i + 1 };
329 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
330 key, 1);
331 REPORTER_ASSERT(reporter, layer);
332
333 lock_layer(reporter, &cache, layer);
334 }
335
336#if GR_CACHE_STATS
337 resourceCache->getStats(&stats);
338 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
339 REPORTER_ASSERT(reporter, 2 == stats.fNumNonPurgeable);
340#endif
341
342 // Unlock the textures
343 for (int i = 0; i < kInitialNumLayers; ++i) {
344 int key[1] = { i+1 };
345
346 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
347 key, 1);
348 REPORTER_ASSERT(reporter, layer);
349 cache.removeUse(layer);
350 }
351
352 picture.reset(nullptr);
353 cache.processDeletedPictures();
354
355 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
356
357#if GR_CACHE_STATS
358 resourceCache->getStats(&stats);
359 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
360 REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
361 REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
362#endif
363
364 cache.end();
365
366#if GR_CACHE_STATS
367 resourceCache->getStats(&stats);
368 REPORTER_ASSERT(reporter, 2 == stats.fTotal);
369 REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
370#endif
robertphillips952841b2014-06-30 08:26:50 -0700371}
372
373#endif
egdaniel37535c92016-06-30 08:23:30 -0700374#endif