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