/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

// Disabling this test since it is for the layer hoister which is current disabled.
// The test fails when we add a discard to a newly created render target.
#if 0

#include "GrContext.h"
#include "GrLayerCache.h"
#include "GrResourceCache.h"
#include "SkPictureRecorder.h"
#include "Test.h"

class TestingAccess {
public:
    static int NumPlots() {
        return GrLayerCache::kNumPlotsX * GrLayerCache::kNumPlotsY;
    }
    static SkISize PlotSize() {
        return SkISize::Make(GrLayerCache::kAtlasTextureWidth / GrLayerCache::kNumPlotsX,
                             GrLayerCache::kAtlasTextureHeight / GrLayerCache::kNumPlotsY);
    }

    static GrTexture* GetBackingTexture(GrLayerCache* cache) {
        return cache->fAtlas->getTextureOrNull();
    }

    static int NumLayers(GrLayerCache* cache) {
        return cache->numLayers();
    }
    static void Purge(GrLayerCache* cache, uint32_t pictureID) {
        cache->purge(pictureID);
    }
    static int Uses(GrCachedLayer* layer) {
        return layer->uses();
    }
    static GrCachedLayer* Find(GrLayerCache* cache, uint32_t pictureID,
                               const SkMatrix& initialMat,
                               const int* key, int keySize) {
        return cache->findLayer(pictureID, initialMat, key, keySize);
    }
};

// Add several layers to the cache
static void create_layers(skiatest::Reporter* reporter,
                          GrLayerCache* cache,
                          const SkPicture& picture,
                          int numToAdd,
                          int idOffset) {

    for (int i = 0; i < numToAdd; ++i) {
        int key[1] = { idOffset+i+1 };
        GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(),
                                                        idOffset+i+1, idOffset+i+2,
                                                        SkIRect::MakeEmpty(),
                                                        SkIRect::MakeEmpty(),
                                                        SkMatrix::I(),
                                                        key, 1,
                                                        nullptr);
        REPORTER_ASSERT(reporter, layer);
        GrCachedLayer* temp = TestingAccess::Find(cache, picture.uniqueID(), SkMatrix::I(),
                                                  key, 1);
        REPORTER_ASSERT(reporter, temp == layer);

        REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1);

        REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID());
        REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1);
        REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2);
        REPORTER_ASSERT(reporter, !layer->texture());
        REPORTER_ASSERT(reporter, !layer->paint());
        REPORTER_ASSERT(reporter, !layer->isAtlased());
    }
}

static void lock_layer(skiatest::Reporter* reporter,
                       GrLayerCache* cache,
                       GrCachedLayer* layer) {
    // Make each layer big enough to consume one whole plot in the atlas
    GrSurfaceDesc desc;
    desc.fFlags = kRenderTarget_GrSurfaceFlag;
    desc.fWidth = TestingAccess::PlotSize().fWidth;
    desc.fHeight = TestingAccess::PlotSize().fHeight;
    desc.fConfig = kSkia8888_GrPixelConfig;

    bool needsRerendering;
    bool inAtlas = cache->tryToAtlas(layer, desc, &needsRerendering);
    if (!inAtlas) {
        cache->lock(layer, desc, &needsRerendering);
    }
    REPORTER_ASSERT(reporter, needsRerendering);

    cache->lock(layer, desc, &needsRerendering);
    REPORTER_ASSERT(reporter, !needsRerendering);

    REPORTER_ASSERT(reporter, layer->texture());
    REPORTER_ASSERT(reporter, layer->locked());

    cache->addUse(layer);

    REPORTER_ASSERT(reporter, 1 == TestingAccess::Uses(layer));
}

// This test case exercises the public API of the GrLayerCache class.
// In particular it checks its interaction with the resource cache (w.r.t.
// locking & unlocking textures).
// TODO: need to add checks on VRAM usage!
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GpuLayerCache, reporter, ctxInfo) {
    // Add one more layer than can fit in the atlas
    static const int kInitialNumLayers = TestingAccess::NumPlots() + 1;

#if GR_CACHE_STATS
    GrResourceCache::Stats stats;
#endif

    sk_sp<SkPicture> picture;

    {
        SkPictureRecorder recorder;
        SkCanvas* c = recorder.beginRecording(1, 1);
        // Draw something, anything, to prevent an empty-picture optimization,
        // which is a singleton and never purged.
        c->drawRect(SkRect::MakeWH(1,1), SkPaint());
        picture = recorder.finishRecordingAsPicture();
    }

    GrResourceCache* resourceCache = ctxInfo.grContext()->getResourceCache();

    GrLayerCache cache(ctxInfo.grContext());

    create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);

    for (int i = 0; i < kInitialNumLayers; ++i) {
        int key[1] = { i + 1 };
        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
        REPORTER_ASSERT(reporter, layer);

        lock_layer(reporter, &cache, layer);

#if GR_CACHE_STATS
        resourceCache->getStats(&stats);
#endif

        // The first 4 layers should be in the atlas (and thus have non-empty rects)
        if (i < TestingAccess::NumPlots()) {
            REPORTER_ASSERT(reporter, layer->isAtlased());
#if GR_CACHE_STATS
            REPORTER_ASSERT(reporter, 1 == stats.fTotal);
#endif
        } else {
            // The 5th layer couldn't fit in the atlas
            REPORTER_ASSERT(reporter, !layer->isAtlased());
#if GR_CACHE_STATS
            REPORTER_ASSERT(reporter, 2 == stats.fTotal);
#endif
        }
    }

    // Unlock the textures
    for (int i = 0; i < kInitialNumLayers; ++i) {
        int key[1] = { i+1 };

        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
        REPORTER_ASSERT(reporter, layer);
        cache.removeUse(layer);
    }

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    // The floating layer is purgeable the cache is not
    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
