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

#include "SkBitmap.h"
#include "SkBitmapHeap.h"
#include "SkColor.h"
#include "SkFlattenable.h"
#include "SkOrderedWriteBuffer.h"
#include "SkPictureFlat.h"
#include "SkRefCnt.h"
#include "SkShader.h"
#include "Test.h"

class FlatDictionary : public SkFlatDictionary<SkShader> {

public:
    FlatDictionary(SkFlatController* controller)
    : SkFlatDictionary<SkShader>(controller) {
        fFlattenProc = &flattenFlattenableProc;
        // No need for an unflattenProc
    }
    static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer, const void* obj) {
        buffer.writeFlattenable((SkFlattenable*)obj);
    }
};

class SkBitmapHeapTester {

public:
    static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
        return entry->fRefCount;
    }
};

static void TestBitmapHeap(skiatest::Reporter* reporter) {
    // Create a bitmap shader.
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
    bm.allocPixels();
    bm.eraseColor(SK_ColorRED);
    uint32_t* pixel = bm.getAddr32(1,0);
    *pixel = SK_ColorBLUE;

    SkShader* bitmapShader = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
                                                          SkShader::kRepeat_TileMode);
    SkAutoTUnref<SkShader> aur(bitmapShader);

    // Flatten, storing it in the bitmap heap.
    SkBitmapHeap heap(1, 1);
    SkChunkFlatController controller(1024);
    controller.setBitmapStorage(&heap);
    FlatDictionary dictionary(&controller);

    // Dictionary and heap start off empty.
    REPORTER_ASSERT(reporter, heap.count() == 0);
    REPORTER_ASSERT(reporter, dictionary.count() == 0);

    heap.deferAddingOwners();
    int index = dictionary.find(*bitmapShader);
    heap.endAddingOwnersDeferral(true);

    // The dictionary and heap should now each have one entry.
    REPORTER_ASSERT(reporter, 1 == index);
    REPORTER_ASSERT(reporter, heap.count() == 1);
    REPORTER_ASSERT(reporter, dictionary.count() == 1);

    // The bitmap entry's refcount should be 1, then 0 after release.
    SkBitmapHeapEntry* entry = heap.getEntry(0);
    REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 1);

    entry->releaseRef();
    REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);

    // Now clear out the heap, after which it should be empty.
    heap.freeMemoryIfPossible(~0U);
    REPORTER_ASSERT(reporter, heap.count() == 0);

    // Now attempt to flatten the shader again.
    heap.deferAddingOwners();
    index = dictionary.find(*bitmapShader);
    heap.endAddingOwnersDeferral(false);

    // The dictionary should report the same index since the new entry is identical.
    // The bitmap heap should contain the bitmap, but with no references.
    REPORTER_ASSERT(reporter, 1 == index);
    REPORTER_ASSERT(reporter, heap.count() == 1);
    REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(heap.getEntry(0)) == 0);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("BitmapHeap", TestBitmapHeapClass, TestBitmapHeap)
