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