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