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