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 12namespace { 13 14struct TestMessage { 15 TestMessage(int i, float f) : x(i), y(f) {} 16 17 int x; 18 float y; 19}; 20 21static inline bool SkShouldPostMessageToBus(const TestMessage&, uint32_t) { 22 return true; 23} 24 25} // namespace 26 27DECLARE_SKMESSAGEBUS_MESSAGE(TestMessage, uint32_t, true) 28 29DEF_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 66namespace { 67 68struct TestMessageRefCnt : public SkRefCnt { 69 TestMessageRefCnt(int i, float f) : x(i), y(f) {} 70 71 int x; 72 float y; 73}; 74 75static inline bool SkShouldPostMessageToBus(const sk_sp<TestMessageRefCnt>&, uint32_t) { 76 return true; 77} 78 79} // namespace 80 81DECLARE_SKMESSAGEBUS_MESSAGE(sk_sp<TestMessageRefCnt>, uint32_t, false) 82 83DEF_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 120namespace { 121 122struct AddressedMessage { 123 GrDirectContext::DirectContextID fInboxID; 124}; 125 126static 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 137DECLARE_SKMESSAGEBUS_MESSAGE(AddressedMessage, GrDirectContext::DirectContextID, true) 138 139DEF_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