blob: cf4a0e9b4785605ff6b83522b3592bfe780873bb [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>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -07005#include <private/dvr/detached_buffer.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07006#include <sys/epoll.h>
7#include <sys/eventfd.h>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -07008#include <ui/DetachedBufferHandle.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08009
10#include <mutex>
11#include <thread>
12
Alex Vakulenko4fe60582017-02-02 11:35:59 -080013#define RETRY_EINTR(fnc_call) \
14 ([&]() -> decltype(fnc_call) { \
15 decltype(fnc_call) result; \
16 do { \
17 result = (fnc_call); \
18 } while (result == -1 && errno == EINTR); \
19 return result; \
20 })()
21
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;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070025using android::dvr::DetachedBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070026using android::dvr::ProducerBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070027using android::dvr::BufferHubDefs::IsBufferAcquired;
28using android::dvr::BufferHubDefs::IsBufferGained;
29using android::dvr::BufferHubDefs::IsBufferPosted;
30using android::dvr::BufferHubDefs::IsBufferReleased;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070031using android::dvr::BufferHubDefs::kConsumerStateMask;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070032using android::dvr::BufferHubDefs::kMetadataHeaderSize;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070033using android::dvr::BufferHubDefs::kProducerStateBit;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070034using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070036using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080037
38const int kWidth = 640;
39const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070040const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080041const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
42const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070043const size_t kUserMetadataSize = 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080044const uint64_t kContext = 42;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -070045const size_t kMaxConsumerCount = 63;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080046const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080047
48using LibBufferHubTest = ::testing::Test;
49
50TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070051 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
53 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -070054 std::unique_ptr<ConsumerBuffer> c =
55 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080056 ASSERT_TRUE(c.get() != nullptr);
57 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070058 std::unique_ptr<ConsumerBuffer> c2 =
59 ConsumerBuffer::Import(c->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080060 ASSERT_TRUE(c2.get() != nullptr);
61
Corey Tabaka52ea25c2017-09-13 18:02:48 -070062 // Producer state mask is unique, i.e. 1.
63 EXPECT_EQ(p->buffer_state_bit(), kProducerStateBit);
64 // Consumer state mask cannot have producer bit on.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080065 EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070066 // Consumer state mask must be a single, i.e. power of 2.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080067 EXPECT_NE(c->buffer_state_bit(), 0U);
68 EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070069 // Consumer state mask cannot have producer bit on.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080070 EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070071 // Consumer state mask must be a single, i.e. power of 2.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080072 EXPECT_NE(c2->buffer_state_bit(), 0U);
73 EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070074 // Each consumer should have unique bit.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080075 EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070076
77 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080078 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
79 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
80 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070081
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080082 EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070083
84 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080085 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
86 EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
87 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088
89 uint64_t context;
90 LocalHandle fence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070091 EXPECT_EQ(0, c->Acquire(&fence, &context));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080092 EXPECT_EQ(kContext, context);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080093 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
94 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080095
Corey Tabaka52ea25c2017-09-13 18:02:48 -070096 EXPECT_EQ(0, c2->Acquire(&fence, &context));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080097 EXPECT_EQ(kContext, context);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080098 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
99 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800100
101 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800102 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800103 EXPECT_EQ(0, c2->Discard());
104
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800105 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800106 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800107 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
108 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
109 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700110}
111
112TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700113 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700114 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
115 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700116 std::unique_ptr<ConsumerBuffer> c =
117 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700118 ASSERT_TRUE(c.get() != nullptr);
119
120 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
121 ASSERT_TRUE(epoll_fd.IsValid());
122
123 epoll_event event;
124 std::array<epoll_event, 64> events;
125
126 auto event_sources = p->GetEventSources();
127 ASSERT_LT(event_sources.size(), events.size());
128
129 for (const auto& event_source : event_sources) {
130 event = {.events = event_source.event_mask | EPOLLET,
131 .data = {.fd = p->event_fd()}};
132 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
133 &event));
134 }
135
136 event_sources = c->GetEventSources();
137 ASSERT_LT(event_sources.size(), events.size());
138
139 for (const auto& event_source : event_sources) {
140 event = {.events = event_source.event_mask | EPOLLET,
141 .data = {.fd = c->event_fd()}};
142 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
143 &event));
144 }
145
146 // No events should be signaled initially.
147 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
148
149 // Post the producer and check for consumer signal.
150 EXPECT_EQ(0, p->Post({}, kContext));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800151 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
152 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700153 ASSERT_TRUE(events[0].events & EPOLLIN);
154 ASSERT_EQ(c->event_fd(), events[0].data.fd);
155
156 // Save the event bits to translate later.
157 event = events[0];
158
159 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800160 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));
166 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
167 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700168
169 // Translate the events.
170 auto event_status = c->GetEventMask(event.events);
171 ASSERT_TRUE(event_status);
172 ASSERT_TRUE(event_status.get() & EPOLLIN);
173
174 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800175 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
176 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700177}
178
179TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700180 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700181 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
182 ASSERT_TRUE(p.get() != nullptr);
183
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700184 // It's ok to create up to kMaxConsumerCount consumer buffers.
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700185 uint64_t buffer_state_bits = p->buffer_state_bit();
Tianyu1a60bb42018-10-08 14:56:08 -0700186 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700187 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700188 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700189 ASSERT_TRUE(cs[i].get() != nullptr);
190 // Expect all buffers have unique state mask.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800191 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700192 buffer_state_bits |= cs[i]->buffer_state_bit();
193 }
194 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
195
196 // The 64th creation will fail with out-of-memory error.
197 auto state = p->CreateConsumer();
198 EXPECT_EQ(state.error(), E2BIG);
199
200 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700201 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700202 buffer_state_bits &= ~cs[i]->buffer_state_bit();
203 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700204 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700205 ASSERT_TRUE(cs[i].get() != nullptr);
206 // The released state mask will be reused.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800207 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700208 buffer_state_bits |= cs[i]->buffer_state_bit();
209 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
210 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800211}
212
Corey Tabakad53870c2017-07-06 18:04:27 -0700213TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700214 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700215 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
216 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700217 std::unique_ptr<ConsumerBuffer> c =
218 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700219 ASSERT_TRUE(c.get() != nullptr);
220
221 uint64_t context;
222 LocalHandle fence;
223
224 // The producer buffer starts in gained state.
225
226 // Acquire, release, and gain in gained state should fail.
227 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
228 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
229 EXPECT_EQ(-EALREADY, p->Gain(&fence));
230
231 // Post in gained state should succeed.
232 EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
233
234 // Post, release, and gain in posted state should fail.
235 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
236 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
237 EXPECT_EQ(-EBUSY, p->Gain(&fence));
238
239 // Acquire in posted state should succeed.
240 EXPECT_LE(0, c->Acquire(&fence, &context));
241
242 // Acquire, post, and gain in acquired state should fail.
243 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
244 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
245 EXPECT_EQ(-EBUSY, p->Gain(&fence));
246
247 // Release in acquired state should succeed.
248 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800249 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700250
251 // Release, acquire, and post in released state should fail.
252 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
253 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
254 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
255
256 // Gain in released state should succeed.
257 EXPECT_EQ(0, p->Gain(&fence));
258
259 // Acquire, release, and gain in gained state should fail.
260 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
261 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
262 EXPECT_EQ(-EALREADY, p->Gain(&fence));
263}
264
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700266 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700267 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
268 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700269 std::unique_ptr<ConsumerBuffer> c =
270 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700271 ASSERT_TRUE(c.get() != nullptr);
272
273 DvrNativeBufferMetadata metadata;
274 LocalHandle invalid_fence;
275
276 // The producer buffer starts in gained state.
277
278 // Acquire, release, and gain in gained state should fail.
279 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
280 EXPECT_FALSE(invalid_fence.IsValid());
281 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
282 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
283 EXPECT_FALSE(invalid_fence.IsValid());
284
285 // Post in gained state should succeed.
286 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
287 EXPECT_EQ(p->buffer_state(), c->buffer_state());
288 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
289
290 // Post, release, and gain in posted state should fail.
291 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
292 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
293 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
294 EXPECT_FALSE(invalid_fence.IsValid());
295
296 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800297 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700298 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
299 EXPECT_FALSE(invalid_fence.IsValid());
300 EXPECT_EQ(p->buffer_state(), c->buffer_state());
301 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
302
303 // Acquire, post, and gain in acquired state should fail.
304 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
305 EXPECT_FALSE(invalid_fence.IsValid());
306 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
307 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
308 EXPECT_FALSE(invalid_fence.IsValid());
309
310 // Release in acquired state should succeed.
311 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800312 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700313 EXPECT_EQ(p->buffer_state(), c->buffer_state());
314 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
315
316 // Release, acquire, and post in released state should fail.
317 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
318 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
319 EXPECT_FALSE(invalid_fence.IsValid());
320 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
321
322 // Gain in released state should succeed.
323 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
324 EXPECT_FALSE(invalid_fence.IsValid());
325 EXPECT_EQ(p->buffer_state(), c->buffer_state());
326 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
327
328 // Acquire, release, and gain in gained state should fail.
329 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
330 EXPECT_FALSE(invalid_fence.IsValid());
331 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
332 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
333 EXPECT_FALSE(invalid_fence.IsValid());
334}
335
336TEST_F(LibBufferHubTest, TestZeroConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700337 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700338 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
339 ASSERT_TRUE(p.get() != nullptr);
340
341 DvrNativeBufferMetadata metadata;
342 LocalHandle invalid_fence;
343
344 // Newly created.
345 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
346 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
347 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
348
349 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800350 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700351
352 // A new consumer should still be able to acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700353 std::unique_ptr<ConsumerBuffer> c =
354 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700355 ASSERT_TRUE(c.get() != nullptr);
356 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
357 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
358}
359
360TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700361 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700362 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
363 ASSERT_TRUE(p.get() != nullptr);
364
Tianyu1a60bb42018-10-08 14:56:08 -0700365 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700366 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700367 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700368 ASSERT_TRUE(cs[i].get() != nullptr);
369 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
370 }
371
372 DvrNativeBufferMetadata metadata;
373 LocalHandle invalid_fence;
374
375 // Post the producer should trigger all consumers to be available.
376 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
377 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
378 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700379 EXPECT_TRUE(
380 IsBufferPosted(cs[i]->buffer_state(), cs[i]->buffer_state_bit()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800381 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700382 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
383 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
384 }
385
386 // All consumers have to release before the buffer is considered to be
387 // released.
388 for (size_t i = 0; i < kMaxConsumerCount; i++) {
389 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
390 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
391 }
392
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800393 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700394 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
395
396 // Buffer state cross all clients must be consistent.
397 for (size_t i = 0; i < kMaxConsumerCount; i++) {
398 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
399 }
400}
401
402TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700403 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700404 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
405 ASSERT_TRUE(p.get() != nullptr);
406 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
407
Tianyu1a60bb42018-10-08 14:56:08 -0700408 std::unique_ptr<ConsumerBuffer> c =
409 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700410 ASSERT_TRUE(c.get() != nullptr);
411 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
412
413 DvrNativeBufferMetadata metadata;
414 LocalHandle invalid_fence;
415
416 // Post the gained buffer should signal already created consumer.
417 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
418 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800419 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700420 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
421 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
422}
423
424TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
Tianyu1a60bb42018-10-08 14:56:08 -0700425 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700426 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
427 ASSERT_TRUE(p.get() != nullptr);
428 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
429
430 DvrNativeBufferMetadata metadata;
431 LocalHandle invalid_fence;
432
433 // Post the gained buffer before any consumer gets created.
434 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
435 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
436
437 // Newly created consumer should be automatically sigalled.
Tianyu1a60bb42018-10-08 14:56:08 -0700438 std::unique_ptr<ConsumerBuffer> c =
439 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700440 ASSERT_TRUE(c.get() != nullptr);
441 EXPECT_TRUE(IsBufferPosted(c->buffer_state()));
442 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
443 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
444}
445
446TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700447 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700448 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
449 ASSERT_TRUE(p.get() != nullptr);
450
Tianyu1a60bb42018-10-08 14:56:08 -0700451 std::unique_ptr<ConsumerBuffer> c1 =
452 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700453 ASSERT_TRUE(c1.get() != nullptr);
454
455 DvrNativeBufferMetadata metadata;
456 LocalHandle invalid_fence;
457
458 // Post, acquire, and release the buffer..
459 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800460 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700461 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
462 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
463
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800464 // Note that the next PDX call is on the producer channel, which may be
465 // executed before Release impulse gets executed by bufferhubd. Thus, here we
466 // need to wait until the releasd is confirmed before creating another
467 // consumer.
468 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
469 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
470
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700471 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800472 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700473 std::unique_ptr<ConsumerBuffer> c2 =
474 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700475 ASSERT_TRUE(c2.get() != nullptr);
476
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700477 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
478 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
479 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
480}
481
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800482TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
483 struct Metadata {
484 int64_t field1;
485 int64_t field2;
486 };
Tianyu1a60bb42018-10-08 14:56:08 -0700487 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800488 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
489 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700490 std::unique_ptr<ConsumerBuffer> c =
491 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800492 ASSERT_TRUE(c.get() != nullptr);
493
494 Metadata m = {1, 3};
495 EXPECT_EQ(0, p->Post(LocalHandle(), m));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800496 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800497
498 LocalHandle fence;
499 Metadata m2 = {};
500 EXPECT_EQ(0, c->Acquire(&fence, &m2));
501 EXPECT_EQ(m.field1, m2.field1);
502 EXPECT_EQ(m.field2, m2.field2);
503
504 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800505 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800506}
507
508TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
509 struct Metadata {
510 int64_t field1;
511 int64_t field2;
512 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700513 struct OverSizedMetadata {
514 int64_t field1;
515 int64_t field2;
516 int64_t field3;
517 };
Tianyu1a60bb42018-10-08 14:56:08 -0700518 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
520 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700521 std::unique_ptr<ConsumerBuffer> c =
522 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800523 ASSERT_TRUE(c.get() != nullptr);
524
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700525 // It is illegal to post metadata larger than originally requested during
526 // buffer allocation.
527 OverSizedMetadata evil_meta = {};
528 EXPECT_NE(0, p->Post(LocalHandle(), evil_meta));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800529 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700530
531 // It is ok to post metadata smaller than originally requested during
532 // buffer allocation.
533 int64_t sequence = 42;
534 EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800535}
536
537TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
538 struct Metadata {
539 int64_t field1;
540 int64_t field2;
541 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700542 struct OverSizedMetadata {
543 int64_t field1;
544 int64_t field2;
545 int64_t field3;
546 };
Tianyu1a60bb42018-10-08 14:56:08 -0700547 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800548 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
549 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700550 std::unique_ptr<ConsumerBuffer> c =
551 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800552 ASSERT_TRUE(c.get() != nullptr);
553
554 Metadata m = {1, 3};
555 EXPECT_EQ(0, p->Post(LocalHandle(), m));
556
557 LocalHandle fence;
558 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700559 OverSizedMetadata e;
560
561 // It is illegal to acquire metadata larger than originally requested during
562 // buffer allocation.
563 EXPECT_NE(0, c->Acquire(&fence, &e));
564
565 // It is ok to acquire metadata smaller than originally requested during
566 // buffer allocation.
567 EXPECT_EQ(0, c->Acquire(&fence, &sequence));
568 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569}
570
571TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700572 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800573 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
574 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700575 std::unique_ptr<ConsumerBuffer> c =
576 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800577 ASSERT_TRUE(c.get() != nullptr);
578
579 int64_t sequence = 3;
580 EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
581
582 LocalHandle fence;
583 EXPECT_EQ(0, c->Acquire(&fence));
584}
585
586TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700587 std::unique_ptr<ProducerBuffer> p =
588 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800589 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700590 std::unique_ptr<ConsumerBuffer> c =
591 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800592 ASSERT_TRUE(c.get() != nullptr);
593
594 LocalHandle fence;
595
Tianyue6e08ab2018-09-13 18:48:55 -0700596 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597 EXPECT_EQ(0, c->Acquire(&fence));
598}
599
600TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700601 std::unique_ptr<ProducerBuffer> p =
602 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800603 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700604 std::unique_ptr<ConsumerBuffer> c =
605 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800606 ASSERT_TRUE(c.get() != nullptr);
607
608 int64_t sequence = 3;
609 EXPECT_NE(0, p->Post(LocalHandle(), sequence));
610}
611
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700612namespace {
613
614int PollFd(int fd, int timeout_ms) {
615 pollfd p = {fd, POLLIN, 0};
616 return poll(&p, 1, timeout_ms);
617}
618
619} // namespace
620
621TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700622 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700623 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
624 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700625 std::unique_ptr<ConsumerBuffer> c =
626 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700627 ASSERT_TRUE(c.get() != nullptr);
628
629 DvrNativeBufferMetadata meta;
630 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
631
632 // Post with unsignaled fence.
633 EXPECT_EQ(0, p->PostAsync(&meta, f1));
634
635 // Should acquire a valid fence.
636 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800637 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700638 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
639 EXPECT_TRUE(f2.IsValid());
640 // The original fence and acquired fence should have different fd number.
641 EXPECT_NE(f1.Get(), f2.Get());
642 EXPECT_GE(0, PollFd(f2.Get(), 0));
643
644 // Signal the original fence will trigger the new fence.
645 eventfd_write(f1.Get(), 1);
646 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800647 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700648
649 // Release the consumer with an invalid fence.
650 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
651
652 // Should gain an invalid fence.
653 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800654 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700655 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
656 EXPECT_FALSE(f3.IsValid());
657
658 // Post with a signaled fence.
659 EXPECT_EQ(0, p->PostAsync(&meta, f1));
660
661 // Should acquire a valid fence and it's already signalled.
662 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800663 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700664 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
665 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800666 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700667
668 // Release with an unsignalled fence and signal it immediately after release
669 // without producer gainning.
670 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
671 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
672 eventfd_write(f5.Get(), 1);
673
674 // Should gain a valid fence, which is already signaled.
675 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800676 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700677 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
678 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800679 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700680}
681
682TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700683 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700684 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
685 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700686 std::unique_ptr<ConsumerBuffer> c1 =
687 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700688 ASSERT_TRUE(c1.get() != nullptr);
689 const uint64_t consumer_state_bit1 = c1->buffer_state_bit();
690
691 DvrNativeBufferMetadata meta;
692 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
693
694 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800695 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700696 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
697 // Destroy the consumer now will make it orphaned and the buffer is still
698 // acquired.
699 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800700 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701
Tianyu1a60bb42018-10-08 14:56:08 -0700702 std::unique_ptr<ConsumerBuffer> c2 =
703 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700704 ASSERT_TRUE(c2.get() != nullptr);
705 const uint64_t consumer_state_bit2 = c2->buffer_state_bit();
706 EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
707
708 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800709 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700710 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
711 // Releasing the consumer makes the buffer gainable.
712 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
713
714 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800715 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716
717 // But if another consumer is created in released state.
Tianyu1a60bb42018-10-08 14:56:08 -0700718 std::unique_ptr<ConsumerBuffer> c3 =
719 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700720 ASSERT_TRUE(c3.get() != nullptr);
721 const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
722 EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
723 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800724 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
726
727 // Producer should be able to gain no matter what.
728 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
729}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700730
731TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700732 // TODO(b/112338294) rewrite test after migration
733 return;
734
Tianyu1a60bb42018-10-08 14:56:08 -0700735 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700736 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700737 std::unique_ptr<ConsumerBuffer> c =
738 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700739 ASSERT_TRUE(p.get() != nullptr);
740 ASSERT_TRUE(c.get() != nullptr);
741
742 DvrNativeBufferMetadata metadata;
743 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700744 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700745
746 // Detach in posted state should fail.
747 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
748 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
749 auto s1 = p->Detach();
750 EXPECT_FALSE(s1);
751
752 // Detach in acquired state should fail.
753 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
754 s1 = p->Detach();
755 EXPECT_FALSE(s1);
756
757 // Detach in released state should fail.
758 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
759 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
760 s1 = p->Detach();
761 EXPECT_FALSE(s1);
762
763 // Detach in gained state should succeed.
764 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
765 s1 = p->Detach();
766 EXPECT_TRUE(s1);
767
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700768 LocalChannelHandle handle = s1.take();
769 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700770
771 // Both producer and consumer should have hangup.
772 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
773 auto s2 = p->GetEventMask(POLLHUP);
774 EXPECT_TRUE(s2);
775 EXPECT_EQ(s2.get(), POLLHUP);
776
777 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
778 s2 = p->GetEventMask(POLLHUP);
779 EXPECT_TRUE(s2);
780 EXPECT_EQ(s2.get(), POLLHUP);
781
782 auto s3 = p->CreateConsumer();
783 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700784 // Note that here the expected error code is EOPNOTSUPP as the socket towards
785 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700786 EXPECT_EQ(s3.error(), EOPNOTSUPP);
787
788 s3 = c->CreateConsumer();
789 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700790 // Note that here the expected error code is EPIPE returned from
791 // ConsumerChannel::HandleMessage as the socket is still open but the producer
792 // is gone.
793 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700794
795 // Detached buffer handle can be use to construct a new DetachedBuffer object.
796 auto d = DetachedBuffer::Import(std::move(handle));
797 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700798 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700799 EXPECT_TRUE(d->IsValid());
800
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700801 EXPECT_EQ(d->id(), p_id);
802}
803
804TEST_F(LibBufferHubTest, TestCreateDetachedBufferFails) {
805 // Buffer Creation will fail: BLOB format requires height to be 1.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700806 auto b1 = DetachedBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700807 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
808 kUserMetadataSize);
809
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700810 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700811 EXPECT_FALSE(b1->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700812
813 // Buffer Creation will fail: user metadata size too large.
814 auto b2 = DetachedBuffer::Create(
815 kWidth, kHeight, kLayerCount, kFormat, kUsage,
816 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
817
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700818 EXPECT_FALSE(b2->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700819 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700820
821 // Buffer Creation will fail: user metadata size too large.
822 auto b3 = DetachedBuffer::Create(
823 kWidth, kHeight, kLayerCount, kFormat, kUsage,
824 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
825 kMetadataHeaderSize);
826
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700827 EXPECT_FALSE(b3->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700828 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700829}
830
831TEST_F(LibBufferHubTest, TestCreateDetachedBuffer) {
832 auto b1 = DetachedBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
833 kUsage, kUserMetadataSize);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700834 EXPECT_TRUE(b1->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700835 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700836 EXPECT_NE(b1->id(), 0);
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700837}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700838
839TEST_F(LibBufferHubTest, TestPromoteDetachedBuffer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700840 // TODO(b/112338294) rewrite test after migration
841 return;
842
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700843 auto b1 = DetachedBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
844 kUsage, kUserMetadataSize);
845 int b1_id = b1->id();
846 EXPECT_TRUE(b1->IsValid());
847
848 auto status_or_handle = b1->Promote();
849 EXPECT_TRUE(status_or_handle);
850
851 // The detached buffer should have hangup.
852 EXPECT_GT(RETRY_EINTR(b1->Poll(kPollTimeoutMs)), 0);
853 auto status_or_int = b1->GetEventMask(POLLHUP);
854 EXPECT_TRUE(status_or_int.ok());
855 EXPECT_EQ(status_or_int.get(), POLLHUP);
856
857 // The buffer client is still considered as connected but invalid.
858 EXPECT_TRUE(b1->IsConnected());
859 EXPECT_FALSE(b1->IsValid());
860
861 // Gets the channel handle for the producer.
862 LocalChannelHandle h1 = status_or_handle.take();
863 EXPECT_TRUE(h1.valid());
864
Tianyu1a60bb42018-10-08 14:56:08 -0700865 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700866 EXPECT_FALSE(h1.valid());
867 ASSERT_TRUE(p1 != nullptr);
868 int p1_id = p1->id();
869
870 // A newly promoted ProducerBuffer should inherit the same buffer id.
871 EXPECT_EQ(b1_id, p1_id);
872 EXPECT_TRUE(IsBufferGained(p1->buffer_state()));
873}
874
875TEST_F(LibBufferHubTest, TestDetachThenPromote) {
Fan Xuddb90db2018-10-03 10:09:14 -0700876 // TODO(b/112338294) rewrite test after migration
877 return;
878
Tianyu1a60bb42018-10-08 14:56:08 -0700879 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700880 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
881 ASSERT_TRUE(p1.get() != nullptr);
882 int p1_id = p1->id();
883
884 // Detached the producer.
885 auto status_or_handle = p1->Detach();
886 EXPECT_TRUE(status_or_handle.ok());
887 LocalChannelHandle h1 = status_or_handle.take();
888 EXPECT_TRUE(h1.valid());
889
890 // Detached buffer handle can be use to construct a new DetachedBuffer object.
891 auto b1 = DetachedBuffer::Import(std::move(h1));
892 EXPECT_FALSE(h1.valid());
893 EXPECT_TRUE(b1->IsValid());
894 int b1_id = b1->id();
895 EXPECT_EQ(b1_id, p1_id);
896
897 // Promote the detached buffer.
898 status_or_handle = b1->Promote();
899 // The buffer client is still considered as connected but invalid.
900 EXPECT_TRUE(b1->IsConnected());
901 EXPECT_FALSE(b1->IsValid());
902 EXPECT_TRUE(status_or_handle.ok());
903
904 // Gets the channel handle for the producer.
905 LocalChannelHandle h2 = status_or_handle.take();
906 EXPECT_TRUE(h2.valid());
907
Tianyu1a60bb42018-10-08 14:56:08 -0700908 std::unique_ptr<ProducerBuffer> p2 = ProducerBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700909 EXPECT_FALSE(h2.valid());
910 ASSERT_TRUE(p2 != nullptr);
911 int p2_id = p2->id();
912
913 // A newly promoted ProducerBuffer should inherit the same buffer id.
914 EXPECT_EQ(b1_id, p2_id);
915 EXPECT_TRUE(IsBufferGained(p2->buffer_state()));
916}
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700917
918TEST_F(LibBufferHubTest, TestDuplicateDetachedBuffer) {
919 auto b1 = DetachedBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
920 kUsage, kUserMetadataSize);
921 int b1_id = b1->id();
922 EXPECT_TRUE(b1->IsValid());
923
924 auto status_or_handle = b1->Duplicate();
925 EXPECT_TRUE(status_or_handle);
926
927 // The detached buffer should still be valid.
928 EXPECT_TRUE(b1->IsConnected());
929 EXPECT_TRUE(b1->IsValid());
930
931 // Gets the channel handle for the duplicated buffer.
932 LocalChannelHandle h2 = status_or_handle.take();
933 EXPECT_TRUE(h2.valid());
934
935 std::unique_ptr<DetachedBuffer> b2 = DetachedBuffer::Import(std::move(h2));
936 EXPECT_FALSE(h2.valid());
937 ASSERT_TRUE(b2 != nullptr);
938 int b2_id = b2->id();
939
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700940 // These two buffer instances are based on the same physical buffer under the
941 // hood, so they should share the same id.
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700942 EXPECT_EQ(b1_id, b2_id);
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700943 // We use buffer_state_bit() to tell those two instances apart.
944 EXPECT_NE(b1->buffer_state_bit(), b2->buffer_state_bit());
945 EXPECT_NE(b1->buffer_state_bit(), 0ULL);
946 EXPECT_NE(b2->buffer_state_bit(), 0ULL);
947 EXPECT_NE(b1->buffer_state_bit(), kProducerStateBit);
948 EXPECT_NE(b2->buffer_state_bit(), kProducerStateBit);
949
950 // Both buffer instances should be in gained state.
951 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
952 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700953
Fan Xuddb90db2018-10-03 10:09:14 -0700954 // TODO(b/112338294) rewrite test after migration
955 return;
956
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700957 // Promote the detached buffer should fail as b1 is no longer the exclusive
958 // owner of the buffer..
959 status_or_handle = b1->Promote();
960 EXPECT_FALSE(status_or_handle.ok());
961 EXPECT_EQ(status_or_handle.error(), EINVAL);
962}