blob: b477f1a571298ab879b3a4557685adcfc12e311a [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>
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' Caiff675b72018-10-09 18:08:29 -070022using android::BufferHubBuffer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070023using android::GraphicBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070024using android::sp;
Tianyu1a60bb42018-10-08 14:56:08 -070025using android::dvr::ConsumerBuffer;
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;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -070044const size_t kMaxConsumerCount = 63;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080045const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080046
47using LibBufferHubTest = ::testing::Test;
48
49TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070050 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080051 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
52 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -070053 std::unique_ptr<ConsumerBuffer> c =
54 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080055 ASSERT_TRUE(c.get() != nullptr);
56 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070057 std::unique_ptr<ConsumerBuffer> c2 =
58 ConsumerBuffer::Import(c->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080059 ASSERT_TRUE(c2.get() != nullptr);
60
Corey Tabaka52ea25c2017-09-13 18:02:48 -070061 // Producer state mask is unique, i.e. 1.
62 EXPECT_EQ(p->buffer_state_bit(), kProducerStateBit);
63 // Consumer state mask cannot have producer bit on.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080064 EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070065 // Consumer state mask must be a single, i.e. power of 2.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080066 EXPECT_NE(c->buffer_state_bit(), 0U);
67 EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070068 // Consumer state mask cannot have producer bit on.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080069 EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070070 // Consumer state mask must be a single, i.e. power of 2.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080071 EXPECT_NE(c2->buffer_state_bit(), 0U);
72 EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070073 // Each consumer should have unique bit.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080074 EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070075
76 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080077 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
78 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
79 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070080
Tianyu58a05a22018-10-10 18:41:27 -070081 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070082
83 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080084 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
85 EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
86 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080087
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088 LocalHandle fence;
Tianyu58a05a22018-10-10 18:41:27 -070089 EXPECT_EQ(0, c->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080090 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
91 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080092
Tianyu58a05a22018-10-10 18:41:27 -070093 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080094 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
95 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080096
97 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080098 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080099 EXPECT_EQ(0, c2->Discard());
100
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800101 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800102 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800103 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
104 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
105 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700106}
107
108TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700109 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700110 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
111 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700112 std::unique_ptr<ConsumerBuffer> c =
113 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700114 ASSERT_TRUE(c.get() != nullptr);
115
116 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
117 ASSERT_TRUE(epoll_fd.IsValid());
118
119 epoll_event event;
120 std::array<epoll_event, 64> events;
121
122 auto event_sources = p->GetEventSources();
123 ASSERT_LT(event_sources.size(), events.size());
124
125 for (const auto& event_source : event_sources) {
126 event = {.events = event_source.event_mask | EPOLLET,
127 .data = {.fd = p->event_fd()}};
128 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
129 &event));
130 }
131
132 event_sources = c->GetEventSources();
133 ASSERT_LT(event_sources.size(), events.size());
134
135 for (const auto& event_source : event_sources) {
136 event = {.events = event_source.event_mask | EPOLLET,
137 .data = {.fd = c->event_fd()}};
138 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
139 &event));
140 }
141
142 // No events should be signaled initially.
143 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
144
145 // Post the producer and check for consumer signal.
Tianyu58a05a22018-10-10 18:41:27 -0700146 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800147 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
148 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700149 ASSERT_TRUE(events[0].events & EPOLLIN);
150 ASSERT_EQ(c->event_fd(), events[0].data.fd);
151
152 // Save the event bits to translate later.
153 event = events[0];
154
155 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800156 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
157 kPollTimeoutMs));
158 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));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700164
165 // Translate the events.
166 auto event_status = c->GetEventMask(event.events);
167 ASSERT_TRUE(event_status);
168 ASSERT_TRUE(event_status.get() & EPOLLIN);
169
170 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800171 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
172 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700173}
174
175TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700176 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700177 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
178 ASSERT_TRUE(p.get() != nullptr);
179
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700180 // It's ok to create up to kMaxConsumerCount consumer buffers.
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700181 uint64_t buffer_state_bits = p->buffer_state_bit();
Tianyu1a60bb42018-10-08 14:56:08 -0700182 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700183 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700184 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700185 ASSERT_TRUE(cs[i].get() != nullptr);
186 // Expect all buffers have unique state mask.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800187 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700188 buffer_state_bits |= cs[i]->buffer_state_bit();
189 }
190 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
191
192 // The 64th creation will fail with out-of-memory error.
193 auto state = p->CreateConsumer();
194 EXPECT_EQ(state.error(), E2BIG);
195
196 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700197 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700198 buffer_state_bits &= ~cs[i]->buffer_state_bit();
199 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700200 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700201 ASSERT_TRUE(cs[i].get() != nullptr);
202 // The released state mask will be reused.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800203 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700204 buffer_state_bits |= cs[i]->buffer_state_bit();
205 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
206 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800207}
208
Corey Tabakad53870c2017-07-06 18:04:27 -0700209TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700210 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700211 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
212 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700213 std::unique_ptr<ConsumerBuffer> c =
214 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700215 ASSERT_TRUE(c.get() != nullptr);
216
217 uint64_t context;
218 LocalHandle fence;
219
220 // The producer buffer starts in gained state.
221
222 // Acquire, release, and gain in gained state should fail.
223 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
224 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
225 EXPECT_EQ(-EALREADY, p->Gain(&fence));
226
227 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700228 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700229
230 // Post, release, and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700231 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700232 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
233 EXPECT_EQ(-EBUSY, p->Gain(&fence));
234
235 // Acquire in posted state should succeed.
236 EXPECT_LE(0, c->Acquire(&fence, &context));
237
238 // Acquire, post, and gain in acquired state should fail.
239 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
Tianyu58a05a22018-10-10 18:41:27 -0700240 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700241 EXPECT_EQ(-EBUSY, p->Gain(&fence));
242
243 // Release in acquired state should succeed.
244 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800245 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700246
247 // Release, acquire, and post in released state should fail.
248 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
249 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
Tianyu58a05a22018-10-10 18:41:27 -0700250 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700251
252 // Gain in released state should succeed.
253 EXPECT_EQ(0, p->Gain(&fence));
254
255 // Acquire, release, and gain in gained state should fail.
256 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
257 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
258 EXPECT_EQ(-EALREADY, p->Gain(&fence));
259}
260
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700261TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700262 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700263 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
264 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700265 std::unique_ptr<ConsumerBuffer> c =
266 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700267 ASSERT_TRUE(c.get() != nullptr);
268
269 DvrNativeBufferMetadata metadata;
270 LocalHandle invalid_fence;
271
272 // The producer buffer starts in gained state.
273
274 // Acquire, release, and gain in gained state should fail.
275 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
276 EXPECT_FALSE(invalid_fence.IsValid());
277 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
278 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
279 EXPECT_FALSE(invalid_fence.IsValid());
280
281 // Post in gained state should succeed.
282 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
283 EXPECT_EQ(p->buffer_state(), c->buffer_state());
284 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
285
286 // Post, release, and gain in posted state should fail.
287 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
288 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
289 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
290 EXPECT_FALSE(invalid_fence.IsValid());
291
292 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800293 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700294 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
295 EXPECT_FALSE(invalid_fence.IsValid());
296 EXPECT_EQ(p->buffer_state(), c->buffer_state());
297 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
298
299 // Acquire, post, and gain in acquired state should fail.
300 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
301 EXPECT_FALSE(invalid_fence.IsValid());
302 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
303 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
304 EXPECT_FALSE(invalid_fence.IsValid());
305
306 // Release in acquired state should succeed.
307 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800308 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700309 EXPECT_EQ(p->buffer_state(), c->buffer_state());
310 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
311
312 // Release, acquire, and post in released state should fail.
313 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
314 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
315 EXPECT_FALSE(invalid_fence.IsValid());
316 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
317
318 // Gain in released state should succeed.
319 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
320 EXPECT_FALSE(invalid_fence.IsValid());
321 EXPECT_EQ(p->buffer_state(), c->buffer_state());
322 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
323
324 // Acquire, release, and gain in gained state should fail.
325 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
326 EXPECT_FALSE(invalid_fence.IsValid());
327 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
328 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
329 EXPECT_FALSE(invalid_fence.IsValid());
330}
331
332TEST_F(LibBufferHubTest, TestZeroConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700333 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700334 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
335 ASSERT_TRUE(p.get() != nullptr);
336
337 DvrNativeBufferMetadata metadata;
338 LocalHandle invalid_fence;
339
340 // Newly created.
341 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
342 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
343 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
344
345 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800346 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700347
348 // A new consumer should still be able to acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700349 std::unique_ptr<ConsumerBuffer> c =
350 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700351 ASSERT_TRUE(c.get() != nullptr);
352 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
353 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
354}
355
356TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700357 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700358 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
359 ASSERT_TRUE(p.get() != nullptr);
360
Tianyu1a60bb42018-10-08 14:56:08 -0700361 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700362 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700363 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700364 ASSERT_TRUE(cs[i].get() != nullptr);
365 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
366 }
367
368 DvrNativeBufferMetadata metadata;
369 LocalHandle invalid_fence;
370
371 // Post the producer should trigger all consumers to be available.
372 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
373 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
374 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700375 EXPECT_TRUE(
376 IsBufferPosted(cs[i]->buffer_state(), cs[i]->buffer_state_bit()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800377 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700378 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
379 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
380 }
381
382 // All consumers have to release before the buffer is considered to be
383 // released.
384 for (size_t i = 0; i < kMaxConsumerCount; i++) {
385 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
386 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
387 }
388
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800389 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700390 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
391
392 // Buffer state cross all clients must be consistent.
393 for (size_t i = 0; i < kMaxConsumerCount; i++) {
394 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
395 }
396}
397
398TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700399 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700400 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
401 ASSERT_TRUE(p.get() != nullptr);
402 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
403
Tianyu1a60bb42018-10-08 14:56:08 -0700404 std::unique_ptr<ConsumerBuffer> c =
405 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700406 ASSERT_TRUE(c.get() != nullptr);
407 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
408
409 DvrNativeBufferMetadata metadata;
410 LocalHandle invalid_fence;
411
412 // Post the gained buffer should signal already created consumer.
413 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
414 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800415 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700416 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
417 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
418}
419
420TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
Tianyu1a60bb42018-10-08 14:56:08 -0700421 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700422 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
423 ASSERT_TRUE(p.get() != nullptr);
424 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
425
426 DvrNativeBufferMetadata metadata;
427 LocalHandle invalid_fence;
428
429 // Post the gained buffer before any consumer gets created.
430 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
431 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
432
433 // Newly created consumer should be automatically sigalled.
Tianyu1a60bb42018-10-08 14:56:08 -0700434 std::unique_ptr<ConsumerBuffer> c =
435 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700436 ASSERT_TRUE(c.get() != nullptr);
437 EXPECT_TRUE(IsBufferPosted(c->buffer_state()));
438 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
439 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
440}
441
442TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700443 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700444 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
445 ASSERT_TRUE(p.get() != nullptr);
446
Tianyu1a60bb42018-10-08 14:56:08 -0700447 std::unique_ptr<ConsumerBuffer> c1 =
448 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700449 ASSERT_TRUE(c1.get() != nullptr);
450
451 DvrNativeBufferMetadata metadata;
452 LocalHandle invalid_fence;
453
454 // Post, acquire, and release the buffer..
455 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800456 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700457 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
458 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
459
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800460 // Note that the next PDX call is on the producer channel, which may be
461 // executed before Release impulse gets executed by bufferhubd. Thus, here we
462 // need to wait until the releasd is confirmed before creating another
463 // consumer.
464 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
465 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
466
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700467 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800468 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700469 std::unique_ptr<ConsumerBuffer> c2 =
470 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700471 ASSERT_TRUE(c2.get() != nullptr);
472
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700473 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
474 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
475 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
476}
477
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800478TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
479 struct Metadata {
480 int64_t field1;
481 int64_t field2;
482 };
Tianyu1a60bb42018-10-08 14:56:08 -0700483 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800484 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
485 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700486 std::unique_ptr<ConsumerBuffer> c =
487 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800488 ASSERT_TRUE(c.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800489 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700490 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800491 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800492 LocalHandle fence;
493 Metadata m2 = {};
494 EXPECT_EQ(0, c->Acquire(&fence, &m2));
495 EXPECT_EQ(m.field1, m2.field1);
496 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800497 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800498 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800499}
500
501TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
502 struct Metadata {
503 int64_t field1;
504 int64_t field2;
505 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700506 struct OverSizedMetadata {
507 int64_t field1;
508 int64_t field2;
509 int64_t field3;
510 };
Tianyu1a60bb42018-10-08 14:56:08 -0700511 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800512 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
513 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700514 std::unique_ptr<ConsumerBuffer> c =
515 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800516 ASSERT_TRUE(c.get() != nullptr);
517
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700518 // It is illegal to post metadata larger than originally requested during
519 // buffer allocation.
520 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700521 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800522 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700523
524 // It is ok to post metadata smaller than originally requested during
525 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700526 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800527}
528
529TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
530 struct Metadata {
531 int64_t field1;
532 int64_t field2;
533 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700534 struct OverSizedMetadata {
535 int64_t field1;
536 int64_t field2;
537 int64_t field3;
538 };
Tianyu1a60bb42018-10-08 14:56:08 -0700539 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800540 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
541 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700542 std::unique_ptr<ConsumerBuffer> c =
543 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800544 ASSERT_TRUE(c.get() != nullptr);
545
546 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700547 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800548
549 LocalHandle fence;
550 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700551 OverSizedMetadata e;
552
553 // It is illegal to acquire metadata larger than originally requested during
554 // buffer allocation.
555 EXPECT_NE(0, c->Acquire(&fence, &e));
556
557 // It is ok to acquire metadata smaller than originally requested during
558 // buffer allocation.
559 EXPECT_EQ(0, c->Acquire(&fence, &sequence));
560 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800561}
562
563TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700564 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800565 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
566 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700567 std::unique_ptr<ConsumerBuffer> c =
568 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569 ASSERT_TRUE(c.get() != nullptr);
570
571 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700572 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800573
574 LocalHandle fence;
575 EXPECT_EQ(0, c->Acquire(&fence));
576}
577
578TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700579 std::unique_ptr<ProducerBuffer> p =
580 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800581 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700582 std::unique_ptr<ConsumerBuffer> c =
583 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800584 ASSERT_TRUE(c.get() != nullptr);
585
586 LocalHandle fence;
587
Tianyue6e08ab2018-09-13 18:48:55 -0700588 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800589 EXPECT_EQ(0, c->Acquire(&fence));
590}
591
592TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700593 std::unique_ptr<ProducerBuffer> p =
594 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800595 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700596 std::unique_ptr<ConsumerBuffer> c =
597 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800598 ASSERT_TRUE(c.get() != nullptr);
599
600 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700601 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800602}
603
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700604namespace {
605
606int PollFd(int fd, int timeout_ms) {
607 pollfd p = {fd, POLLIN, 0};
608 return poll(&p, 1, timeout_ms);
609}
610
611} // namespace
612
613TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700614 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700615 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
616 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700617 std::unique_ptr<ConsumerBuffer> c =
618 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700619 ASSERT_TRUE(c.get() != nullptr);
620
621 DvrNativeBufferMetadata meta;
622 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
623
624 // Post with unsignaled fence.
625 EXPECT_EQ(0, p->PostAsync(&meta, f1));
626
627 // Should acquire a valid fence.
628 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800629 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700630 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
631 EXPECT_TRUE(f2.IsValid());
632 // The original fence and acquired fence should have different fd number.
633 EXPECT_NE(f1.Get(), f2.Get());
634 EXPECT_GE(0, PollFd(f2.Get(), 0));
635
636 // Signal the original fence will trigger the new fence.
637 eventfd_write(f1.Get(), 1);
638 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800639 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700640
641 // Release the consumer with an invalid fence.
642 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
643
644 // Should gain an invalid fence.
645 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800646 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700647 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
648 EXPECT_FALSE(f3.IsValid());
649
650 // Post with a signaled fence.
651 EXPECT_EQ(0, p->PostAsync(&meta, f1));
652
653 // Should acquire a valid fence and it's already signalled.
654 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800655 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700656 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
657 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800658 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700659
660 // Release with an unsignalled fence and signal it immediately after release
661 // without producer gainning.
662 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
663 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
664 eventfd_write(f5.Get(), 1);
665
666 // Should gain a valid fence, which is already signaled.
667 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800668 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700669 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
670 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800671 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700672}
673
674TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700675 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700676 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
677 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700678 std::unique_ptr<ConsumerBuffer> c1 =
679 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700680 ASSERT_TRUE(c1.get() != nullptr);
681 const uint64_t consumer_state_bit1 = c1->buffer_state_bit();
682
683 DvrNativeBufferMetadata meta;
684 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
685
686 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800687 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700688 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
689 // Destroy the consumer now will make it orphaned and the buffer is still
690 // acquired.
691 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800692 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700693
Tianyu1a60bb42018-10-08 14:56:08 -0700694 std::unique_ptr<ConsumerBuffer> c2 =
695 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700696 ASSERT_TRUE(c2.get() != nullptr);
697 const uint64_t consumer_state_bit2 = c2->buffer_state_bit();
698 EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
699
700 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800701 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700702 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
703 // Releasing the consumer makes the buffer gainable.
704 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
705
706 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800707 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700708
709 // But if another consumer is created in released state.
Tianyu1a60bb42018-10-08 14:56:08 -0700710 std::unique_ptr<ConsumerBuffer> c3 =
711 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700712 ASSERT_TRUE(c3.get() != nullptr);
713 const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
714 EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
715 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800716 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700717 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
718
719 // Producer should be able to gain no matter what.
720 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
721}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700722
723TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700724 // TODO(b/112338294) rewrite test after migration
725 return;
726
Tianyu1a60bb42018-10-08 14:56:08 -0700727 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700728 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700729 std::unique_ptr<ConsumerBuffer> c =
730 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700731 ASSERT_TRUE(p.get() != nullptr);
732 ASSERT_TRUE(c.get() != nullptr);
733
734 DvrNativeBufferMetadata metadata;
735 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700736 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700737
738 // Detach in posted state should fail.
739 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
740 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
741 auto s1 = p->Detach();
742 EXPECT_FALSE(s1);
743
744 // Detach in acquired state should fail.
745 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
746 s1 = p->Detach();
747 EXPECT_FALSE(s1);
748
749 // Detach in released state should fail.
750 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
751 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
752 s1 = p->Detach();
753 EXPECT_FALSE(s1);
754
755 // Detach in gained state should succeed.
756 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
757 s1 = p->Detach();
758 EXPECT_TRUE(s1);
759
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700760 LocalChannelHandle handle = s1.take();
761 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700762
763 // Both producer and consumer should have hangup.
764 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
765 auto s2 = p->GetEventMask(POLLHUP);
766 EXPECT_TRUE(s2);
767 EXPECT_EQ(s2.get(), POLLHUP);
768
769 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
770 s2 = p->GetEventMask(POLLHUP);
771 EXPECT_TRUE(s2);
772 EXPECT_EQ(s2.get(), POLLHUP);
773
774 auto s3 = p->CreateConsumer();
775 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700776 // Note that here the expected error code is EOPNOTSUPP as the socket towards
777 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700778 EXPECT_EQ(s3.error(), EOPNOTSUPP);
779
780 s3 = c->CreateConsumer();
781 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700782 // Note that here the expected error code is EPIPE returned from
783 // ConsumerChannel::HandleMessage as the socket is still open but the producer
784 // is gone.
785 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700786
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700787 // Detached buffer handle can be use to construct a new BufferHubBuffer
788 // object.
789 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700790 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700791 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700792 EXPECT_TRUE(d->IsValid());
793
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700794 EXPECT_EQ(d->id(), p_id);
795}
796
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700797TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700798 // Buffer Creation will fail: BLOB format requires height to be 1.
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700799 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
800 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
801 kUserMetadataSize);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700802
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700803 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700804 EXPECT_FALSE(b1->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700805
806 // Buffer Creation will fail: user metadata size too large.
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700807 auto b2 = BufferHubBuffer::Create(
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700808 kWidth, kHeight, kLayerCount, kFormat, kUsage,
809 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
810
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700811 EXPECT_FALSE(b2->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700812 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700813
814 // Buffer Creation will fail: user metadata size too large.
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700815 auto b3 = BufferHubBuffer::Create(
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700816 kWidth, kHeight, kLayerCount, kFormat, kUsage,
817 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
818 kMetadataHeaderSize);
819
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700820 EXPECT_FALSE(b3->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700821 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700822}
823
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700824TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
825 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
826 kUsage, kUserMetadataSize);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700827 EXPECT_TRUE(b1->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700828 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700829 EXPECT_NE(b1->id(), 0);
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700830}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700831
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700832TEST_F(LibBufferHubTest, TestPromoteBufferHubBuffer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700833 // TODO(b/112338294) rewrite test after migration
834 return;
835
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700836 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
837 kUsage, kUserMetadataSize);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700838 int b1_id = b1->id();
839 EXPECT_TRUE(b1->IsValid());
840
841 auto status_or_handle = b1->Promote();
842 EXPECT_TRUE(status_or_handle);
843
844 // The detached buffer should have hangup.
845 EXPECT_GT(RETRY_EINTR(b1->Poll(kPollTimeoutMs)), 0);
846 auto status_or_int = b1->GetEventMask(POLLHUP);
847 EXPECT_TRUE(status_or_int.ok());
848 EXPECT_EQ(status_or_int.get(), POLLHUP);
849
850 // The buffer client is still considered as connected but invalid.
851 EXPECT_TRUE(b1->IsConnected());
852 EXPECT_FALSE(b1->IsValid());
853
854 // Gets the channel handle for the producer.
855 LocalChannelHandle h1 = status_or_handle.take();
856 EXPECT_TRUE(h1.valid());
857
Tianyu1a60bb42018-10-08 14:56:08 -0700858 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700859 EXPECT_FALSE(h1.valid());
860 ASSERT_TRUE(p1 != nullptr);
861 int p1_id = p1->id();
862
863 // A newly promoted ProducerBuffer should inherit the same buffer id.
864 EXPECT_EQ(b1_id, p1_id);
865 EXPECT_TRUE(IsBufferGained(p1->buffer_state()));
866}
867
868TEST_F(LibBufferHubTest, TestDetachThenPromote) {
Fan Xuddb90db2018-10-03 10:09:14 -0700869 // TODO(b/112338294) rewrite test after migration
870 return;
871
Tianyu1a60bb42018-10-08 14:56:08 -0700872 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700873 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
874 ASSERT_TRUE(p1.get() != nullptr);
875 int p1_id = p1->id();
876
877 // Detached the producer.
878 auto status_or_handle = p1->Detach();
879 EXPECT_TRUE(status_or_handle.ok());
880 LocalChannelHandle h1 = status_or_handle.take();
881 EXPECT_TRUE(h1.valid());
882
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700883 // Detached buffer handle can be use to construct a new BufferHubBuffer
884 // object.
885 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700886 EXPECT_FALSE(h1.valid());
887 EXPECT_TRUE(b1->IsValid());
888 int b1_id = b1->id();
889 EXPECT_EQ(b1_id, p1_id);
890
891 // Promote the detached buffer.
892 status_or_handle = b1->Promote();
893 // The buffer client is still considered as connected but invalid.
894 EXPECT_TRUE(b1->IsConnected());
895 EXPECT_FALSE(b1->IsValid());
896 EXPECT_TRUE(status_or_handle.ok());
897
898 // Gets the channel handle for the producer.
899 LocalChannelHandle h2 = status_or_handle.take();
900 EXPECT_TRUE(h2.valid());
901
Tianyu1a60bb42018-10-08 14:56:08 -0700902 std::unique_ptr<ProducerBuffer> p2 = ProducerBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700903 EXPECT_FALSE(h2.valid());
904 ASSERT_TRUE(p2 != nullptr);
905 int p2_id = p2->id();
906
907 // A newly promoted ProducerBuffer should inherit the same buffer id.
908 EXPECT_EQ(b1_id, p2_id);
909 EXPECT_TRUE(IsBufferGained(p2->buffer_state()));
910}
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700911
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700912TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
913 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
914 kUsage, kUserMetadataSize);
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700915 int b1_id = b1->id();
916 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700917 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700918
919 auto status_or_handle = b1->Duplicate();
920 EXPECT_TRUE(status_or_handle);
921
922 // The detached buffer should still be valid.
923 EXPECT_TRUE(b1->IsConnected());
924 EXPECT_TRUE(b1->IsValid());
925
926 // Gets the channel handle for the duplicated buffer.
927 LocalChannelHandle h2 = status_or_handle.take();
928 EXPECT_TRUE(h2.valid());
929
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700930 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700931 EXPECT_FALSE(h2.valid());
932 ASSERT_TRUE(b2 != nullptr);
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700933 EXPECT_TRUE(b2->IsValid());
934 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
935
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700936 int b2_id = b2->id();
937
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700938 // These two buffer instances are based on the same physical buffer under the
939 // hood, so they should share the same id.
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700940 EXPECT_EQ(b1_id, b2_id);
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700941 // We use buffer_state_bit() to tell those two instances apart.
942 EXPECT_NE(b1->buffer_state_bit(), b2->buffer_state_bit());
943 EXPECT_NE(b1->buffer_state_bit(), 0ULL);
944 EXPECT_NE(b2->buffer_state_bit(), 0ULL);
945 EXPECT_NE(b1->buffer_state_bit(), kProducerStateBit);
946 EXPECT_NE(b2->buffer_state_bit(), kProducerStateBit);
947
948 // Both buffer instances should be in gained state.
949 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
950 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700951
Fan Xuddb90db2018-10-03 10:09:14 -0700952 // TODO(b/112338294) rewrite test after migration
953 return;
954
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700955 // Promote the detached buffer should fail as b1 is no longer the exclusive
956 // owner of the buffer..
957 status_or_handle = b1->Promote();
958 EXPECT_FALSE(status_or_handle.ok());
959 EXPECT_EQ(status_or_handle.error(), EINVAL);
960}