1 /* 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 8 // 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 12 #if SK_SUPPORT_GPU 13 14 #include "GrContext.h" 15 #include "GrLayerCache.h" 16 #include "GrResourceCache.h" 17 #include "SkPictureRecorder.h" 18 #include "Test.h" 19 20 class TestingAccess { 21 public: 22 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 34 static int NumLayers(GrLayerCache* cache) { 35 return cache->numLayers(); 36 } 37 static void Purge(GrLayerCache* cache, uint32_t pictureID) { 38 cache->purge(pictureID); 39 } 40 static int Uses(GrCachedLayer* layer) { 41 return layer->uses(); 42 } 43 static GrCachedLayer* Find(GrLayerCache* cache, uint32_t pictureID, 44 const SkMatrix& initialMat, 45 const int* key, int keySize) { 46 return cache->findLayer(pictureID, initialMat, key, keySize); 47 } 48 }; 49 50 // Add several layers to the cache 51 static void create_layers(skiatest::Reporter* reporter, 52 GrLayerCache* cache, 53 const SkPicture& picture, 54 int numToAdd, 55 int idOffset) { 56 57 for (int i = 0; i < numToAdd; ++i) { 58 int key[1] = { idOffset+i+1 }; 59 GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 60 idOffset+i+1, idOffset+i+2, 61 SkIRect::MakeEmpty(), 62 SkIRect::MakeEmpty(), 63 SkMatrix::I(), 64 key, 1, 65 nullptr); 66 REPORTER_ASSERT(reporter, layer); 67 GrCachedLayer* temp = TestingAccess::Find(cache, picture.uniqueID(), SkMatrix::I(), 68 key, 1); 69 REPORTER_ASSERT(reporter, temp == layer); 70 71 REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1); 72 73 REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID()); 74 REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1); 75 REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2); 76 REPORTER_ASSERT(reporter, !layer->texture()); 77 REPORTER_ASSERT(reporter, !layer->paint()); 78 REPORTER_ASSERT(reporter, !layer->isAtlased()); 79 } 80 } 81 82 static void lock_layer(skiatest::Reporter* reporter, 83 GrLayerCache* cache, 84 GrCachedLayer* layer) { 85 // Make each layer big enough to consume one whole plot in the atlas 86 GrSurfaceDesc desc; 87 desc.fFlags = kRenderTarget_GrSurfaceFlag; 88 desc.fWidth = TestingAccess::PlotSize().fWidth; 89 desc.fHeight = TestingAccess::PlotSize().fHeight; 90 desc.fConfig = kSkia8888_GrPixelConfig; 91 92 bool needsRerendering; 93 bool inAtlas = cache->tryToAtlas(layer, desc, &needsRerendering); 94 if (!inAtlas) { 95 cache->lock(layer, desc, &needsRerendering); 96 } 97 REPORTER_ASSERT(reporter, needsRerendering); 98 99 cache->lock(layer, desc, &needsRerendering); 100 REPORTER_ASSERT(reporter, !needsRerendering); 101 102 REPORTER_ASSERT(reporter, layer->texture()); 103 REPORTER_ASSERT(reporter, layer->locked()); 104 105 cache->addUse(layer); 106 107 REPORTER_ASSERT(reporter, 1 == TestingAccess::Uses(layer)); 108 } 109 110 // 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! 114 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GpuLayerCache, reporter, ctxInfo) { 115 // Add one more layer than can fit in the atlas 116 static const int kInitialNumLayers = TestingAccess::NumPlots() + 1; 117 118 #if GR_CACHE_STATS 119 GrResourceCache::Stats stats; 120 #endif 121 122 sk_sp<SkPicture> picture; 123 124 { 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()); 130 picture = recorder.finishRecordingAsPicture(); 131 } 132 133 GrResourceCache* resourceCache = ctxInfo.grContext()->getResourceCache(); 134 135 GrLayerCache cache(ctxInfo.grContext()); 136 137 create_layers(reporter, &cache, *picture, kInitialNumLayers, 0); 138 139 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); 144 145 lock_layer(reporter, &cache, layer); 146 147 #if GR_CACHE_STATS 148 resourceCache->getStats(&stats); 149 #endif 150 151 // 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 } 165 166 // Unlock the textures 167 for (int i = 0; i < kInitialNumLayers; ++i) { 168 int key[1] = { i+1 }; 169 170 GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(), 171 key, 1); 172 REPORTER_ASSERT(reporter, layer); 173 cache.removeUse(layer); 174 } 175 176 #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 196 #if GR_CACHE_HOISTED_LAYERS 197 // 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 { 202 #endif 203 // The final layer should not be atlased. 204 REPORTER_ASSERT(reporter, !layer->texture()); 205 REPORTER_ASSERT(reporter, !layer->isAtlased()); 206 #if GR_CACHE_HOISTED_LAYERS 207 } 208 #endif 209 } 210 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 265 REPORTER_ASSERT(reporter, !layer->texture()); 266 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 371 } 372 373 #endif 374 #endif 375