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 "SkOrderedWriteBuffer.h" 13 #include "SkPictureFlat.h" 14 #include "SkRefCnt.h" 15 #include "SkShader.h" 16 #include "Test.h" 17 #include "TestClassDef.h" 18 19 class FlatDictionary : public SkFlatDictionary<SkShader> { 20 21 public: 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 32 class SkBitmapHeapTester { 33 34 public: 35 static int32_t GetRefCount(const SkBitmapHeapEntry* entry) { 36 return entry->fRefCount; 37 } 38 }; 39 40 DEF_TEST(BitmapHeap, reporter) { 41 // 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 } 94