#endif

    for (int i = 0; i < kInitialNumLayers; ++i) {
        int key[1] = { i+1 };

        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
        REPORTER_ASSERT(reporter, layer);

        // All the layers should be unlocked
        REPORTER_ASSERT(reporter, !layer->locked());

        // When hoisted layers aren't cached they are aggressively removed
        // from the atlas
#if GR_CACHE_HOISTED_LAYERS
        // The first 4 layers should still be in the atlas.
        if (i < 4) {
            REPORTER_ASSERT(reporter, layer->texture());
            REPORTER_ASSERT(reporter, layer->isAtlased());
        } else {
#endif
            // The final layer should not be atlased.
            REPORTER_ASSERT(reporter, !layer->texture());
            REPORTER_ASSERT(reporter, !layer->isAtlased());
#if GR_CACHE_HOISTED_LAYERS
        }
#endif
    }

    // Let go of the backing texture
    cache.end();
    REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    // Now both the floater and the atlas are purgeable
    REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
#endif

    // re-attach to the backing texture
    cache.begin();
    REPORTER_ASSERT(reporter, TestingAccess::GetBackingTexture(&cache));

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    // The atlas is restored to being non-purgeable
    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
#endif

    {
        int key[1] = { kInitialNumLayers+1 };

        // Add an additional layer. Since all the layers are unlocked this
        // will force out the first atlased layer
        create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
        REPORTER_ASSERT(reporter, layer);

        lock_layer(reporter, &cache, layer);
        cache.removeUse(layer);
    }

    for (int i = 0; i < kInitialNumLayers+1; ++i) {
        int key[1] = { i+1 };

        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
#if GR_CACHE_HOISTED_LAYERS
        // 3 old layers plus the new one should be in the atlas.
        if (1 == i || 2 == i || 3 == i || 5 == i) {
            REPORTER_ASSERT(reporter, layer);
            REPORTER_ASSERT(reporter, !layer->locked());
            REPORTER_ASSERT(reporter, layer->texture());
            REPORTER_ASSERT(reporter, layer->isAtlased());
        } else if (4 == i) {
#endif
            // The one that was never atlased should still be around
            REPORTER_ASSERT(reporter, layer);

            REPORTER_ASSERT(reporter, !layer->texture());
            REPORTER_ASSERT(reporter, !layer->isAtlased());
#if GR_CACHE_HOISTED_LAYERS
        } else {
            // The one bumped out of the atlas (i.e., 0) should be gone
            REPORTER_ASSERT(reporter, nullptr == layer);
        }
#endif
    }

    //--------------------------------------------------------------------
    // Free them all SkGpuDevice-style. This will not free up the
    // atlas' texture but will eliminate all the layers.
    TestingAccess::Purge(&cache, picture->uniqueID());

    REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    // Atlas isn't purgeable
    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
#endif

    //--------------------------------------------------------------------
    // Test out the GrContext-style purge. This should remove all the layers
    // and the atlas.
    // Re-create the layers
    create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);

    // Free them again GrContext-style. This should free up everything.
    cache.freeAll();

    REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);

    REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
#endif

    // Purge the resource cache ...
    resourceCache->purgeAllUnlocked();

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 0 == stats.fTotal);
#endif

    // and try to re-attach to the backing texture. This should fail
    cache.begin();
    REPORTER_ASSERT(reporter, nullptr == TestingAccess::GetBackingTexture(&cache));

    //--------------------------------------------------------------------
    // Test out the MessageBus-style purge. This will not free the atlas
    // but should eliminate the free-floating layers.
    create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);

    // Allocate/use the layers
    for (int i = 0; i < kInitialNumLayers; ++i) {
        int key[1] = { i + 1 };
        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
        REPORTER_ASSERT(reporter, layer);

        lock_layer(reporter, &cache, layer);
    }

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    REPORTER_ASSERT(reporter, 2 == stats.fNumNonPurgeable);
#endif

    // Unlock the textures
    for (int i = 0; i < kInitialNumLayers; ++i) {
        int key[1] = { i+1 };

        GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                   key, 1);
        REPORTER_ASSERT(reporter, layer);
        cache.removeUse(layer);
    }

    picture.reset(nullptr);
    cache.processDeletedPictures();

    REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    REPORTER_ASSERT(reporter, 1 == stats.fNumPurgeable);
    REPORTER_ASSERT(reporter, 1 == stats.fNumNonPurgeable);
#endif

    cache.end();

#if GR_CACHE_STATS
    resourceCache->getStats(&stats);
    REPORTER_ASSERT(reporter, 2 == stats.fTotal);
    REPORTER_ASSERT(reporter, 2 == stats.fNumPurgeable);
#endif
}

#endif
