blob: 230282887f3f7c4f9b5aaf700255f35568014e41 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <gtest/gtest.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07002#include <poll.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <private/dvr/buffer_hub_client.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07004#include <private/dvr/bufferhub_rpc.h>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -07005#include <private/dvr/detached_buffer.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07006#include <sys/epoll.h>
7#include <sys/eventfd.h>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -07008#include <ui/DetachedBufferHandle.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08009
10#include <mutex>
11#include <thread>
12
Alex Vakulenko4fe60582017-02-02 11:35:59 -080013#define RETRY_EINTR(fnc_call) \
14 ([&]() -> decltype(fnc_call) { \
15 decltype(fnc_call) result; \
16 do { \
17 result = (fnc_call); \
18 } while (result == -1 && errno == EINTR); \
19 return result; \
20 })()
21
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070022using android::sp;
23using android::GraphicBuffer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080024using android::dvr::BufferConsumer;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070025using android::dvr::BufferHubDefs::kConsumerStateMask;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070026using android::dvr::BufferHubDefs::kMetadataHeaderSize;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070027using android::dvr::BufferHubDefs::kProducerStateBit;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -070028using android::dvr::BufferHubDefs::IsBufferGained;
29using android::dvr::BufferHubDefs::IsBufferPosted;
30using android::dvr::BufferHubDefs::IsBufferAcquired;
31using android::dvr::BufferHubDefs::IsBufferReleased;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070032using android::dvr::BufferProducer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070033using android::dvr::DetachedBuffer;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070034using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070036using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080037
38const int kWidth = 640;
39const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070040const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080041const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
42const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070043const size_t kUserMetadataSize = 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080044const uint64_t kContext = 42;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -070045const size_t kMaxConsumerCount = 63;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080046const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080047
48using LibBufferHubTest = ::testing::Test;
49
50TEST_F(LibBufferHubTest, TestBasicUsage) {
51 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
52 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
53 ASSERT_TRUE(p.get() != nullptr);
54 std::unique_ptr<BufferConsumer> c =
55 BufferConsumer::Import(p->CreateConsumer());
56 ASSERT_TRUE(c.get() != nullptr);
57 // Check that consumers can spawn other consumers.
58 std::unique_ptr<BufferConsumer> c2 =
59 BufferConsumer::Import(c->CreateConsumer());
60 ASSERT_TRUE(c2.get() != nullptr);
61
Corey Tabaka52ea25c2017-09-13 18:02:48 -070062 // Producer state mask is unique, i.e. 1.
63 EXPECT_EQ(p->buffer_state_bit(), kProducerStateBit);
64 // Consumer state mask cannot have producer bit on.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080065 EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070066 // Consumer state mask must be a single, i.e. power of 2.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080067 EXPECT_NE(c->buffer_state_bit(), 0U);
68 EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070069 // Consumer state mask cannot have producer bit on.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080070 EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070071 // Consumer state mask must be a single, i.e. power of 2.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080072 EXPECT_NE(c2->buffer_state_bit(), 0U);
73 EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070074 // Each consumer should have unique bit.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080075 EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070076
77 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080078 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
79 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
80 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070081
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080082 EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070083
84 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080085 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
86 EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
87 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088
89 uint64_t context;
90 LocalHandle fence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070091 EXPECT_EQ(0, c->Acquire(&fence, &context));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080092 EXPECT_EQ(kContext, context);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080093 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
94 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080095
Corey Tabaka52ea25c2017-09-13 18:02:48 -070096 EXPECT_EQ(0, c2->Acquire(&fence, &context));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080097 EXPECT_EQ(kContext, context);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080098 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
99 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800100
101 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800102 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800103 EXPECT_EQ(0, c2->Discard());
104
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800105 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800106 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800107 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
108 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
109 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700110}
111
112TEST_F(LibBufferHubTest, TestEpoll) {
113 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
114 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
115 ASSERT_TRUE(p.get() != nullptr);
116 std::unique_ptr<BufferConsumer> c =
117 BufferConsumer::Import(p->CreateConsumer());
118 ASSERT_TRUE(c.get() != nullptr);
119
120 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
121 ASSERT_TRUE(epoll_fd.IsValid());
122
123 epoll_event event;
124 std::array<epoll_event, 64> events;
125
126 auto event_sources = p->GetEventSources();
127 ASSERT_LT(event_sources.size(), events.size());
128
129 for (const auto& event_source : event_sources) {
130 event = {.events = event_source.event_mask | EPOLLET,
131 .data = {.fd = p->event_fd()}};
132 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
133 &event));
134 }
135
136 event_sources = c->GetEventSources();
137 ASSERT_LT(event_sources.size(), events.size());
138
139 for (const auto& event_source : event_sources) {
140 event = {.events = event_source.event_mask | EPOLLET,
141 .data = {.fd = c->event_fd()}};
142 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
143 &event));
144 }
145
146 // No events should be signaled initially.
147 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
148
149 // Post the producer and check for consumer signal.
150 EXPECT_EQ(0, p->Post({}, kContext));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800151 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
152 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700153 ASSERT_TRUE(events[0].events & EPOLLIN);
154 ASSERT_EQ(c->event_fd(), events[0].data.fd);
155
156 // Save the event bits to translate later.
157 event = events[0];
158
159 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800160 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
161 kPollTimeoutMs));
162 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
163 kPollTimeoutMs));
164 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
165 kPollTimeoutMs));
166 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
167 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700168
169 // Translate the events.
170 auto event_status = c->GetEventMask(event.events);
171 ASSERT_TRUE(event_status);
172 ASSERT_TRUE(event_status.get() & EPOLLIN);
173
174 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800175 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
176 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700177}
178
179TEST_F(LibBufferHubTest, TestStateMask) {
180 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
181 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
182 ASSERT_TRUE(p.get() != nullptr);
183
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700184 // It's ok to create up to kMaxConsumerCount consumer buffers.
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700185 uint64_t buffer_state_bits = p->buffer_state_bit();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700186 std::array<std::unique_ptr<BufferConsumer>, kMaxConsumerCount> cs;
187 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700188 cs[i] = BufferConsumer::Import(p->CreateConsumer());
189 ASSERT_TRUE(cs[i].get() != nullptr);
190 // Expect all buffers have unique state mask.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800191 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700192 buffer_state_bits |= cs[i]->buffer_state_bit();
193 }
194 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
195
196 // The 64th creation will fail with out-of-memory error.
197 auto state = p->CreateConsumer();
198 EXPECT_EQ(state.error(), E2BIG);
199
200 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700201 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700202 buffer_state_bits &= ~cs[i]->buffer_state_bit();
203 cs[i] = nullptr;
204 cs[i] = BufferConsumer::Import(p->CreateConsumer());
205 ASSERT_TRUE(cs[i].get() != nullptr);
206 // The released state mask will be reused.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800207 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700208 buffer_state_bits |= cs[i]->buffer_state_bit();
209 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
210 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800211}
212
Corey Tabakad53870c2017-07-06 18:04:27 -0700213TEST_F(LibBufferHubTest, TestStateTransitions) {
214 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
215 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
216 ASSERT_TRUE(p.get() != nullptr);
217 std::unique_ptr<BufferConsumer> c =
218 BufferConsumer::Import(p->CreateConsumer());
219 ASSERT_TRUE(c.get() != nullptr);
220
221 uint64_t context;
222 LocalHandle fence;
223
224 // The producer buffer starts in gained state.
225
226 // Acquire, release, and gain in gained state should fail.
227 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
228 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
229 EXPECT_EQ(-EALREADY, p->Gain(&fence));
230
231 // Post in gained state should succeed.
232 EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
233
234 // Post, release, and gain in posted state should fail.
235 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
236 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
237 EXPECT_EQ(-EBUSY, p->Gain(&fence));
238
239 // Acquire in posted state should succeed.
240 EXPECT_LE(0, c->Acquire(&fence, &context));
241
242 // Acquire, post, and gain in acquired state should fail.
243 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
244 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
245 EXPECT_EQ(-EBUSY, p->Gain(&fence));
246
247 // Release in acquired state should succeed.
248 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800249 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700250
251 // Release, acquire, and post in released state should fail.
252 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
253 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
254 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
255
256 // Gain in released state should succeed.
257 EXPECT_EQ(0, p->Gain(&fence));
258
259 // Acquire, release, and gain in gained state should fail.
260 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
261 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
262 EXPECT_EQ(-EALREADY, p->Gain(&fence));
263}
264
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
266 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
267 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
268 ASSERT_TRUE(p.get() != nullptr);
269 std::unique_ptr<BufferConsumer> c =
270 BufferConsumer::Import(p->CreateConsumer());
271 ASSERT_TRUE(c.get() != nullptr);
272
273 DvrNativeBufferMetadata metadata;
274 LocalHandle invalid_fence;
275
276 // The producer buffer starts in gained state.
277
278 // Acquire, release, and gain in gained state should fail.
279 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
280 EXPECT_FALSE(invalid_fence.IsValid());
281 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
282 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
283 EXPECT_FALSE(invalid_fence.IsValid());
284
285 // Post in gained state should succeed.
286 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
287 EXPECT_EQ(p->buffer_state(), c->buffer_state());
288 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
289
290 // Post, release, and gain in posted state should fail.
291 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
292 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
293 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
294 EXPECT_FALSE(invalid_fence.IsValid());
295
296 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800297 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700298 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
299 EXPECT_FALSE(invalid_fence.IsValid());
300 EXPECT_EQ(p->buffer_state(), c->buffer_state());
301 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
302
303 // Acquire, post, and gain in acquired state should fail.
304 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
305 EXPECT_FALSE(invalid_fence.IsValid());
306 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
307 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
308 EXPECT_FALSE(invalid_fence.IsValid());
309
310 // Release in acquired state should succeed.
311 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800312 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700313 EXPECT_EQ(p->buffer_state(), c->buffer_state());
314 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
315
316 // Release, acquire, and post in released state should fail.
317 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
318 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
319 EXPECT_FALSE(invalid_fence.IsValid());
320 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
321
322 // Gain in released state should succeed.
323 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
324 EXPECT_FALSE(invalid_fence.IsValid());
325 EXPECT_EQ(p->buffer_state(), c->buffer_state());
326 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
327
328 // Acquire, release, and gain in gained state should fail.
329 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
330 EXPECT_FALSE(invalid_fence.IsValid());
331 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
332 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
333 EXPECT_FALSE(invalid_fence.IsValid());
334}
335
336TEST_F(LibBufferHubTest, TestZeroConsumer) {
337 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
338 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
339 ASSERT_TRUE(p.get() != nullptr);
340
341 DvrNativeBufferMetadata metadata;
342 LocalHandle invalid_fence;
343
344 // Newly created.
345 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
346 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
347 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
348
349 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800350 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700351
352 // A new consumer should still be able to acquire the buffer immediately.
353 std::unique_ptr<BufferConsumer> c =
354 BufferConsumer::Import(p->CreateConsumer());
355 ASSERT_TRUE(c.get() != nullptr);
356 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
357 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
358}
359
360TEST_F(LibBufferHubTest, TestMaxConsumers) {
361 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
362 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
363 ASSERT_TRUE(p.get() != nullptr);
364
365 std::array<std::unique_ptr<BufferConsumer>, kMaxConsumerCount> cs;
366 for (size_t i = 0; i < kMaxConsumerCount; i++) {
367 cs[i] = BufferConsumer::Import(p->CreateConsumer());
368 ASSERT_TRUE(cs[i].get() != nullptr);
369 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
370 }
371
372 DvrNativeBufferMetadata metadata;
373 LocalHandle invalid_fence;
374
375 // Post the producer should trigger all consumers to be available.
376 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
377 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
378 for (size_t i = 0; i < kMaxConsumerCount; i++) {
379 EXPECT_TRUE(IsBufferPosted(cs[i]->buffer_state(),
380 cs[i]->buffer_state_bit()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800381 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700382 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
383 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
384 }
385
386 // All consumers have to release before the buffer is considered to be
387 // released.
388 for (size_t i = 0; i < kMaxConsumerCount; i++) {
389 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
390 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
391 }
392
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800393 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700394 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
395
396 // Buffer state cross all clients must be consistent.
397 for (size_t i = 0; i < kMaxConsumerCount; i++) {
398 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
399 }
400}
401
402TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
403 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
404 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
405 ASSERT_TRUE(p.get() != nullptr);
406 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
407
408 std::unique_ptr<BufferConsumer> c =
409 BufferConsumer::Import(p->CreateConsumer());
410 ASSERT_TRUE(c.get() != nullptr);
411 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
412
413 DvrNativeBufferMetadata metadata;
414 LocalHandle invalid_fence;
415
416 // Post the gained buffer should signal already created consumer.
417 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
418 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800419 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700420 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
421 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
422}
423
424TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
425 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
426 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
427 ASSERT_TRUE(p.get() != nullptr);
428 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
429
430 DvrNativeBufferMetadata metadata;
431 LocalHandle invalid_fence;
432
433 // Post the gained buffer before any consumer gets created.
434 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
435 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
436
437 // Newly created consumer should be automatically sigalled.
438 std::unique_ptr<BufferConsumer> c =
439 BufferConsumer::Import(p->CreateConsumer());
440 ASSERT_TRUE(c.get() != nullptr);
441 EXPECT_TRUE(IsBufferPosted(c->buffer_state()));
442 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
443 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
444}
445
446TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
447 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
448 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
449 ASSERT_TRUE(p.get() != nullptr);
450
451 std::unique_ptr<BufferConsumer> c1 =
452 BufferConsumer::Import(p->CreateConsumer());
453 ASSERT_TRUE(c1.get() != nullptr);
454
455 DvrNativeBufferMetadata metadata;
456 LocalHandle invalid_fence;
457
458 // Post, acquire, and release the buffer..
459 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800460 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700461 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
462 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
463
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800464 // Note that the next PDX call is on the producer channel, which may be
465 // executed before Release impulse gets executed by bufferhubd. Thus, here we
466 // need to wait until the releasd is confirmed before creating another
467 // consumer.
468 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
469 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
470
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700471 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800472 // buffer un-released.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700473 std::unique_ptr<BufferConsumer> c2 =
474 BufferConsumer::Import(p->CreateConsumer());
475 ASSERT_TRUE(c2.get() != nullptr);
476
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700477 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
478 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
479 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
480}
481
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800482TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
483 struct Metadata {
484 int64_t field1;
485 int64_t field2;
486 };
487 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
488 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
489 ASSERT_TRUE(p.get() != nullptr);
490 std::unique_ptr<BufferConsumer> c =
491 BufferConsumer::Import(p->CreateConsumer());
492 ASSERT_TRUE(c.get() != nullptr);
493
494 Metadata m = {1, 3};
495 EXPECT_EQ(0, p->Post(LocalHandle(), m));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800496 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800497
498 LocalHandle fence;
499 Metadata m2 = {};
500 EXPECT_EQ(0, c->Acquire(&fence, &m2));
501 EXPECT_EQ(m.field1, m2.field1);
502 EXPECT_EQ(m.field2, m2.field2);
503
504 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800505 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800506}
507
508TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
509 struct Metadata {
510 int64_t field1;
511 int64_t field2;
512 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700513 struct OverSizedMetadata {
514 int64_t field1;
515 int64_t field2;
516 int64_t field3;
517 };
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800518 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
519 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
520 ASSERT_TRUE(p.get() != nullptr);
521 std::unique_ptr<BufferConsumer> c =
522 BufferConsumer::Import(p->CreateConsumer());
523 ASSERT_TRUE(c.get() != nullptr);
524
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700525 // It is illegal to post metadata larger than originally requested during
526 // buffer allocation.
527 OverSizedMetadata evil_meta = {};
528 EXPECT_NE(0, p->Post(LocalHandle(), evil_meta));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800529 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700530
531 // It is ok to post metadata smaller than originally requested during
532 // buffer allocation.
533 int64_t sequence = 42;
534 EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800535}
536
537TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
538 struct Metadata {
539 int64_t field1;
540 int64_t field2;
541 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700542 struct OverSizedMetadata {
543 int64_t field1;
544 int64_t field2;
545 int64_t field3;
546 };
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800547 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
548 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
549 ASSERT_TRUE(p.get() != nullptr);
550 std::unique_ptr<BufferConsumer> c =
551 BufferConsumer::Import(p->CreateConsumer());
552 ASSERT_TRUE(c.get() != nullptr);
553
554 Metadata m = {1, 3};
555 EXPECT_EQ(0, p->Post(LocalHandle(), m));
556
557 LocalHandle fence;
558 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700559 OverSizedMetadata e;
560
561 // It is illegal to acquire metadata larger than originally requested during
562 // buffer allocation.
563 EXPECT_NE(0, c->Acquire(&fence, &e));
564
565 // It is ok to acquire metadata smaller than originally requested during
566 // buffer allocation.
567 EXPECT_EQ(0, c->Acquire(&fence, &sequence));
568 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569}
570
571TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
572 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
573 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
574 ASSERT_TRUE(p.get() != nullptr);
575 std::unique_ptr<BufferConsumer> c =
576 BufferConsumer::Import(p->CreateConsumer());
577 ASSERT_TRUE(c.get() != nullptr);
578
579 int64_t sequence = 3;
580 EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
581
582 LocalHandle fence;
583 EXPECT_EQ(0, c->Acquire(&fence));
584}
585
586TEST_F(LibBufferHubTest, TestWithNoMeta) {
587 std::unique_ptr<BufferProducer> p =
588 BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
589 ASSERT_TRUE(p.get() != nullptr);
590 std::unique_ptr<BufferConsumer> c =
591 BufferConsumer::Import(p->CreateConsumer());
592 ASSERT_TRUE(c.get() != nullptr);
593
594 LocalHandle fence;
595
596 EXPECT_EQ(0, p->Post<void>(LocalHandle()));
597 EXPECT_EQ(0, c->Acquire(&fence));
598}
599
600TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
601 std::unique_ptr<BufferProducer> p =
602 BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
603 ASSERT_TRUE(p.get() != nullptr);
604 std::unique_ptr<BufferConsumer> c =
605 BufferConsumer::Import(p->CreateConsumer());
606 ASSERT_TRUE(c.get() != nullptr);
607
608 int64_t sequence = 3;
609 EXPECT_NE(0, p->Post(LocalHandle(), sequence));
610}
611
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700612namespace {
613
614int PollFd(int fd, int timeout_ms) {
615 pollfd p = {fd, POLLIN, 0};
616 return poll(&p, 1, timeout_ms);
617}
618
619} // namespace
620
621TEST_F(LibBufferHubTest, TestAcquireFence) {
622 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
623 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
624 ASSERT_TRUE(p.get() != nullptr);
625 std::unique_ptr<BufferConsumer> c =
626 BufferConsumer::Import(p->CreateConsumer());
627 ASSERT_TRUE(c.get() != nullptr);
628
629 DvrNativeBufferMetadata meta;
630 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
631
632 // Post with unsignaled fence.
633 EXPECT_EQ(0, p->PostAsync(&meta, f1));
634
635 // Should acquire a valid fence.
636 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800637 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700638 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
639 EXPECT_TRUE(f2.IsValid());
640 // The original fence and acquired fence should have different fd number.
641 EXPECT_NE(f1.Get(), f2.Get());
642 EXPECT_GE(0, PollFd(f2.Get(), 0));
643
644 // Signal the original fence will trigger the new fence.
645 eventfd_write(f1.Get(), 1);
646 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800647 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700648
649 // Release the consumer with an invalid fence.
650 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
651
652 // Should gain an invalid fence.
653 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800654 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700655 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
656 EXPECT_FALSE(f3.IsValid());
657
658 // Post with a signaled fence.
659 EXPECT_EQ(0, p->PostAsync(&meta, f1));
660
661 // Should acquire a valid fence and it's already signalled.
662 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800663 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700664 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
665 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800666 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700667
668 // Release with an unsignalled fence and signal it immediately after release
669 // without producer gainning.
670 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
671 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
672 eventfd_write(f5.Get(), 1);
673
674 // Should gain a valid fence, which is already signaled.
675 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800676 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700677 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
678 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800679 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700680}
681
682TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
683 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
684 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
685 ASSERT_TRUE(p.get() != nullptr);
686 std::unique_ptr<BufferConsumer> c1 =
687 BufferConsumer::Import(p->CreateConsumer());
688 ASSERT_TRUE(c1.get() != nullptr);
689 const uint64_t consumer_state_bit1 = c1->buffer_state_bit();
690
691 DvrNativeBufferMetadata meta;
692 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
693
694 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800695 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700696 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
697 // Destroy the consumer now will make it orphaned and the buffer is still
698 // acquired.
699 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800700 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701
702 std::unique_ptr<BufferConsumer> c2 =
703 BufferConsumer::Import(p->CreateConsumer());
704 ASSERT_TRUE(c2.get() != nullptr);
705 const uint64_t consumer_state_bit2 = c2->buffer_state_bit();
706 EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
707
708 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800709 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700710 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
711 // Releasing the consumer makes the buffer gainable.
712 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
713
714 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800715 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716
717 // But if another consumer is created in released state.
718 std::unique_ptr<BufferConsumer> c3 =
719 BufferConsumer::Import(p->CreateConsumer());
720 ASSERT_TRUE(c3.get() != nullptr);
721 const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
722 EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
723 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800724 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
726
727 // Producer should be able to gain no matter what.
728 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
729}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700730
731TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
732 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
733 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
734 std::unique_ptr<BufferConsumer> c =
735 BufferConsumer::Import(p->CreateConsumer());
736 ASSERT_TRUE(p.get() != nullptr);
737 ASSERT_TRUE(c.get() != nullptr);
738
739 DvrNativeBufferMetadata metadata;
740 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700741 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700742
743 // Detach in posted state should fail.
744 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
745 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
746 auto s1 = p->Detach();
747 EXPECT_FALSE(s1);
748
749 // Detach in acquired state should fail.
750 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
751 s1 = p->Detach();
752 EXPECT_FALSE(s1);
753
754 // Detach in released state should fail.
755 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
756 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
757 s1 = p->Detach();
758 EXPECT_FALSE(s1);
759
760 // Detach in gained state should succeed.
761 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
762 s1 = p->Detach();
763 EXPECT_TRUE(s1);
764
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700765 LocalChannelHandle handle = s1.take();
766 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700767
768 // Both producer and consumer should have hangup.
769 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
770 auto s2 = p->GetEventMask(POLLHUP);
771 EXPECT_TRUE(s2);
772 EXPECT_EQ(s2.get(), POLLHUP);
773
774 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
775 s2 = p->GetEventMask(POLLHUP);
776 EXPECT_TRUE(s2);
777 EXPECT_EQ(s2.get(), POLLHUP);
778
779 auto s3 = p->CreateConsumer();
780 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700781 // Note that here the expected error code is EOPNOTSUPP as the socket towards
782 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700783 EXPECT_EQ(s3.error(), EOPNOTSUPP);
784
785 s3 = c->CreateConsumer();
786 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700787 // Note that here the expected error code is EPIPE returned from
788 // ConsumerChannel::HandleMessage as the socket is still open but the producer
789 // is gone.
790 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700791
792 // Detached buffer handle can be use to construct a new DetachedBuffer object.
793 auto d = DetachedBuffer::Import(std::move(handle));
794 EXPECT_FALSE(handle.valid());
795 EXPECT_TRUE(d->IsValid());
796
797 ASSERT_TRUE(d->buffer() != nullptr);
798 EXPECT_EQ(d->buffer()->initCheck(), 0);
799 EXPECT_EQ(d->id(), p_id);
800}
801
802TEST_F(LibBufferHubTest, TestCreateDetachedBufferFails) {
803 // Buffer Creation will fail: BLOB format requires height to be 1.
804 auto b1 = DetachedBuffer::Create(kWidth, /*height=2*/2, kLayerCount,
805 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
806 kUserMetadataSize);
807
808 EXPECT_FALSE(b1->IsValid());
809 EXPECT_TRUE(b1->buffer() == nullptr);
810
811 // Buffer Creation will fail: user metadata size too large.
812 auto b2 = DetachedBuffer::Create(
813 kWidth, kHeight, kLayerCount, kFormat, kUsage,
814 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
815
816 EXPECT_FALSE(b2->IsValid());
817 EXPECT_TRUE(b2->buffer() == nullptr);
818
819 // Buffer Creation will fail: user metadata size too large.
820 auto b3 = DetachedBuffer::Create(
821 kWidth, kHeight, kLayerCount, kFormat, kUsage,
822 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
823 kMetadataHeaderSize);
824
825 EXPECT_FALSE(b3->IsValid());
826 EXPECT_TRUE(b3->buffer() == nullptr);
827}
828
829TEST_F(LibBufferHubTest, TestCreateDetachedBuffer) {
830 auto b1 = DetachedBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
831 kUsage, kUserMetadataSize);
832 int b1_id = b1->id();
833
834 EXPECT_TRUE(b1->IsValid());
835 ASSERT_TRUE(b1->buffer() != nullptr);
836 EXPECT_NE(b1->id(), 0);
837 EXPECT_EQ(b1->buffer()->initCheck(), 0);
838 EXPECT_FALSE(b1->buffer()->isDetachedBuffer());
839
840 // Takes a standalone GraphicBuffer which still holds on an
841 // PDX::LocalChannelHandle towards BufferHub.
842 sp<GraphicBuffer> g1 = b1->TakeGraphicBuffer();
843 ASSERT_TRUE(g1 != nullptr);
844 EXPECT_TRUE(g1->isDetachedBuffer());
845
846 EXPECT_FALSE(b1->IsValid());
847 EXPECT_TRUE(b1->buffer() == nullptr);
848
849 sp<GraphicBuffer> g2 = b1->TakeGraphicBuffer();
850 ASSERT_TRUE(g2 == nullptr);
851
852 auto h1 = g1->takeDetachedBufferHandle();
853 ASSERT_TRUE(h1 != nullptr);
854 ASSERT_TRUE(h1->isValid());
855 EXPECT_FALSE(g1->isDetachedBuffer());
856
857 auto b2 = DetachedBuffer::Import(std::move(h1->handle()));
858 ASSERT_FALSE(h1->isValid());
859 EXPECT_TRUE(b2->IsValid());
860
861 ASSERT_TRUE(b2->buffer() != nullptr);
862 EXPECT_EQ(b2->buffer()->initCheck(), 0);
863
864 // The newly created DetachedBuffer should share the original buffer_id.
865 EXPECT_EQ(b2->id(), b1_id);
866 EXPECT_FALSE(b2->buffer()->isDetachedBuffer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700867}