blob: 89e6faf76491089c8c361d4dcba1d9af589c5d06 [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"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000012#include "SkWriteBuffer.h"
scroggo@google.com013c5d92012-11-16 20:34:37 +000013#include "SkPictureFlat.h"
14#include "SkRefCnt.h"
15#include "SkShader.h"
16#include "Test.h"
17
mtkleina74ce852014-11-12 09:19:02 -080018struct SimpleFlatController : public SkFlatController {
19 SimpleFlatController() : SkFlatController() {}
mtklein391e3182014-11-12 10:09:10 -080020 ~SimpleFlatController() { fAllocations.freeAll(); }
mtklein36352bf2015-03-25 18:17:31 -070021 void* allocThrow(size_t bytes) override {
mtklein391e3182014-11-12 10:09:10 -080022 fAllocations.push(sk_malloc_throw(bytes));
23 return fAllocations.top();
24 }
mtklein36352bf2015-03-25 18:17:31 -070025 void unalloc(void*) override { }
mtkleina74ce852014-11-12 09:19:02 -080026 void setBitmapStorage(SkBitmapHeap* h) { this->setBitmapHeap(h); }
mtklein391e3182014-11-12 10:09:10 -080027private:
28 SkTDArray<void*> fAllocations;
mtkleina74ce852014-11-12 09:19:02 -080029};
30
commit-bot@chromium.org07adb632014-01-02 22:20:49 +000031struct SkShaderTraits {
commit-bot@chromium.org186c0cc2014-02-18 16:15:05 +000032 static void Flatten(SkWriteBuffer& buffer, const SkShader& shader) {
commit-bot@chromium.org07adb632014-01-02 22:20:49 +000033 buffer.writeFlattenable(&shader);
scroggo@google.com013c5d92012-11-16 20:34:37 +000034 }
35};
commit-bot@chromium.org07adb632014-01-02 22:20:49 +000036typedef SkFlatDictionary<SkShader, SkShaderTraits> FlatDictionary;
scroggo@google.com013c5d92012-11-16 20:34:37 +000037
38class SkBitmapHeapTester {
scroggo@google.com013c5d92012-11-16 20:34:37 +000039public:
40 static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
41 return entry->fRefCount;
42 }
43};
44
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000045DEF_TEST(BitmapHeap, reporter) {
scroggo@google.com013c5d92012-11-16 20:34:37 +000046 // Create a bitmap shader.
47 SkBitmap bm;
commit-bot@chromium.orgfa9e5fa2014-02-13 22:00:04 +000048 bm.allocN32Pixels(2, 2);
scroggo@google.com013c5d92012-11-16 20:34:37 +000049 bm.eraseColor(SK_ColorRED);
50 uint32_t* pixel = bm.getAddr32(1,0);
51 *pixel = SK_ColorBLUE;
52
reed1a9b9642016-03-13 14:13:58 -070053 auto bitmapShader = SkShader::MakeBitmapShader(bm, SkShader::kRepeat_TileMode,
54 SkShader::kRepeat_TileMode);
scroggo@google.com013c5d92012-11-16 20:34:37 +000055
56 // Flatten, storing it in the bitmap heap.
57 SkBitmapHeap heap(1, 1);
mtkleina74ce852014-11-12 09:19:02 -080058 SimpleFlatController controller;
scroggo@google.com013c5d92012-11-16 20:34:37 +000059 controller.setBitmapStorage(&heap);
60 FlatDictionary dictionary(&controller);
61
62 // Dictionary and heap start off empty.
63 REPORTER_ASSERT(reporter, heap.count() == 0);
64 REPORTER_ASSERT(reporter, dictionary.count() == 0);
65
66 heap.deferAddingOwners();
67 int index = dictionary.find(*bitmapShader);
68 heap.endAddingOwnersDeferral(true);
69
70 // The dictionary and heap should now each have one entry.
71 REPORTER_ASSERT(reporter, 1 == index);
72 REPORTER_ASSERT(reporter, heap.count() == 1);
73 REPORTER_ASSERT(reporter, dictionary.count() == 1);
74
75 // The bitmap entry's refcount should be 1, then 0 after release.
76 SkBitmapHeapEntry* entry = heap.getEntry(0);
77 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 1);
78
79 entry->releaseRef();
80 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);
81
82 // Now clear out the heap, after which it should be empty.
83 heap.freeMemoryIfPossible(~0U);
84 REPORTER_ASSERT(reporter, heap.count() == 0);
85
86 // Now attempt to flatten the shader again.
87 heap.deferAddingOwners();
88 index = dictionary.find(*bitmapShader);
89 heap.endAddingOwnersDeferral(false);
90
91 // The dictionary should report the same index since the new entry is identical.
92 // The bitmap heap should contain the bitmap, but with no references.
93 REPORTER_ASSERT(reporter, 1 == index);
94 REPORTER_ASSERT(reporter, heap.count() == 1);
95 REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(heap.getEntry(0)) == 0);
96}