xref: /aosp_15_r20/external/skia/tests/MessageBusTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2013 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 "include/core/SkRefCnt.h"
9 #include "include/core/SkTypes.h"
10 #include "include/gpu/ganesh/GrDirectContext.h"
11 #include "include/private/base/SkTArray.h"
12 #include "src/core/SkMessageBus.h"
13 #include "tests/Test.h"
14 
15 #include <cstdint>
16 #include <utility>
17 
18 using namespace skia_private;
19 
20 namespace {
21 
22 struct TestMessage {
TestMessage__anonc2c15a200111::TestMessage23     TestMessage(int i, float f) : x(i), y(f) {}
24 
25     int x;
26     float y;
27 };
28 
SkShouldPostMessageToBus(const TestMessage &,uint32_t)29 static inline bool SkShouldPostMessageToBus(const TestMessage&, uint32_t) {
30     return true;
31 }
32 
33 }  // namespace
34 
DECLARE_SKMESSAGEBUS_MESSAGE(TestMessage,uint32_t,true)35 DECLARE_SKMESSAGEBUS_MESSAGE(TestMessage, uint32_t, true)
36 
37 DEF_TEST(MessageBus, r) {
38     using TestMessageBus = SkMessageBus<TestMessage, uint32_t>;
39     // Register two inboxes to receive all TestMessages.
40     TestMessageBus::Inbox inbox1(0), inbox2(0);
41 
42     // Send two messages.
43     const TestMessage m1 = { 5, 4.2f };
44     const TestMessage m2 = { 6, 4.3f };
45     TestMessageBus::Post(std::move(m1));
46     TestMessageBus::Post(std::move(m2));
47 
48     // Make sure we got two.
49     TArray<TestMessage> messages;
50     inbox1.poll(&messages);
51     REPORTER_ASSERT(r, 2 == messages.size());
52     REPORTER_ASSERT(r, 5 == messages[0].x);
53     REPORTER_ASSERT(r, 6 == messages[1].x);
54 
55     // Send another; check we get just that one.
56     const TestMessage m3 = { 1, 0.3f };
57     TestMessageBus::Post(m3);
58     inbox1.poll(&messages);
59     REPORTER_ASSERT(r, 1 == messages.size());
60     REPORTER_ASSERT(r, 1 == messages[0].x);
61 
62     // Nothing was sent since the last read.
63     inbox1.poll(&messages);
64     REPORTER_ASSERT(r, 0 == messages.size());
65 
66     // Over all this time, inbox2 should have piled up 3 messages.
67     inbox2.poll(&messages);
68     REPORTER_ASSERT(r, 3 == messages.size());
69     REPORTER_ASSERT(r, 5 == messages[0].x);
70     REPORTER_ASSERT(r, 6 == messages[1].x);
71     REPORTER_ASSERT(r, 1 == messages[2].x);
72 }
73 
74 namespace {
75 
76 struct TestMessageRefCnt : public SkRefCnt {
TestMessageRefCnt__anonc2c15a200211::TestMessageRefCnt77     TestMessageRefCnt(int i, float f) : x(i), y(f) {}
78 
79     int x;
80     float y;
81 };
82 
SkShouldPostMessageToBus(const sk_sp<TestMessageRefCnt> &,uint32_t)83 static inline bool SkShouldPostMessageToBus(const sk_sp<TestMessageRefCnt>&, uint32_t) {
84     return true;
85 }
86 
87 }  // namespace
88 
DECLARE_SKMESSAGEBUS_MESSAGE(sk_sp<TestMessageRefCnt>,uint32_t,false)89 DECLARE_SKMESSAGEBUS_MESSAGE(sk_sp<TestMessageRefCnt>, uint32_t, false)
90 
91 DEF_TEST(MessageBusSp, r) {
92     // Register two inboxes to receive all TestMessages.
93     using TestMessageBus = SkMessageBus<sk_sp<TestMessageRefCnt>, uint32_t, false>;
94     TestMessageBus::Inbox inbox1(0);
95 
96     // Send two messages.
97     auto m1 = sk_make_sp<TestMessageRefCnt>(5, 4.2f);
98     auto m2 = sk_make_sp<TestMessageRefCnt>(6, 4.3f);
99     TestMessageBus::Post(std::move(m1));
100     TestMessageBus::Post(std::move(m2));
101 
102     // Make sure we got two.
103     TArray<sk_sp<TestMessageRefCnt>> messages;
104     inbox1.poll(&messages);
105     REPORTER_ASSERT(r, 2 == messages.size());
106     REPORTER_ASSERT(r, messages[0]->unique());
107     REPORTER_ASSERT(r, messages[1]->unique());
108     REPORTER_ASSERT(r, 5 == messages[0]->x);
109     REPORTER_ASSERT(r, 6 == messages[1]->x);
110 
111     // Send another; check we get just that one.
112     auto m3 = sk_make_sp<TestMessageRefCnt>(1, 0.3f);
113     TestMessageBus::Post(std::move(m3));
114     inbox1.poll(&messages);
115     REPORTER_ASSERT(r, 1 == messages.size());
116     REPORTER_ASSERT(r, messages[0]->unique());
117     REPORTER_ASSERT(r, 1 == messages[0]->x);
118 
119     // Send another without std::move(), it should trigger SkASSERT().
120     // auto m4 = sk_make_sp<TestMessageRefCnt>(1, 0.3f);
121     // TestMessageBus::Post(m4);
122 
123     // Nothing was sent since the last read.
124     inbox1.poll(&messages);
125     REPORTER_ASSERT(r, 0 == messages.size());
126 }
127 
128 namespace {
129 
130 struct AddressedMessage {
131     GrDirectContext::DirectContextID fInboxID;
132 };
133 
SkShouldPostMessageToBus(const AddressedMessage & msg,GrDirectContext::DirectContextID msgBusUniqueID)134 static inline bool SkShouldPostMessageToBus(const AddressedMessage& msg,
135                                             GrDirectContext::DirectContextID msgBusUniqueID) {
136     SkASSERT(msgBusUniqueID.isValid());
137     if (!msg.fInboxID.isValid()) {
138         return true;
139     }
140     return msgBusUniqueID == msg.fInboxID;
141 }
142 
143 }  // namespace
144 
DECLARE_SKMESSAGEBUS_MESSAGE(AddressedMessage,GrDirectContext::DirectContextID,true)145 DECLARE_SKMESSAGEBUS_MESSAGE(AddressedMessage, GrDirectContext::DirectContextID, true)
146 
147 DEF_TEST(MessageBus_SkShouldPostMessageToBus, r) {
148     using ID = GrDirectContext::DirectContextID;
149     using AddressedMessageBus = SkMessageBus<AddressedMessage, ID>;
150 
151     ID idInvalid;
152     ID id1 = ID::Next(),
153        id2 = ID::Next(),
154        id3 = ID::Next();
155 
156     AddressedMessageBus::Inbox inbox1(id1), inbox2(id2);
157 
158     AddressedMessageBus::Post({idInvalid});  // Should go to both
159     AddressedMessageBus::Post({id1});        // Should go to inbox1
160     AddressedMessageBus::Post({id2});        // Should go to inbox2
161     AddressedMessageBus::Post({id3});        // Should go nowhere
162 
163     TArray<AddressedMessage> messages;
164     inbox1.poll(&messages);
165     REPORTER_ASSERT(r, messages.size() == 2);
166     if (messages.size() == 2) {
167         REPORTER_ASSERT(r, !messages[0].fInboxID.isValid());
168         REPORTER_ASSERT(r, messages[1].fInboxID == id1);
169     }
170     inbox2.poll(&messages);
171     REPORTER_ASSERT(r, messages.size() == 2);
172     if (messages.size() == 2) {
173         REPORTER_ASSERT(r, !messages[0].fInboxID.isValid());
174         REPORTER_ASSERT(r, messages[1].fInboxID == id2);
175     }
176 }
177 
178 // Multithreaded tests tbd.
179