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

#include "SkDiscardableMemory.h"
#include "SkScaledImageCache.h"
#include "Test.h"

static void make_bm(SkBitmap* bm, int w, int h) {
    bm->allocN32Pixels(w, h);
}

static const int COUNT = 10;
static const int DIM = 256;

static void test_cache(skiatest::Reporter* reporter, SkScaledImageCache& cache,
                       bool testPurge) {
    SkScaledImageCache::ID* id;

    SkBitmap bm[COUNT];

    const SkScalar scale = 2;
    for (int i = 0; i < COUNT; ++i) {
        make_bm(&bm[i], DIM, DIM);
    }

    for (int i = 0; i < COUNT; ++i) {
        SkBitmap tmp;

        SkScaledImageCache::ID* id = cache.findAndLock(bm[i], scale, scale, &tmp);
        REPORTER_ASSERT(reporter, NULL == id);

        make_bm(&tmp, DIM, DIM);
        id = cache.addAndLock(bm[i], scale, scale, tmp);
        REPORTER_ASSERT(reporter, NULL != id);

        SkBitmap tmp2;
        SkScaledImageCache::ID* id2 = cache.findAndLock(bm[i], scale, scale,
                                                        &tmp2);
        REPORTER_ASSERT(reporter, id == id2);
        REPORTER_ASSERT(reporter, tmp.pixelRef() == tmp2.pixelRef());
        REPORTER_ASSERT(reporter, tmp.width() == tmp2.width());
        REPORTER_ASSERT(reporter, tmp.height() == tmp2.height());
        cache.unlock(id2);

        cache.unlock(id);
    }

    if (testPurge) {
        // stress test, should trigger purges
        float incScale = 2;
        for (size_t i = 0; i < COUNT * 100; ++i) {
            incScale += 1;

            SkBitmap tmp;
            make_bm(&tmp, DIM, DIM);

            SkScaledImageCache::ID* id = cache.addAndLock(bm[0], incScale,
                                                          incScale, tmp);
            REPORTER_ASSERT(reporter, NULL != id);
            cache.unlock(id);
        }
    }

    // test the originals after all that purging
    for (int i = 0; i < COUNT; ++i) {
        SkBitmap tmp;
        id = cache.findAndLock(bm[i], scale, scale, &tmp);
        if (id) {
            cache.unlock(id);
        }
    }

    cache.setByteLimit(0);
}

#include "SkDiscardableMemoryPool.h"

static SkDiscardableMemoryPool* gPool;
static SkDiscardableMemory* pool_factory(size_t bytes) {
    SkASSERT(gPool);
    return gPool->create(bytes);
}

DEF_TEST(ImageCache, reporter) {
    static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024;    // 1K slop

    {
        SkScaledImageCache cache(defLimit);
        test_cache(reporter, cache, true);
    }
    {
        SkAutoTUnref<SkDiscardableMemoryPool> pool(
                SkDiscardableMemoryPool::Create(defLimit, NULL));
        gPool = pool.get();
        SkScaledImageCache cache(pool_factory);
        test_cache(reporter, cache, true);
    }
    {
        SkScaledImageCache cache(SkDiscardableMemory::Create);
        test_cache(reporter, cache, false);
    }
}

DEF_TEST(ImageCache_doubleAdd, r) {
    // Adding the same key twice should be safe.
    SkScaledImageCache cache(4096);

    SkBitmap original;
    original.allocN32Pixels(40, 40);

    SkBitmap scaled1;
    scaled1.allocN32Pixels(20, 20);

    SkBitmap scaled2;
    scaled2.allocN32Pixels(20, 20);

    SkScaledImageCache::ID* id1 = cache.addAndLock(original, 0.5f, 0.5f, scaled1);
    SkScaledImageCache::ID* id2 = cache.addAndLock(original, 0.5f, 0.5f, scaled2);
    // We don't really care if id1 == id2 as long as unlocking both works.
    cache.unlock(id1);
    cache.unlock(id2);

    SkBitmap tmp;
    // Lookup should return the value that was added last.
    SkScaledImageCache::ID* id = cache.findAndLock(original, 0.5f, 0.5f, &tmp);
    REPORTER_ASSERT(r, NULL != id);
    REPORTER_ASSERT(r, tmp.getGenerationID() == scaled2.getGenerationID());
    cache.unlock(id);
}
