21ce2f39e8500e60bbd2f52835c34cb43abb375a
[platform/upstream/libSkiaSharp.git] / tests / BitmapHeapTest.cpp
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "SkBitmap.h"
9 #include "SkBitmapHeap.h"
10 #include "SkColor.h"
11 #include "SkFlattenable.h"
12 #include "SkWriteBuffer.h"
13 #include "SkPictureFlat.h"
14 #include "SkRefCnt.h"
15 #include "SkShader.h"
16 #include "Test.h"
17
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();
24     }
25     void unalloc(void*) SK_OVERRIDE { }
26     void setBitmapStorage(SkBitmapHeap* h) { this->setBitmapHeap(h); }
27 private:
28     SkTDArray<void*> fAllocations;
29 };
30
31 struct SkShaderTraits {
32     static void Flatten(SkWriteBuffer& buffer, const SkShader& shader) {
33         buffer.writeFlattenable(&shader);
34     }
35 };
36 typedef SkFlatDictionary<SkShader, SkShaderTraits> FlatDictionary;
37
38 class SkBitmapHeapTester {
39 public:
40     static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
41         return entry->fRefCount;
42     }
43 };
44
45 DEF_TEST(BitmapHeap, reporter) {
46     // Create a bitmap shader.
47     SkBitmap bm;
48     bm.allocN32Pixels(2, 2);
49     bm.eraseColor(SK_ColorRED);
50     uint32_t* pixel = bm.getAddr32(1,0);
51     *pixel = SK_ColorBLUE;
52
53     SkShader* bitmapShader = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
54                                                           SkShader::kRepeat_TileMode);
55     SkAutoTUnref<SkShader> aur(bitmapShader);
56
57     // Flatten, storing it in the bitmap heap.
58     SkBitmapHeap heap(1, 1);
59     SimpleFlatController controller;
60     controller.setBitmapStorage(&heap);
61     FlatDictionary dictionary(&controller);
62
63     // Dictionary and heap start off empty.
64     REPORTER_ASSERT(reporter, heap.count() == 0);
65     REPORTER_ASSERT(reporter, dictionary.count() == 0);
66
67     heap.deferAddingOwners();
68     int index = dictionary.find(*bitmapShader);
69     heap.endAddingOwnersDeferral(true);
70
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);
75
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);
79
80     entry->releaseRef();
81     REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);
82
83     // Now clear out the heap, after which it should be empty.
84     heap.freeMemoryIfPossible(~0U);
85     REPORTER_ASSERT(reporter, heap.count() == 0);
86
87     // Now attempt to flatten the shader again.
88     heap.deferAddingOwners();
89     index = dictionary.find(*bitmapShader);
90     heap.endAddingOwnersDeferral(false);
91
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);
97 }