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

#if SK_SUPPORT_GPU

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

static const int kNumLayers = 5;

class GetNumLayers {
public:
    static int NumLayers(GrLayerCache* cache) {
        return cache->numLayers();
    }
};

// Add several layers to the cache
static void create_layers(skiatest::Reporter* reporter,
                          GrLayerCache* cache,
                          const SkPicture& picture) {
    GrCachedLayer* layers[kNumLayers];

    for (int i = 0; i < kNumLayers; ++i) {
        layers[i] = cache->findLayerOrCreate(&picture, i);
        REPORTER_ASSERT(reporter, NULL != layers[i]);
        GrCachedLayer* layer = cache->findLayer(&picture, i);
        REPORTER_ASSERT(reporter, layer == layers[i]);

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

        REPORTER_ASSERT(reporter, picture.uniqueID() == layers[i]->pictureID());
        REPORTER_ASSERT(reporter, layers[i]->layerID() == i);
        REPORTER_ASSERT(reporter, NULL == layers[i]->texture());
        REPORTER_ASSERT(reporter, layers[i]->rect().isEmpty());
    }

}

// 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(GpuLayerCache, reporter, factory) {

    GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
    if (NULL == context) {
        return;
    }

    SkPictureRecorder recorder;
    recorder.beginRecording(1, 1);
    SkAutoTUnref<const SkPicture> picture(recorder.endRecording());

    GrLayerCache cache(context);

    create_layers(reporter, &cache, *picture);

    // Lock the layers making them all 512x512
    GrTextureDesc desc;
    desc.fWidth = 512;
    desc.fHeight = 512;
    desc.fConfig = kSkia8888_GrPixelConfig;

    for (int i = 0; i < kNumLayers; ++i) {
        GrCachedLayer* layer = cache.findLayer(picture, i);
        REPORTER_ASSERT(reporter, NULL != layer);

        bool foundInCache = cache.lock(layer, desc);
        REPORTER_ASSERT(reporter, !foundInCache);
        foundInCache = cache.lock(layer, desc);
        REPORTER_ASSERT(reporter, foundInCache);

        REPORTER_ASSERT(reporter, NULL != layer->texture());
#if USE_ATLAS
        // The first 4 layers should be in the atlas (and thus have non-empty
        // rects)
        if (i < 4) {
            REPORTER_ASSERT(reporter, !layer->rect().isEmpty());
        } else {
#endif
            REPORTER_ASSERT(reporter, layer->rect().isEmpty());
#if USE_ATLAS
        }
#endif
    }

    // Unlock the textures
    for (int i = 0; i < kNumLayers; ++i) {
        GrCachedLayer* layer = cache.findLayer(picture, i);
        REPORTER_ASSERT(reporter, NULL != layer);

        cache.unlock(layer);
    }

    for (int i = 0; i < kNumLayers; ++i) {
        GrCachedLayer* layer = cache.findLayer(picture, i);
        REPORTER_ASSERT(reporter, NULL != layer);

#if USE_ATLAS
        // The first 4 layers should be in the atlas (and thus do not 
        // currently unlock). The final layer should be unlocked.
        if (i < 4) {
            REPORTER_ASSERT(reporter, NULL != layer->texture());
            REPORTER_ASSERT(reporter, !layer->rect().isEmpty());
        } else {
#endif
            REPORTER_ASSERT(reporter, NULL == layer->texture());
            REPORTER_ASSERT(reporter, layer->rect().isEmpty());
#if USE_ATLAS
        }
#endif
    }

    // Free them all SkGpuDevice-style. This will not free up the
    // atlas' texture but will eliminate all the layers.
    cache.purge(picture);

    REPORTER_ASSERT(reporter, GetNumLayers::NumLayers(&cache) == 0);
    // TODO: add VRAM/resource cache check here
#if 0
    // Re-create the layers
    create_layers(reporter, &cache, picture);

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

    REPORTER_ASSERT(reporter, GetNumLayers::NumLayers(&cache) == 0);
    // TODO: add VRAM/resource cache check here
#endif
}

#endif
