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