blob: 8351efce40c26b93fdbdd1e190d2ef6512f904e0 [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
Corey Tabakad53870c2017-07-06 18:04:27 -0700217 LocalHandle fence;
218
219 // The producer buffer starts in gained state.
220
221 // Acquire, release, and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700222 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700223 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
224 EXPECT_EQ(-EALREADY, p->Gain(&fence));
225
226 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700227 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700228
229 // Post, release, and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700230 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700231 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
232 EXPECT_EQ(-EBUSY, p->Gain(&fence));
233
234 // Acquire in posted state should succeed.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700235 EXPECT_LE(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700236
237 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700238 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700239 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700240 EXPECT_EQ(-EBUSY, p->Gain(&fence));
241
242 // Release in acquired state should succeed.
243 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800244 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700245
246 // Release, acquire, and post in released state should fail.
247 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
Tianyu Jiangee723f52018-10-24 16:37:38 -0700248 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700249 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700250
251 // Gain in released state should succeed.
252 EXPECT_EQ(0, p->Gain(&fence));
253
254 // Acquire, release, and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700255 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700256 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
257 EXPECT_EQ(-EALREADY, p->Gain(&fence));
258}
259
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700260TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700261 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700262 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
263 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700264 std::unique_ptr<ConsumerBuffer> c =
265 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700266 ASSERT_TRUE(c.get() != nullptr);
267
268 DvrNativeBufferMetadata metadata;
269 LocalHandle invalid_fence;
270
271 // The producer buffer starts in gained state.
272
273 // Acquire, release, and gain in gained state should fail.
274 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
275 EXPECT_FALSE(invalid_fence.IsValid());
276 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
277 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
278 EXPECT_FALSE(invalid_fence.IsValid());
279
280 // Post in gained state should succeed.
281 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
282 EXPECT_EQ(p->buffer_state(), c->buffer_state());
283 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
284
285 // Post, release, and gain in posted state should fail.
286 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
287 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
288 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
289 EXPECT_FALSE(invalid_fence.IsValid());
290
291 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800292 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700293 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
294 EXPECT_FALSE(invalid_fence.IsValid());
295 EXPECT_EQ(p->buffer_state(), c->buffer_state());
296 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
297
298 // Acquire, post, and gain in acquired state should fail.
299 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
300 EXPECT_FALSE(invalid_fence.IsValid());
301 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
302 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
303 EXPECT_FALSE(invalid_fence.IsValid());
304
305 // Release in acquired state should succeed.
306 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800307 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700308 EXPECT_EQ(p->buffer_state(), c->buffer_state());
309 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
310
311 // Release, acquire, and post in released state should fail.
312 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
313 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
314 EXPECT_FALSE(invalid_fence.IsValid());
315 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
316
317 // Gain in released state should succeed.
318 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
319 EXPECT_FALSE(invalid_fence.IsValid());
320 EXPECT_EQ(p->buffer_state(), c->buffer_state());
321 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
322
323 // Acquire, release, and gain in gained state should fail.
324 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
325 EXPECT_FALSE(invalid_fence.IsValid());
326 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
327 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
328 EXPECT_FALSE(invalid_fence.IsValid());
329}
330
Tianyu5465d6c2018-08-14 13:03:10 -0700331TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
332 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
333 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
334 ASSERT_TRUE(p.get() != nullptr);
335
336 // The producer buffer starts in gained state. Post the buffer.
337 ASSERT_EQ(0, p->Post(LocalHandle()));
338
339 // Gain in posted state should only succeed with gain_posted_buffer = true.
340 LocalHandle invalid_fence;
341 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
342 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
343}
344
345TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
346 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
347 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
348 ASSERT_TRUE(p.get() != nullptr);
349
350 // The producer buffer starts in gained state. Post the buffer.
351 ASSERT_EQ(0, p->Post(LocalHandle()));
352
353 // GainAsync in posted state should only succeed with gain_posted_buffer
354 // equals true.
355 DvrNativeBufferMetadata metadata;
356 LocalHandle invalid_fence;
357 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
358 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
359}
360
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700361TEST_F(LibBufferHubTest, TestZeroConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700362 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700363 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
364 ASSERT_TRUE(p.get() != nullptr);
365
366 DvrNativeBufferMetadata metadata;
367 LocalHandle invalid_fence;
368
369 // Newly created.
370 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
371 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
372 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
373
374 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800375 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700376
377 // A new consumer should still be able to acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700378 std::unique_ptr<ConsumerBuffer> c =
379 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700380 ASSERT_TRUE(c.get() != nullptr);
381 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
382 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
383}
384
385TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700386 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700387 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
388 ASSERT_TRUE(p.get() != nullptr);
389
Tianyu1a60bb42018-10-08 14:56:08 -0700390 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700391 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700392 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700393 ASSERT_TRUE(cs[i].get() != nullptr);
394 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
395 }
396
397 DvrNativeBufferMetadata metadata;
398 LocalHandle invalid_fence;
399
400 // Post the producer should trigger all consumers to be available.
401 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
402 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
403 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700404 EXPECT_TRUE(
405 IsBufferPosted(cs[i]->buffer_state(), cs[i]->buffer_state_bit()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800406 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700407 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
408 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
409 }
410
411 // All consumers have to release before the buffer is considered to be
412 // released.
413 for (size_t i = 0; i < kMaxConsumerCount; i++) {
414 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
415 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
416 }
417
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800418 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700419 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
420
421 // Buffer state cross all clients must be consistent.
422 for (size_t i = 0; i < kMaxConsumerCount; i++) {
423 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
424 }
425}
426
427TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700428 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700429 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
430 ASSERT_TRUE(p.get() != nullptr);
431 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
432
Tianyu1a60bb42018-10-08 14:56:08 -0700433 std::unique_ptr<ConsumerBuffer> c =
434 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700435 ASSERT_TRUE(c.get() != nullptr);
436 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
437
438 DvrNativeBufferMetadata metadata;
439 LocalHandle invalid_fence;
440
441 // Post the gained buffer should signal already created consumer.
442 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
443 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800444 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700445 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
446 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
447}
448
449TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
Tianyu1a60bb42018-10-08 14:56:08 -0700450 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700451 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
452 ASSERT_TRUE(p.get() != nullptr);
453 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
454
455 DvrNativeBufferMetadata metadata;
456 LocalHandle invalid_fence;
457
458 // Post the gained buffer before any consumer gets created.
459 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
460 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
461
462 // Newly created consumer should be automatically sigalled.
Tianyu1a60bb42018-10-08 14:56:08 -0700463 std::unique_ptr<ConsumerBuffer> c =
464 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700465 ASSERT_TRUE(c.get() != nullptr);
466 EXPECT_TRUE(IsBufferPosted(c->buffer_state()));
467 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
468 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
469}
470
471TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700472 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700473 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
474 ASSERT_TRUE(p.get() != nullptr);
475
Tianyu1a60bb42018-10-08 14:56:08 -0700476 std::unique_ptr<ConsumerBuffer> c1 =
477 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700478 ASSERT_TRUE(c1.get() != nullptr);
479
480 DvrNativeBufferMetadata metadata;
481 LocalHandle invalid_fence;
482
483 // Post, acquire, and release the buffer..
484 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800485 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700486 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
487 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
488
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800489 // Note that the next PDX call is on the producer channel, which may be
490 // executed before Release impulse gets executed by bufferhubd. Thus, here we
491 // need to wait until the releasd is confirmed before creating another
492 // consumer.
493 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
494 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
495
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700496 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800497 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700498 std::unique_ptr<ConsumerBuffer> c2 =
499 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700500 ASSERT_TRUE(c2.get() != nullptr);
501
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700502 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
503 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
504 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
505}
506
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800507TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
508 struct Metadata {
509 int64_t field1;
510 int64_t field2;
511 };
Tianyu1a60bb42018-10-08 14:56:08 -0700512 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800513 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
514 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700515 std::unique_ptr<ConsumerBuffer> c =
516 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800517 ASSERT_TRUE(c.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800518 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700519 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800520 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800521 LocalHandle fence;
522 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700523 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800524 EXPECT_EQ(m.field1, m2.field1);
525 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800526 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800527 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800528}
529
530TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
531 struct Metadata {
532 int64_t field1;
533 int64_t field2;
534 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700535 struct OverSizedMetadata {
536 int64_t field1;
537 int64_t field2;
538 int64_t field3;
539 };
Tianyu1a60bb42018-10-08 14:56:08 -0700540 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800541 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
542 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700543 std::unique_ptr<ConsumerBuffer> c =
544 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800545 ASSERT_TRUE(c.get() != nullptr);
546
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700547 // It is illegal to post metadata larger than originally requested during
548 // buffer allocation.
549 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700550 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800551 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700552
553 // It is ok to post metadata smaller than originally requested during
554 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700555 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800556}
557
558TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
559 struct Metadata {
560 int64_t field1;
561 int64_t field2;
562 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700563 struct OverSizedMetadata {
564 int64_t field1;
565 int64_t field2;
566 int64_t field3;
567 };
Tianyu1a60bb42018-10-08 14:56:08 -0700568 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
570 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700571 std::unique_ptr<ConsumerBuffer> c =
572 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800573 ASSERT_TRUE(c.get() != nullptr);
574
575 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700576 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800577
578 LocalHandle fence;
579 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700580 OverSizedMetadata e;
581
582 // It is illegal to acquire metadata larger than originally requested during
583 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700584 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700585
586 // It is ok to acquire metadata smaller than originally requested during
587 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700588 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700589 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800590}
591
592TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700593 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800594 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
595 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_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800602
603 LocalHandle fence;
604 EXPECT_EQ(0, c->Acquire(&fence));
605}
606
607TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700608 std::unique_ptr<ProducerBuffer> p =
609 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800610 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700611 std::unique_ptr<ConsumerBuffer> c =
612 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800613 ASSERT_TRUE(c.get() != nullptr);
614
615 LocalHandle fence;
616
Tianyue6e08ab2018-09-13 18:48:55 -0700617 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800618 EXPECT_EQ(0, c->Acquire(&fence));
619}
620
621TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700622 std::unique_ptr<ProducerBuffer> p =
623 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800624 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700625 std::unique_ptr<ConsumerBuffer> c =
626 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800627 ASSERT_TRUE(c.get() != nullptr);
628
629 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700630 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800631}
632
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700633namespace {
634
635int PollFd(int fd, int timeout_ms) {
636 pollfd p = {fd, POLLIN, 0};
637 return poll(&p, 1, timeout_ms);
638}
639
640} // namespace
641
642TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700643 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700644 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
645 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700646 std::unique_ptr<ConsumerBuffer> c =
647 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700648 ASSERT_TRUE(c.get() != nullptr);
649
650 DvrNativeBufferMetadata meta;
651 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
652
653 // Post with unsignaled fence.
654 EXPECT_EQ(0, p->PostAsync(&meta, f1));
655
656 // Should acquire a valid fence.
657 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800658 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700659 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
660 EXPECT_TRUE(f2.IsValid());
661 // The original fence and acquired fence should have different fd number.
662 EXPECT_NE(f1.Get(), f2.Get());
663 EXPECT_GE(0, PollFd(f2.Get(), 0));
664
665 // Signal the original fence will trigger the new fence.
666 eventfd_write(f1.Get(), 1);
667 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800668 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700669
670 // Release the consumer with an invalid fence.
671 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
672
673 // Should gain an invalid fence.
674 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800675 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700676 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
677 EXPECT_FALSE(f3.IsValid());
678
679 // Post with a signaled fence.
680 EXPECT_EQ(0, p->PostAsync(&meta, f1));
681
682 // Should acquire a valid fence and it's already signalled.
683 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800684 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700685 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
686 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800687 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700688
689 // Release with an unsignalled fence and signal it immediately after release
690 // without producer gainning.
691 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
692 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
693 eventfd_write(f5.Get(), 1);
694
695 // Should gain a valid fence, which is already signaled.
696 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800697 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700698 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
699 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800700 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701}
702
703TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700704 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700705 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
706 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700707 std::unique_ptr<ConsumerBuffer> c1 =
708 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700709 ASSERT_TRUE(c1.get() != nullptr);
710 const uint64_t consumer_state_bit1 = c1->buffer_state_bit();
711
712 DvrNativeBufferMetadata meta;
713 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
714
715 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800716 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700717 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
718 // Destroy the consumer now will make it orphaned and the buffer is still
719 // acquired.
720 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800721 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700722
Tianyu1a60bb42018-10-08 14:56:08 -0700723 std::unique_ptr<ConsumerBuffer> c2 =
724 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725 ASSERT_TRUE(c2.get() != nullptr);
726 const uint64_t consumer_state_bit2 = c2->buffer_state_bit();
727 EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
728
729 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800730 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700731 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
732 // Releasing the consumer makes the buffer gainable.
733 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
734
735 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800736 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700737
738 // But if another consumer is created in released state.
Tianyu1a60bb42018-10-08 14:56:08 -0700739 std::unique_ptr<ConsumerBuffer> c3 =
740 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700741 ASSERT_TRUE(c3.get() != nullptr);
742 const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
743 EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
744 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800745 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700746 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
747
748 // Producer should be able to gain no matter what.
749 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
750}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700751
752TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700753 // TODO(b/112338294) rewrite test after migration
754 return;
755
Tianyu1a60bb42018-10-08 14:56:08 -0700756 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700757 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700758 std::unique_ptr<ConsumerBuffer> c =
759 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700760 ASSERT_TRUE(p.get() != nullptr);
761 ASSERT_TRUE(c.get() != nullptr);
762
763 DvrNativeBufferMetadata metadata;
764 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700765 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700766
767 // Detach in posted state should fail.
768 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
769 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
770 auto s1 = p->Detach();
771 EXPECT_FALSE(s1);
772
773 // Detach in acquired state should fail.
774 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
775 s1 = p->Detach();
776 EXPECT_FALSE(s1);
777
778 // Detach in released state should fail.
779 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
780 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
781 s1 = p->Detach();
782 EXPECT_FALSE(s1);
783
784 // Detach in gained state should succeed.
785 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
786 s1 = p->Detach();
787 EXPECT_TRUE(s1);
788
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700789 LocalChannelHandle handle = s1.take();
790 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700791
792 // Both producer and consumer should have hangup.
793 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
794 auto s2 = p->GetEventMask(POLLHUP);
795 EXPECT_TRUE(s2);
796 EXPECT_EQ(s2.get(), POLLHUP);
797
798 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
799 s2 = p->GetEventMask(POLLHUP);
800 EXPECT_TRUE(s2);
801 EXPECT_EQ(s2.get(), POLLHUP);
802
803 auto s3 = p->CreateConsumer();
804 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700805 // Note that here the expected error code is EOPNOTSUPP as the socket towards
806 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700807 EXPECT_EQ(s3.error(), EOPNOTSUPP);
808
809 s3 = c->CreateConsumer();
810 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700811 // Note that here the expected error code is EPIPE returned from
812 // ConsumerChannel::HandleMessage as the socket is still open but the producer
813 // is gone.
814 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700815
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700816 // Detached buffer handle can be use to construct a new BufferHubBuffer
817 // object.
818 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700819 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700820 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700821 EXPECT_TRUE(d->IsValid());
822
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700823 EXPECT_EQ(d->id(), p_id);
824}
825
Tianyub61df912018-10-16 14:55:39 -0700826TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
827 // Buffer Creation will fail: BLOB format requires height to be 1.
828 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
829 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
830 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700831
Tianyub61df912018-10-16 14:55:39 -0700832 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700833 EXPECT_FALSE(b1->IsValid());
834
Tianyub61df912018-10-16 14:55:39 -0700835 // Buffer Creation will fail: user metadata size too large.
836 auto b2 = BufferHubBuffer::Create(
837 kWidth, kHeight, kLayerCount, kFormat, kUsage,
838 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700839
Tianyub61df912018-10-16 14:55:39 -0700840 EXPECT_FALSE(b2->IsConnected());
841 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700842
Tianyub61df912018-10-16 14:55:39 -0700843 // Buffer Creation will fail: user metadata size too large.
844 auto b3 = BufferHubBuffer::Create(
845 kWidth, kHeight, kLayerCount, kFormat, kUsage,
846 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
847 kMetadataHeaderSize);
848
849 EXPECT_FALSE(b3->IsConnected());
850 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700851}
852
Tianyub61df912018-10-16 14:55:39 -0700853TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
854 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
855 kUsage, kUserMetadataSize);
856 EXPECT_TRUE(b1->IsConnected());
857 EXPECT_TRUE(b1->IsValid());
858 EXPECT_NE(b1->id(), 0);
859}
860
861TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700862 // TODO(b/112338294) rewrite test after migration
863 return;
864
Tianyu1a60bb42018-10-08 14:56:08 -0700865 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700866 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
867 ASSERT_TRUE(p1.get() != nullptr);
868 int p1_id = p1->id();
869
870 // Detached the producer.
871 auto status_or_handle = p1->Detach();
872 EXPECT_TRUE(status_or_handle.ok());
873 LocalChannelHandle h1 = status_or_handle.take();
874 EXPECT_TRUE(h1.valid());
875
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700876 // Detached buffer handle can be use to construct a new BufferHubBuffer
877 // object.
878 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700879 EXPECT_FALSE(h1.valid());
880 EXPECT_TRUE(b1->IsValid());
881 int b1_id = b1->id();
882 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700883}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700884
Tianyub61df912018-10-16 14:55:39 -0700885TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
886 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
887 kUsage, kUserMetadataSize);
888 int b1_id = b1->id();
889 EXPECT_TRUE(b1->IsValid());
890 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
891
892 auto status_or_handle = b1->Duplicate();
893 EXPECT_TRUE(status_or_handle);
894
895 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700896 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700897 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700898
Tianyub61df912018-10-16 14:55:39 -0700899 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700900 LocalChannelHandle h2 = status_or_handle.take();
901 EXPECT_TRUE(h2.valid());
902
Tianyub61df912018-10-16 14:55:39 -0700903 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700904 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700905 ASSERT_TRUE(b2 != nullptr);
906 EXPECT_TRUE(b2->IsValid());
907 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700908
Tianyub61df912018-10-16 14:55:39 -0700909 int b2_id = b2->id();
910
911 // These two buffer instances are based on the same physical buffer under the
912 // hood, so they should share the same id.
913 EXPECT_EQ(b1_id, b2_id);
914 // We use buffer_state_bit() to tell those two instances apart.
915 EXPECT_NE(b1->buffer_state_bit(), b2->buffer_state_bit());
916 EXPECT_NE(b1->buffer_state_bit(), 0ULL);
917 EXPECT_NE(b2->buffer_state_bit(), 0ULL);
918 EXPECT_NE(b1->buffer_state_bit(), kProducerStateBit);
919 EXPECT_NE(b2->buffer_state_bit(), kProducerStateBit);
920
921 // Both buffer instances should be in gained state.
922 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
923 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
924
925 // TODO(b/112338294) rewrite test after migration
926 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700927}