scroggo@google.com | 013c5d9 | 2012-11-16 20:34:37 +0000 | [diff] [blame^] | 1 | |
| 2 | /* |
| 3 | * Copyright 2012 Google Inc. |
| 4 | * |
| 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
| 7 | */ |
| 8 | |
| 9 | #include "SkBitmap.h" |
| 10 | #include "SkBitmapHeap.h" |
| 11 | #include "SkColor.h" |
| 12 | #include "SkFlattenable.h" |
| 13 | #include "SkOrderedWriteBuffer.h" |
| 14 | #include "SkPictureFlat.h" |
| 15 | #include "SkRefCnt.h" |
| 16 | #include "SkShader.h" |
| 17 | #include "Test.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 | static void TestBitmapHeap(skiatest::Reporter* 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 | |
| 95 | #include "TestClassDef.h" |
| 96 | DEFINE_TESTCLASS("BitmapHeap", TestBitmapHeapClass, TestBitmapHeap) |