blob: 4d98dfc8da8b29cbc92c740c37e8ff7e3f2a6c75 [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
331TEST_F(LibBufferHubTest, TestZeroConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700332 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700333 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
334 ASSERT_TRUE(p.get() != nullptr);
335
336 DvrNativeBufferMetadata metadata;
337 LocalHandle invalid_fence;
338
339 // Newly created.
340 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
341 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
342 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
343
344 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800345 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700346
347 // A new consumer should still be able to acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700348 std::unique_ptr<ConsumerBuffer> c =
349 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700350 ASSERT_TRUE(c.get() != nullptr);
351 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
352 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
353}
354
355TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700356 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700357 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
358 ASSERT_TRUE(p.get() != nullptr);
359
Tianyu1a60bb42018-10-08 14:56:08 -0700360 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700361 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700362 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700363 ASSERT_TRUE(cs[i].get() != nullptr);
364 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
365 }
366
367 DvrNativeBufferMetadata metadata;
368 LocalHandle invalid_fence;
369
370 // Post the producer should trigger all consumers to be available.
371 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
372 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
373 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700374 EXPECT_TRUE(
375 IsBufferPosted(cs[i]->buffer_state(), cs[i]->buffer_state_bit()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800376 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700377 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
378 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
379 }
380
381 // All consumers have to release before the buffer is considered to be
382 // released.
383 for (size_t i = 0; i < kMaxConsumerCount; i++) {
384 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
385 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
386 }
387
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800388 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700389 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
390
391 // Buffer state cross all clients must be consistent.
392 for (size_t i = 0; i < kMaxConsumerCount; i++) {
393 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
394 }
395}
396
397TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700398 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700399 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
400 ASSERT_TRUE(p.get() != nullptr);
401 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
402
Tianyu1a60bb42018-10-08 14:56:08 -0700403 std::unique_ptr<ConsumerBuffer> c =
404 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700405 ASSERT_TRUE(c.get() != nullptr);
406 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
407
408 DvrNativeBufferMetadata metadata;
409 LocalHandle invalid_fence;
410
411 // Post the gained buffer should signal already created consumer.
412 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
413 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800414 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700415 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
416 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
417}
418
419TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
Tianyu1a60bb42018-10-08 14:56:08 -0700420 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700421 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
422 ASSERT_TRUE(p.get() != nullptr);
423 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
424
425 DvrNativeBufferMetadata metadata;
426 LocalHandle invalid_fence;
427
428 // Post the gained buffer before any consumer gets created.
429 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
430 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
431
432 // Newly created consumer should be automatically sigalled.
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(IsBufferPosted(c->buffer_state()));
437 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
438 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
439}
440
441TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700442 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700443 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
444 ASSERT_TRUE(p.get() != nullptr);
445
Tianyu1a60bb42018-10-08 14:56:08 -0700446 std::unique_ptr<ConsumerBuffer> c1 =
447 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700448 ASSERT_TRUE(c1.get() != nullptr);
449
450 DvrNativeBufferMetadata metadata;
451 LocalHandle invalid_fence;
452
453 // Post, acquire, and release the buffer..
454 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800455 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700456 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
457 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
458
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800459 // Note that the next PDX call is on the producer channel, which may be
460 // executed before Release impulse gets executed by bufferhubd. Thus, here we
461 // need to wait until the releasd is confirmed before creating another
462 // consumer.
463 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
464 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
465
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700466 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800467 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700468 std::unique_ptr<ConsumerBuffer> c2 =
469 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700470 ASSERT_TRUE(c2.get() != nullptr);
471
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700472 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
473 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
474 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
475}
476
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800477TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
478 struct Metadata {
479 int64_t field1;
480 int64_t field2;
481 };
Tianyu1a60bb42018-10-08 14:56:08 -0700482 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800483 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
484 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700485 std::unique_ptr<ConsumerBuffer> c =
486 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800487 ASSERT_TRUE(c.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800488 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700489 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800490 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800491 LocalHandle fence;
492 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700493 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800494 EXPECT_EQ(m.field1, m2.field1);
495 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800496 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800497 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800498}
499
500TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
501 struct Metadata {
502 int64_t field1;
503 int64_t field2;
504 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700505 struct OverSizedMetadata {
506 int64_t field1;
507 int64_t field2;
508 int64_t field3;
509 };
Tianyu1a60bb42018-10-08 14:56:08 -0700510 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800511 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
512 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700513 std::unique_ptr<ConsumerBuffer> c =
514 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800515 ASSERT_TRUE(c.get() != nullptr);
516
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700517 // It is illegal to post metadata larger than originally requested during
518 // buffer allocation.
519 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700520 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800521 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700522
523 // It is ok to post metadata smaller than originally requested during
524 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700525 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800526}
527
528TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
529 struct Metadata {
530 int64_t field1;
531 int64_t field2;
532 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700533 struct OverSizedMetadata {
534 int64_t field1;
535 int64_t field2;
536 int64_t field3;
537 };
Tianyu1a60bb42018-10-08 14:56:08 -0700538 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800539 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
540 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700541 std::unique_ptr<ConsumerBuffer> c =
542 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800543 ASSERT_TRUE(c.get() != nullptr);
544
545 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700546 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800547
548 LocalHandle fence;
549 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700550 OverSizedMetadata e;
551
552 // It is illegal to acquire metadata larger than originally requested during
553 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700554 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700555
556 // It is ok to acquire metadata smaller than originally requested during
557 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700558 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700559 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800560}
561
562TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700563 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800564 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
565 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700566 std::unique_ptr<ConsumerBuffer> c =
567 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800568 ASSERT_TRUE(c.get() != nullptr);
569
570 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700571 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800572
573 LocalHandle fence;
574 EXPECT_EQ(0, c->Acquire(&fence));
575}
576
577TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700578 std::unique_ptr<ProducerBuffer> p =
579 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800580 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700581 std::unique_ptr<ConsumerBuffer> c =
582 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800583 ASSERT_TRUE(c.get() != nullptr);
584
585 LocalHandle fence;
586
Tianyue6e08ab2018-09-13 18:48:55 -0700587 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800588 EXPECT_EQ(0, c->Acquire(&fence));
589}
590
591TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700592 std::unique_ptr<ProducerBuffer> p =
593 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800594 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700595 std::unique_ptr<ConsumerBuffer> c =
596 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597 ASSERT_TRUE(c.get() != nullptr);
598
599 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700600 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800601}
602
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700603namespace {
604
605int PollFd(int fd, int timeout_ms) {
606 pollfd p = {fd, POLLIN, 0};
607 return poll(&p, 1, timeout_ms);
608}
609
610} // namespace
611
612TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700613 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700614 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
615 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700616 std::unique_ptr<ConsumerBuffer> c =
617 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700618 ASSERT_TRUE(c.get() != nullptr);
619
620 DvrNativeBufferMetadata meta;
621 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
622
623 // Post with unsignaled fence.
624 EXPECT_EQ(0, p->PostAsync(&meta, f1));
625
626 // Should acquire a valid fence.
627 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800628 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700629 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
630 EXPECT_TRUE(f2.IsValid());
631 // The original fence and acquired fence should have different fd number.
632 EXPECT_NE(f1.Get(), f2.Get());
633 EXPECT_GE(0, PollFd(f2.Get(), 0));
634
635 // Signal the original fence will trigger the new fence.
636 eventfd_write(f1.Get(), 1);
637 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800638 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700639
640 // Release the consumer with an invalid fence.
641 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
642
643 // Should gain an invalid fence.
644 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800645 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700646 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
647 EXPECT_FALSE(f3.IsValid());
648
649 // Post with a signaled fence.
650 EXPECT_EQ(0, p->PostAsync(&meta, f1));
651
652 // Should acquire a valid fence and it's already signalled.
653 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800654 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700655 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
656 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800657 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700658
659 // Release with an unsignalled fence and signal it immediately after release
660 // without producer gainning.
661 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
662 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
663 eventfd_write(f5.Get(), 1);
664
665 // Should gain a valid fence, which is already signaled.
666 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800667 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700668 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
669 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800670 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700671}
672
673TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700674 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700675 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
676 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700677 std::unique_ptr<ConsumerBuffer> c1 =
678 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700679 ASSERT_TRUE(c1.get() != nullptr);
680 const uint64_t consumer_state_bit1 = c1->buffer_state_bit();
681
682 DvrNativeBufferMetadata meta;
683 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
684
685 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800686 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700687 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
688 // Destroy the consumer now will make it orphaned and the buffer is still
689 // acquired.
690 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800691 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700692
Tianyu1a60bb42018-10-08 14:56:08 -0700693 std::unique_ptr<ConsumerBuffer> c2 =
694 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700695 ASSERT_TRUE(c2.get() != nullptr);
696 const uint64_t consumer_state_bit2 = c2->buffer_state_bit();
697 EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
698
699 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800700 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
702 // Releasing the consumer makes the buffer gainable.
703 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
704
705 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800706 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700707
708 // But if another consumer is created in released state.
Tianyu1a60bb42018-10-08 14:56:08 -0700709 std::unique_ptr<ConsumerBuffer> c3 =
710 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700711 ASSERT_TRUE(c3.get() != nullptr);
712 const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
713 EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
714 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800715 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
717
718 // Producer should be able to gain no matter what.
719 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
720}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700721
722TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700723 // TODO(b/112338294) rewrite test after migration
724 return;
725
Tianyu1a60bb42018-10-08 14:56:08 -0700726 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700727 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700728 std::unique_ptr<ConsumerBuffer> c =
729 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700730 ASSERT_TRUE(p.get() != nullptr);
731 ASSERT_TRUE(c.get() != nullptr);
732
733 DvrNativeBufferMetadata metadata;
734 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700735 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700736
737 // Detach in posted state should fail.
738 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
739 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
740 auto s1 = p->Detach();
741 EXPECT_FALSE(s1);
742
743 // Detach in acquired state should fail.
744 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
745 s1 = p->Detach();
746 EXPECT_FALSE(s1);
747
748 // Detach in released state should fail.
749 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
750 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
751 s1 = p->Detach();
752 EXPECT_FALSE(s1);
753
754 // Detach in gained state should succeed.
755 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
756 s1 = p->Detach();
757 EXPECT_TRUE(s1);
758
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700759 LocalChannelHandle handle = s1.take();
760 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700761
762 // Both producer and consumer should have hangup.
763 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
764 auto s2 = p->GetEventMask(POLLHUP);
765 EXPECT_TRUE(s2);
766 EXPECT_EQ(s2.get(), POLLHUP);
767
768 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
769 s2 = p->GetEventMask(POLLHUP);
770 EXPECT_TRUE(s2);
771 EXPECT_EQ(s2.get(), POLLHUP);
772
773 auto s3 = p->CreateConsumer();
774 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700775 // Note that here the expected error code is EOPNOTSUPP as the socket towards
776 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700777 EXPECT_EQ(s3.error(), EOPNOTSUPP);
778
779 s3 = c->CreateConsumer();
780 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700781 // Note that here the expected error code is EPIPE returned from
782 // ConsumerChannel::HandleMessage as the socket is still open but the producer
783 // is gone.
784 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700785
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700786 // Detached buffer handle can be use to construct a new BufferHubBuffer
787 // object.
788 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700789 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700790 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700791 EXPECT_TRUE(d->IsValid());
792
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700793 EXPECT_EQ(d->id(), p_id);
794}
795
Tianyub61df912018-10-16 14:55:39 -0700796TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
797 // Buffer Creation will fail: BLOB format requires height to be 1.
798 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
799 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
800 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700801
Tianyub61df912018-10-16 14:55:39 -0700802 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700803 EXPECT_FALSE(b1->IsValid());
804
Tianyub61df912018-10-16 14:55:39 -0700805 // Buffer Creation will fail: user metadata size too large.
806 auto b2 = BufferHubBuffer::Create(
807 kWidth, kHeight, kLayerCount, kFormat, kUsage,
808 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700809
Tianyub61df912018-10-16 14:55:39 -0700810 EXPECT_FALSE(b2->IsConnected());
811 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700812
Tianyub61df912018-10-16 14:55:39 -0700813 // Buffer Creation will fail: user metadata size too large.
814 auto b3 = BufferHubBuffer::Create(
815 kWidth, kHeight, kLayerCount, kFormat, kUsage,
816 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
817 kMetadataHeaderSize);
818
819 EXPECT_FALSE(b3->IsConnected());
820 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700821}
822
Tianyub61df912018-10-16 14:55:39 -0700823TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
824 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
825 kUsage, kUserMetadataSize);
826 EXPECT_TRUE(b1->IsConnected());
827 EXPECT_TRUE(b1->IsValid());
828 EXPECT_NE(b1->id(), 0);
829}
830
831TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700832 // TODO(b/112338294) rewrite test after migration
833 return;
834
Tianyu1a60bb42018-10-08 14:56:08 -0700835 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700836 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
837 ASSERT_TRUE(p1.get() != nullptr);
838 int p1_id = p1->id();
839
840 // Detached the producer.
841 auto status_or_handle = p1->Detach();
842 EXPECT_TRUE(status_or_handle.ok());
843 LocalChannelHandle h1 = status_or_handle.take();
844 EXPECT_TRUE(h1.valid());
845
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700846 // Detached buffer handle can be use to construct a new BufferHubBuffer
847 // object.
848 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700849 EXPECT_FALSE(h1.valid());
850 EXPECT_TRUE(b1->IsValid());
851 int b1_id = b1->id();
852 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700853}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700854
Tianyub61df912018-10-16 14:55:39 -0700855TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
856 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
857 kUsage, kUserMetadataSize);
858 int b1_id = b1->id();
859 EXPECT_TRUE(b1->IsValid());
860 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
861
862 auto status_or_handle = b1->Duplicate();
863 EXPECT_TRUE(status_or_handle);
864
865 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700866 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700867 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700868
Tianyub61df912018-10-16 14:55:39 -0700869 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700870 LocalChannelHandle h2 = status_or_handle.take();
871 EXPECT_TRUE(h2.valid());
872
Tianyub61df912018-10-16 14:55:39 -0700873 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700874 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700875 ASSERT_TRUE(b2 != nullptr);
876 EXPECT_TRUE(b2->IsValid());
877 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700878
Tianyub61df912018-10-16 14:55:39 -0700879 int b2_id = b2->id();
880
881 // These two buffer instances are based on the same physical buffer under the
882 // hood, so they should share the same id.
883 EXPECT_EQ(b1_id, b2_id);
884 // We use buffer_state_bit() to tell those two instances apart.
885 EXPECT_NE(b1->buffer_state_bit(), b2->buffer_state_bit());
886 EXPECT_NE(b1->buffer_state_bit(), 0ULL);
887 EXPECT_NE(b2->buffer_state_bit(), 0ULL);
888 EXPECT_NE(b1->buffer_state_bit(), kProducerStateBit);
889 EXPECT_NE(b2->buffer_state_bit(), kProducerStateBit);
890
891 // Both buffer instances should be in gained state.
892 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
893 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
894
895 // TODO(b/112338294) rewrite test after migration
896 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700897}