blob: 2b5cf830c5933df2b0a9a84ad9aa0090e9922285 [file] [log] [blame]
scroggo@google.com013c5d92012-11-16 20:34:37 +00001/*
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 "SkOrderedWriteBuffer.h"
13#include "SkPictureFlat.h"
14#include "SkRefCnt.h"
15#include "SkShader.h"
16#include "Test.h"
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000017#include "TestClassDef.h"
scroggo@google.com013c5d92012-11-16 20:34:37 +000018
19class FlatDictionary : public SkFlatDictionary<SkShader> {
20
21public:
22 FlatDictionary(SkFlatController* controller)
23 : SkFlatDictionary<SkShader>(controller) {
24 fFlattenProc = &flattenFlattenableProc;
25 // No need for an unflattenProc
26 }
27 static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer, const void* obj) {
28 buffer.writeFlattenable((SkFlattenable*)obj);
29 }
30};
31
32class SkBitmapHeapTester {
33
34public:
35 static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
36 return entry->fRefCount;
37 }
38};
39
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000040DEF_TEST(BitmapHeap, reporter) {
scroggo@google.com013c5d92012-11-16 20:34:37 +000041 // Create a bitmap shader.
42 SkBitmap bm;
43 bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
44 bm.allocPixels();
45 bm.eraseColor(SK_ColorRED);
46 uint32_t* pixel = bm.getAddr32(1,0);
47 *pixel = SK_ColorBLUE;
48
49 SkShader* bitmapShader = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
50 SkShader::kRepeat_TileMode);
51 SkAutoTUnref<SkShader> aur(bitmapShader);
52
53 // Flatten, storing it in the bitmap heap.
54 SkBitmapHeap heap(1, 1);
55 SkChunkFlatController controller(1024);
56 controller.setBitmapStorage(&heap);
57 FlatDictionary dictionary(&controller);
58
59 // Dictionary and heap start off empty.
60 REPORTER_ASSERT(reporter, heap.count() == 0);
61 REPORTER_ASSERT(reporter, dictionary.count() == 0);
62
63 heap.deferAddingOwners();
64 int index = dictionary.find(*bitmapShader);
65 heap.endAddingOwnersDeferral(true);
66
67 // The dictionary and heap should now each have one entry.
68 REPORTER_ASSERT(reporter, 1 == index);
69 REPORTER_ASSERT(reporter, heap.count() == 1);
70 REPORTER_ASSERT(reporter, dictionary.count() == 1);
71
72 // The bitmap entry's refcount should be 1, then 0 after release.
73 SkBitmapHeapEntry* entry = heap.getEntry(0);
74 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 1);
75
76 entry->releaseRef();
77 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);
78
79 // Now clear out the heap, after which it should be empty.
80 heap.freeMemoryIfPossible(~0U);
81 REPORTER_ASSERT(reporter, heap.count() == 0);
82
83 // Now attempt to flatten the shader again.
84 heap.deferAddingOwners();
85 index = dictionary.find(*bitmapShader);
86 heap.endAddingOwnersDeferral(false);
87
88 // The dictionary should report the same index since the new entry is identical.
89 // The bitmap heap should contain the bitmap, but with no references.
90 REPORTER_ASSERT(reporter, 1 == index);
91 REPORTER_ASSERT(reporter, heap.count() == 1);
92 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(heap.getEntry(0)) == 0);
93}