--- /dev/null
+
+/*
+ * 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)