1 /*
2 * Copyright 2015 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 "Test.h"
9
10 #include "SkMallocPixelRef.h"
11 #include "SkPixelRef.h"
12
decrement_counter_proc(void * pixels,void * ctx)13 static void decrement_counter_proc(void* pixels, void* ctx) {
14 int* counter = (int*)ctx;
15 *counter -= 1;
16 }
17
test_dont_leak_install(skiatest::Reporter * reporter)18 static void test_dont_leak_install(skiatest::Reporter* reporter) {
19 bool success;
20 int release_counter;
21 SkImageInfo info;
22 SkBitmap bm;
23
24 info = SkImageInfo::MakeN32Premul(0, 0);
25 release_counter = 1;
26 success = bm.installPixels(info, nullptr, 0, nullptr, decrement_counter_proc, &release_counter);
27 REPORTER_ASSERT(reporter, true == success);
28 bm.reset();
29 REPORTER_ASSERT(reporter, 0 == release_counter);
30
31 info = SkImageInfo::MakeN32Premul(10, 10);
32 release_counter = 1;
33 success = bm.installPixels(info, nullptr, 0, nullptr, decrement_counter_proc, &release_counter);
34 REPORTER_ASSERT(reporter, true == success);
35 bm.reset();
36 REPORTER_ASSERT(reporter, 0 == release_counter);
37
38 info = SkImageInfo::MakeN32Premul(-10, -10);
39 release_counter = 1;
40 success = bm.installPixels(info, nullptr, 0, nullptr, decrement_counter_proc, &release_counter);
41 REPORTER_ASSERT(reporter, false == success);
42 bm.reset();
43 REPORTER_ASSERT(reporter, 0 == release_counter);
44 }
45
test_install(skiatest::Reporter * reporter)46 static void test_install(skiatest::Reporter* reporter) {
47 bool success;
48 SkImageInfo info = SkImageInfo::MakeN32Premul(0, 0);
49 SkBitmap bm;
50 // make sure we don't assert on an empty install
51 success = bm.installPixels(info, nullptr, 0);
52 REPORTER_ASSERT(reporter, success);
53
54 // no pixels should be the same as setInfo()
55 info = SkImageInfo::MakeN32Premul(10, 10);
56 success = bm.installPixels(info, nullptr, 0);
57 REPORTER_ASSERT(reporter, success);
58
59 }
60
61 class TestListener : public SkPixelRef::GenIDChangeListener {
62 public:
TestListener(int * ptr)63 explicit TestListener(int* ptr) : fPtr(ptr) {}
onChange()64 void onChange() override { (*fPtr)++; }
65 private:
66 int* fPtr;
67 };
68
DEF_TEST(PixelRef_GenIDChange,r)69 DEF_TEST(PixelRef_GenIDChange, r) {
70 SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
71
72 SkAutoTUnref<SkPixelRef> pixelRef(SkMallocPixelRef::NewAllocate(info, 0, nullptr));
73
74 // Register a listener.
75 int count = 0;
76 pixelRef->addGenIDChangeListener(new TestListener(&count));
77 REPORTER_ASSERT(r, 0 == count);
78
79 // No one has looked at our pixelRef's generation ID, so invalidating it doesn't make sense.
80 // (An SkPixelRef tree falls in the forest but there's nobody around to hear it. Do we care?)
81 pixelRef->notifyPixelsChanged();
82 REPORTER_ASSERT(r, 0 == count);
83
84 // Force the generation ID to be calculated.
85 REPORTER_ASSERT(r, 0 != pixelRef->getGenerationID());
86
87 // Our listener was dropped in the first call to notifyPixelsChanged(). This is a no-op.
88 pixelRef->notifyPixelsChanged();
89 REPORTER_ASSERT(r, 0 == count);
90
91 // Force the generation ID to be recalculated, then add a listener.
92 REPORTER_ASSERT(r, 0 != pixelRef->getGenerationID());
93 pixelRef->addGenIDChangeListener(new TestListener(&count));
94 pixelRef->notifyPixelsChanged();
95 REPORTER_ASSERT(r, 1 == count);
96
97 // Quick check that nullptr is safe.
98 REPORTER_ASSERT(r, 0 != pixelRef->getGenerationID());
99 pixelRef->addGenIDChangeListener(nullptr);
100 pixelRef->notifyPixelsChanged();
101
102 test_install(r);
103 test_dont_leak_install(r);
104 }
105