2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "SkBitmapHeap.h"
11 #include "SkFlattenable.h"
12 #include "SkWriteBuffer.h"
13 #include "SkPictureFlat.h"
18 struct SimpleFlatController : public SkFlatController {
19 SimpleFlatController() : SkFlatController() {}
20 ~SimpleFlatController() { fAllocations.freeAll(); }
21 void* allocThrow(size_t bytes) SK_OVERRIDE {
22 fAllocations.push(sk_malloc_throw(bytes));
23 return fAllocations.top();
25 void unalloc(void*) SK_OVERRIDE { }
26 void setBitmapStorage(SkBitmapHeap* h) { this->setBitmapHeap(h); }
28 SkTDArray<void*> fAllocations;
31 struct SkShaderTraits {
32 static void Flatten(SkWriteBuffer& buffer, const SkShader& shader) {
33 buffer.writeFlattenable(&shader);
36 typedef SkFlatDictionary<SkShader, SkShaderTraits> FlatDictionary;
38 class SkBitmapHeapTester {
40 static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
41 return entry->fRefCount;
45 DEF_TEST(BitmapHeap, reporter) {
46 // Create a bitmap shader.
48 bm.allocN32Pixels(2, 2);
49 bm.eraseColor(SK_ColorRED);
50 uint32_t* pixel = bm.getAddr32(1,0);
51 *pixel = SK_ColorBLUE;
53 SkShader* bitmapShader = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
54 SkShader::kRepeat_TileMode);
55 SkAutoTUnref<SkShader> aur(bitmapShader);
57 // Flatten, storing it in the bitmap heap.
58 SkBitmapHeap heap(1, 1);
59 SimpleFlatController controller;
60 controller.setBitmapStorage(&heap);
61 FlatDictionary dictionary(&controller);
63 // Dictionary and heap start off empty.
64 REPORTER_ASSERT(reporter, heap.count() == 0);
65 REPORTER_ASSERT(reporter, dictionary.count() == 0);
67 heap.deferAddingOwners();
68 int index = dictionary.find(*bitmapShader);
69 heap.endAddingOwnersDeferral(true);
71 // The dictionary and heap should now each have one entry.
72 REPORTER_ASSERT(reporter, 1 == index);
73 REPORTER_ASSERT(reporter, heap.count() == 1);
74 REPORTER_ASSERT(reporter, dictionary.count() == 1);
76 // The bitmap entry's refcount should be 1, then 0 after release.
77 SkBitmapHeapEntry* entry = heap.getEntry(0);
78 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 1);
81 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);
83 // Now clear out the heap, after which it should be empty.
84 heap.freeMemoryIfPossible(~0U);
85 REPORTER_ASSERT(reporter, heap.count() == 0);
87 // Now attempt to flatten the shader again.
88 heap.deferAddingOwners();
89 index = dictionary.find(*bitmapShader);
90 heap.endAddingOwnersDeferral(false);
92 // The dictionary should report the same index since the new entry is identical.
93 // The bitmap heap should contain the bitmap, but with no references.
94 REPORTER_ASSERT(reporter, 1 == index);
95 REPORTER_ASSERT(reporter, heap.count() == 1);
96 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(heap.getEntry(0)) == 0);