blob: 73ca69bfecf4b752313352eb1a244fa52a45e421 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <gtest/gtest.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07002#include <poll.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <private/dvr/buffer_hub_client.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07004#include <private/dvr/bufferhub_rpc.h>
5#include <sys/epoll.h>
6#include <sys/eventfd.h>
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -07007#include <ui/BufferHubBuffer.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08008
9#include <mutex>
10#include <thread>
11
Alex Vakulenko4fe60582017-02-02 11:35:59 -080012#define RETRY_EINTR(fnc_call) \
13 ([&]() -> decltype(fnc_call) { \
14 decltype(fnc_call) result; \
15 do { \
16 result = (fnc_call); \
17 } while (result == -1 && errno == EINTR); \
18 return result; \
19 })()
20
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -070021using android::BufferHubBuffer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070022using android::GraphicBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070023using android::sp;
Tianyu1a60bb42018-10-08 14:56:08 -070024using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070025using android::dvr::ProducerBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070026using android::dvr::BufferHubDefs::IsBufferAcquired;
27using android::dvr::BufferHubDefs::IsBufferGained;
28using android::dvr::BufferHubDefs::IsBufferPosted;
29using android::dvr::BufferHubDefs::IsBufferReleased;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070030using android::dvr::BufferHubDefs::kConsumerStateMask;
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070031using android::dvr::BufferHubDefs::kFirstClientBitMask;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070032using android::dvr::BufferHubDefs::kMetadataHeaderSize;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070033using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080034using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070035using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036
37const int kWidth = 640;
38const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070039const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080040const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
41const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070042const size_t kUserMetadataSize = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070043// Maximum number of consumers for the buffer that only has one producer in the
44// test.
45const size_t kMaxConsumerCount =
46 android::dvr::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080047const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080048
49using LibBufferHubTest = ::testing::Test;
50
51TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070052 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080053 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
54 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -070055 std::unique_ptr<ConsumerBuffer> c =
56 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057 ASSERT_TRUE(c.get() != nullptr);
58 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070059 std::unique_ptr<ConsumerBuffer> c2 =
60 ConsumerBuffer::Import(c->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080061 ASSERT_TRUE(c2.get() != nullptr);
62
Corey Tabaka52ea25c2017-09-13 18:02:48 -070063 // Producer state mask is unique, i.e. 1.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070064 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070065 // Consumer state mask cannot have producer bit on.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070066 EXPECT_EQ(c->client_state_mask() & kFirstClientBitMask, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070067 // Consumer state mask must be a single, i.e. power of 2.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070068 EXPECT_NE(c->client_state_mask(), 0U);
69 EXPECT_EQ(c->client_state_mask() & (c->client_state_mask() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070070 // Consumer state mask cannot have producer bit on.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070071 EXPECT_EQ(c2->client_state_mask() & kFirstClientBitMask, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070072 // Consumer state mask must be a single, i.e. power of 2.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070073 EXPECT_NE(c2->client_state_mask(), 0U);
74 EXPECT_EQ(c2->client_state_mask() & (c2->client_state_mask() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070075 // Each consumer should have unique bit.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070076 EXPECT_EQ(c->client_state_mask() & c2->client_state_mask(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070077
78 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080079 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
80 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
81 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070082
Tianyu58a05a22018-10-10 18:41:27 -070083 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070084
85 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080086 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
87 EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
88 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090 LocalHandle fence;
Tianyu58a05a22018-10-10 18:41:27 -070091 EXPECT_EQ(0, c->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080092 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
93 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080094
Tianyu58a05a22018-10-10 18:41:27 -070095 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080096 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
97 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080098
99 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800100 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800101 EXPECT_EQ(0, c2->Discard());
102
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800103 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800104 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800105 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
106 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
107 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700108}
109
110TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700111 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700112 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
113 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700114 std::unique_ptr<ConsumerBuffer> c =
115 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700116 ASSERT_TRUE(c.get() != nullptr);
117
118 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
119 ASSERT_TRUE(epoll_fd.IsValid());
120
121 epoll_event event;
122 std::array<epoll_event, 64> events;
123
124 auto event_sources = p->GetEventSources();
125 ASSERT_LT(event_sources.size(), events.size());
126
127 for (const auto& event_source : event_sources) {
128 event = {.events = event_source.event_mask | EPOLLET,
129 .data = {.fd = p->event_fd()}};
130 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
131 &event));
132 }
133
134 event_sources = c->GetEventSources();
135 ASSERT_LT(event_sources.size(), events.size());
136
137 for (const auto& event_source : event_sources) {
138 event = {.events = event_source.event_mask | EPOLLET,
139 .data = {.fd = c->event_fd()}};
140 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
141 &event));
142 }
143
144 // No events should be signaled initially.
145 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
146
147 // Post the producer and check for consumer signal.
Tianyu58a05a22018-10-10 18:41:27 -0700148 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800149 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
150 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700151 ASSERT_TRUE(events[0].events & EPOLLIN);
152 ASSERT_EQ(c->event_fd(), events[0].data.fd);
153
154 // Save the event bits to translate later.
155 event = events[0];
156
157 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800158 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
159 kPollTimeoutMs));
160 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
161 kPollTimeoutMs));
162 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
163 kPollTimeoutMs));
164 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
165 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700166
167 // Translate the events.
168 auto event_status = c->GetEventMask(event.events);
169 ASSERT_TRUE(event_status);
170 ASSERT_TRUE(event_status.get() & EPOLLIN);
171
172 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800173 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
174 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700175}
176
177TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700178 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700179 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
180 ASSERT_TRUE(p.get() != nullptr);
181
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700182 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700183 uint64_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700184 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700185 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700186 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700187 ASSERT_TRUE(cs[i].get() != nullptr);
188 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700189 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
190 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700191 }
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700192 EXPECT_EQ(client_state_masks, kFirstClientBitMask | kConsumerStateMask);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700193
194 // The 64th creation will fail with out-of-memory error.
195 auto state = p->CreateConsumer();
196 EXPECT_EQ(state.error(), E2BIG);
197
198 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700199 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700200 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700201 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700202 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700203 ASSERT_TRUE(cs[i].get() != nullptr);
204 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700205 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
206 client_state_masks |= cs[i]->client_state_mask();
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700207 EXPECT_EQ(client_state_masks, kFirstClientBitMask | kConsumerStateMask);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700208 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800209}
210
Corey Tabakad53870c2017-07-06 18:04:27 -0700211TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700212 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700213 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
214 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700215 std::unique_ptr<ConsumerBuffer> c =
216 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700217 ASSERT_TRUE(c.get() != nullptr);
218
Corey Tabakad53870c2017-07-06 18:04:27 -0700219 LocalHandle fence;
220
221 // The producer buffer starts in gained state.
222
223 // Acquire, release, and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700224 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700225 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
226 EXPECT_EQ(-EALREADY, p->Gain(&fence));
227
228 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700229 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700230
231 // Post, release, and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700232 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700233 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
234 EXPECT_EQ(-EBUSY, p->Gain(&fence));
235
236 // Acquire in posted state should succeed.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700237 EXPECT_LE(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700238
239 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700240 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700241 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700242 EXPECT_EQ(-EBUSY, p->Gain(&fence));
243
244 // Release in acquired state should succeed.
245 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800246 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700247
248 // Release, acquire, and post in released state should fail.
249 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
Tianyu Jiangee723f52018-10-24 16:37:38 -0700250 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700251 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700252
253 // Gain in released state should succeed.
254 EXPECT_EQ(0, p->Gain(&fence));
255
256 // Acquire, release, and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700257 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700258 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
259 EXPECT_EQ(-EALREADY, p->Gain(&fence));
260}
261
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700262TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700263 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700264 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
265 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700266 std::unique_ptr<ConsumerBuffer> c =
267 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700268 ASSERT_TRUE(c.get() != nullptr);
269
270 DvrNativeBufferMetadata metadata;
271 LocalHandle invalid_fence;
272
273 // The producer buffer starts in gained state.
274
275 // Acquire, release, and gain in gained state should fail.
276 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
277 EXPECT_FALSE(invalid_fence.IsValid());
278 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
279 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
280 EXPECT_FALSE(invalid_fence.IsValid());
281
282 // Post in gained state should succeed.
283 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
284 EXPECT_EQ(p->buffer_state(), c->buffer_state());
285 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
286
287 // Post, release, and gain in posted state should fail.
288 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
289 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
290 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
291 EXPECT_FALSE(invalid_fence.IsValid());
292
293 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800294 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700295 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
296 EXPECT_FALSE(invalid_fence.IsValid());
297 EXPECT_EQ(p->buffer_state(), c->buffer_state());
298 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
299
300 // Acquire, post, and gain in acquired state should fail.
301 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
302 EXPECT_FALSE(invalid_fence.IsValid());
303 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
304 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
305 EXPECT_FALSE(invalid_fence.IsValid());
306
307 // Release in acquired state should succeed.
308 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800309 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700310 EXPECT_EQ(p->buffer_state(), c->buffer_state());
311 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
312
313 // Release, acquire, and post in released state should fail.
314 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
315 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
316 EXPECT_FALSE(invalid_fence.IsValid());
317 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
318
319 // Gain in released state should succeed.
320 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
321 EXPECT_FALSE(invalid_fence.IsValid());
322 EXPECT_EQ(p->buffer_state(), c->buffer_state());
323 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
324
325 // Acquire, release, and gain in gained state should fail.
326 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
327 EXPECT_FALSE(invalid_fence.IsValid());
328 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
329 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
330 EXPECT_FALSE(invalid_fence.IsValid());
331}
332
Tianyu5465d6c2018-08-14 13:03:10 -0700333TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
334 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
335 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
336 ASSERT_TRUE(p.get() != nullptr);
337
338 // The producer buffer starts in gained state. Post the buffer.
339 ASSERT_EQ(0, p->Post(LocalHandle()));
340
341 // Gain in posted state should only succeed with gain_posted_buffer = true.
342 LocalHandle invalid_fence;
343 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
344 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
345}
346
347TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
348 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
349 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
350 ASSERT_TRUE(p.get() != nullptr);
351
352 // The producer buffer starts in gained state. Post the buffer.
353 ASSERT_EQ(0, p->Post(LocalHandle()));
354
355 // GainAsync in posted state should only succeed with gain_posted_buffer
356 // equals true.
357 DvrNativeBufferMetadata metadata;
358 LocalHandle invalid_fence;
359 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
360 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
361}
362
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700363TEST_F(LibBufferHubTest, TestZeroConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700364 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700365 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
366 ASSERT_TRUE(p.get() != nullptr);
367
368 DvrNativeBufferMetadata metadata;
369 LocalHandle invalid_fence;
370
371 // Newly created.
372 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
373 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
374 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
375
376 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800377 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700378
379 // A new consumer should still be able to acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700380 std::unique_ptr<ConsumerBuffer> c =
381 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700382 ASSERT_TRUE(c.get() != nullptr);
383 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
384 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
385}
386
387TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700388 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700389 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
390 ASSERT_TRUE(p.get() != nullptr);
391
Tianyu1a60bb42018-10-08 14:56:08 -0700392 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700393 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700394 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700395 ASSERT_TRUE(cs[i].get() != nullptr);
396 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
397 }
398
399 DvrNativeBufferMetadata metadata;
400 LocalHandle invalid_fence;
401
402 // Post the producer should trigger all consumers to be available.
403 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
404 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
405 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700406 EXPECT_TRUE(
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700407 IsBufferPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800408 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700409 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
410 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
411 }
412
413 // All consumers have to release before the buffer is considered to be
414 // released.
415 for (size_t i = 0; i < kMaxConsumerCount; i++) {
416 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
417 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
418 }
419
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800420 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700421 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
422
423 // Buffer state cross all clients must be consistent.
424 for (size_t i = 0; i < kMaxConsumerCount; i++) {
425 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
426 }
427}
428
429TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700430 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700431 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
432 ASSERT_TRUE(p.get() != nullptr);
433 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
434
Tianyu1a60bb42018-10-08 14:56:08 -0700435 std::unique_ptr<ConsumerBuffer> c =
436 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700437 ASSERT_TRUE(c.get() != nullptr);
438 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
439
440 DvrNativeBufferMetadata metadata;
441 LocalHandle invalid_fence;
442
443 // Post the gained buffer should signal already created consumer.
444 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
445 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800446 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700447 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
448 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
449}
450
451TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
Tianyu1a60bb42018-10-08 14:56:08 -0700452 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700453 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
454 ASSERT_TRUE(p.get() != nullptr);
455 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
456
457 DvrNativeBufferMetadata metadata;
458 LocalHandle invalid_fence;
459
460 // Post the gained buffer before any consumer gets created.
461 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
462 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
463
464 // Newly created consumer should be automatically sigalled.
Tianyu1a60bb42018-10-08 14:56:08 -0700465 std::unique_ptr<ConsumerBuffer> c =
466 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700467 ASSERT_TRUE(c.get() != nullptr);
468 EXPECT_TRUE(IsBufferPosted(c->buffer_state()));
469 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
470 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
471}
472
473TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700474 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700475 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
476 ASSERT_TRUE(p.get() != nullptr);
477
Tianyu1a60bb42018-10-08 14:56:08 -0700478 std::unique_ptr<ConsumerBuffer> c1 =
479 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700480 ASSERT_TRUE(c1.get() != nullptr);
481
482 DvrNativeBufferMetadata metadata;
483 LocalHandle invalid_fence;
484
485 // Post, acquire, and release the buffer..
486 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800487 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700488 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
489 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
490
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800491 // Note that the next PDX call is on the producer channel, which may be
492 // executed before Release impulse gets executed by bufferhubd. Thus, here we
493 // need to wait until the releasd is confirmed before creating another
494 // consumer.
495 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
496 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
497
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700498 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800499 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700500 std::unique_ptr<ConsumerBuffer> c2 =
501 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700502 ASSERT_TRUE(c2.get() != nullptr);
503
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700504 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
505 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
506 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
507}
508
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800509TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
510 struct Metadata {
511 int64_t field1;
512 int64_t field2;
513 };
Tianyu1a60bb42018-10-08 14:56:08 -0700514 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800515 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
516 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700517 std::unique_ptr<ConsumerBuffer> c =
518 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519 ASSERT_TRUE(c.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800520 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700521 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800522 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800523 LocalHandle fence;
524 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700525 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800526 EXPECT_EQ(m.field1, m2.field1);
527 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800528 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800529 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800530}
531
532TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
533 struct Metadata {
534 int64_t field1;
535 int64_t field2;
536 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700537 struct OverSizedMetadata {
538 int64_t field1;
539 int64_t field2;
540 int64_t field3;
541 };
Tianyu1a60bb42018-10-08 14:56:08 -0700542 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800543 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
544 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700545 std::unique_ptr<ConsumerBuffer> c =
546 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800547 ASSERT_TRUE(c.get() != nullptr);
548
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700549 // It is illegal to post metadata larger than originally requested during
550 // buffer allocation.
551 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700552 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800553 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700554
555 // It is ok to post metadata smaller than originally requested during
556 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700557 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800558}
559
560TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
561 struct Metadata {
562 int64_t field1;
563 int64_t field2;
564 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700565 struct OverSizedMetadata {
566 int64_t field1;
567 int64_t field2;
568 int64_t field3;
569 };
Tianyu1a60bb42018-10-08 14:56:08 -0700570 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800571 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
572 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700573 std::unique_ptr<ConsumerBuffer> c =
574 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800575 ASSERT_TRUE(c.get() != nullptr);
576
577 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700578 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800579
580 LocalHandle fence;
581 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700582 OverSizedMetadata e;
583
584 // It is illegal to acquire metadata larger than originally requested during
585 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700586 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700587
588 // It is ok to acquire metadata smaller than originally requested during
589 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700590 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700591 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800592}
593
594TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700595 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800596 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
597 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700598 std::unique_ptr<ConsumerBuffer> c =
599 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800600 ASSERT_TRUE(c.get() != nullptr);
601
602 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700603 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800604
605 LocalHandle fence;
606 EXPECT_EQ(0, c->Acquire(&fence));
607}
608
609TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700610 std::unique_ptr<ProducerBuffer> p =
611 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800612 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700613 std::unique_ptr<ConsumerBuffer> c =
614 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800615 ASSERT_TRUE(c.get() != nullptr);
616
617 LocalHandle fence;
618
Tianyue6e08ab2018-09-13 18:48:55 -0700619 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800620 EXPECT_EQ(0, c->Acquire(&fence));
621}
622
623TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700624 std::unique_ptr<ProducerBuffer> p =
625 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800626 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700627 std::unique_ptr<ConsumerBuffer> c =
628 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800629 ASSERT_TRUE(c.get() != nullptr);
630
631 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700632 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800633}
634
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700635namespace {
636
637int PollFd(int fd, int timeout_ms) {
638 pollfd p = {fd, POLLIN, 0};
639 return poll(&p, 1, timeout_ms);
640}
641
642} // namespace
643
644TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700645 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700646 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
647 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700648 std::unique_ptr<ConsumerBuffer> c =
649 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700650 ASSERT_TRUE(c.get() != nullptr);
651
652 DvrNativeBufferMetadata meta;
653 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
654
655 // Post with unsignaled fence.
656 EXPECT_EQ(0, p->PostAsync(&meta, f1));
657
658 // Should acquire a valid fence.
659 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800660 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700661 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
662 EXPECT_TRUE(f2.IsValid());
663 // The original fence and acquired fence should have different fd number.
664 EXPECT_NE(f1.Get(), f2.Get());
665 EXPECT_GE(0, PollFd(f2.Get(), 0));
666
667 // Signal the original fence will trigger the new fence.
668 eventfd_write(f1.Get(), 1);
669 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800670 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700671
672 // Release the consumer with an invalid fence.
673 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
674
675 // Should gain an invalid fence.
676 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800677 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700678 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
679 EXPECT_FALSE(f3.IsValid());
680
681 // Post with a signaled fence.
682 EXPECT_EQ(0, p->PostAsync(&meta, f1));
683
684 // Should acquire a valid fence and it's already signalled.
685 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800686 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700687 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
688 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800689 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700690
691 // Release with an unsignalled fence and signal it immediately after release
692 // without producer gainning.
693 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
694 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
695 eventfd_write(f5.Get(), 1);
696
697 // Should gain a valid fence, which is already signaled.
698 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800699 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700700 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
701 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800702 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700703}
704
705TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700706 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700707 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
708 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700709 std::unique_ptr<ConsumerBuffer> c1 =
710 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700711 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700712 const uint64_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700713
714 DvrNativeBufferMetadata meta;
715 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
716
717 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800718 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700719 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
720 // Destroy the consumer now will make it orphaned and the buffer is still
721 // acquired.
722 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800723 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700724
Tianyu1a60bb42018-10-08 14:56:08 -0700725 std::unique_ptr<ConsumerBuffer> c2 =
726 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700727 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700728 const uint64_t client_state_mask2 = c2->client_state_mask();
729 EXPECT_NE(client_state_mask1, client_state_mask2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700730
731 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800732 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700733 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
734 // Releasing the consumer makes the buffer gainable.
735 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
736
737 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800738 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700739
740 // But if another consumer is created in released state.
Tianyu1a60bb42018-10-08 14:56:08 -0700741 std::unique_ptr<ConsumerBuffer> c3 =
742 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700743 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700744 const uint64_t client_state_mask3 = c3->client_state_mask();
745 EXPECT_NE(client_state_mask2, client_state_mask3);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700746 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800747 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700748 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
749
750 // Producer should be able to gain no matter what.
751 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
752}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700753
754TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700755 // TODO(b/112338294) rewrite test after migration
756 return;
757
Tianyu1a60bb42018-10-08 14:56:08 -0700758 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700759 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700760 std::unique_ptr<ConsumerBuffer> c =
761 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700762 ASSERT_TRUE(p.get() != nullptr);
763 ASSERT_TRUE(c.get() != nullptr);
764
765 DvrNativeBufferMetadata metadata;
766 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700767 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700768
769 // Detach in posted state should fail.
770 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
771 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
772 auto s1 = p->Detach();
773 EXPECT_FALSE(s1);
774
775 // Detach in acquired state should fail.
776 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
777 s1 = p->Detach();
778 EXPECT_FALSE(s1);
779
780 // Detach in released state should fail.
781 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
782 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
783 s1 = p->Detach();
784 EXPECT_FALSE(s1);
785
786 // Detach in gained state should succeed.
787 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
788 s1 = p->Detach();
789 EXPECT_TRUE(s1);
790
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700791 LocalChannelHandle handle = s1.take();
792 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700793
794 // Both producer and consumer should have hangup.
795 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
796 auto s2 = p->GetEventMask(POLLHUP);
797 EXPECT_TRUE(s2);
798 EXPECT_EQ(s2.get(), POLLHUP);
799
800 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
801 s2 = p->GetEventMask(POLLHUP);
802 EXPECT_TRUE(s2);
803 EXPECT_EQ(s2.get(), POLLHUP);
804
805 auto s3 = p->CreateConsumer();
806 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700807 // Note that here the expected error code is EOPNOTSUPP as the socket towards
808 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700809 EXPECT_EQ(s3.error(), EOPNOTSUPP);
810
811 s3 = c->CreateConsumer();
812 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700813 // Note that here the expected error code is EPIPE returned from
814 // ConsumerChannel::HandleMessage as the socket is still open but the producer
815 // is gone.
816 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700817
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700818 // Detached buffer handle can be use to construct a new BufferHubBuffer
819 // object.
820 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700821 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700822 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700823 EXPECT_TRUE(d->IsValid());
824
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700825 EXPECT_EQ(d->id(), p_id);
826}
827
Tianyub61df912018-10-16 14:55:39 -0700828TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
829 // Buffer Creation will fail: BLOB format requires height to be 1.
830 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
831 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
832 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700833
Tianyub61df912018-10-16 14:55:39 -0700834 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700835 EXPECT_FALSE(b1->IsValid());
836
Tianyub61df912018-10-16 14:55:39 -0700837 // Buffer Creation will fail: user metadata size too large.
838 auto b2 = BufferHubBuffer::Create(
839 kWidth, kHeight, kLayerCount, kFormat, kUsage,
840 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700841
Tianyub61df912018-10-16 14:55:39 -0700842 EXPECT_FALSE(b2->IsConnected());
843 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700844
Tianyub61df912018-10-16 14:55:39 -0700845 // Buffer Creation will fail: user metadata size too large.
846 auto b3 = BufferHubBuffer::Create(
847 kWidth, kHeight, kLayerCount, kFormat, kUsage,
848 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
849 kMetadataHeaderSize);
850
851 EXPECT_FALSE(b3->IsConnected());
852 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700853}
854
Tianyub61df912018-10-16 14:55:39 -0700855TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
856 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
857 kUsage, kUserMetadataSize);
858 EXPECT_TRUE(b1->IsConnected());
859 EXPECT_TRUE(b1->IsValid());
860 EXPECT_NE(b1->id(), 0);
861}
862
863TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700864 // TODO(b/112338294) rewrite test after migration
865 return;
866
Tianyu1a60bb42018-10-08 14:56:08 -0700867 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700868 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
869 ASSERT_TRUE(p1.get() != nullptr);
870 int p1_id = p1->id();
871
872 // Detached the producer.
873 auto status_or_handle = p1->Detach();
874 EXPECT_TRUE(status_or_handle.ok());
875 LocalChannelHandle h1 = status_or_handle.take();
876 EXPECT_TRUE(h1.valid());
877
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700878 // Detached buffer handle can be use to construct a new BufferHubBuffer
879 // object.
880 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700881 EXPECT_FALSE(h1.valid());
882 EXPECT_TRUE(b1->IsValid());
883 int b1_id = b1->id();
884 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700885}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700886
Tianyub61df912018-10-16 14:55:39 -0700887TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
888 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
889 kUsage, kUserMetadataSize);
890 int b1_id = b1->id();
891 EXPECT_TRUE(b1->IsValid());
892 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700893 EXPECT_NE(b1->client_state_mask(), 0ULL);
Tianyub61df912018-10-16 14:55:39 -0700894
895 auto status_or_handle = b1->Duplicate();
896 EXPECT_TRUE(status_or_handle);
897
898 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700899 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700900 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700901
Tianyub61df912018-10-16 14:55:39 -0700902 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700903 LocalChannelHandle h2 = status_or_handle.take();
904 EXPECT_TRUE(h2.valid());
905
Tianyub61df912018-10-16 14:55:39 -0700906 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700907 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700908 ASSERT_TRUE(b2 != nullptr);
909 EXPECT_TRUE(b2->IsValid());
910 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700911 EXPECT_NE(b2->client_state_mask(), 0ULL);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700912
Tianyub61df912018-10-16 14:55:39 -0700913 int b2_id = b2->id();
914
915 // These two buffer instances are based on the same physical buffer under the
916 // hood, so they should share the same id.
917 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700918 // We use client_state_mask() to tell those two instances apart.
919 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
Tianyub61df912018-10-16 14:55:39 -0700920
921 // Both buffer instances should be in gained state.
922 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
923 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
924
925 // TODO(b/112338294) rewrite test after migration
926 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700927}