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