Home | History | Annotate | Download | only in tests
      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