blob: db624de2604d99612418662f39ba549720f4fd24 [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;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070044// Maximum number of consumers for the buffer that only has one producer in the
45// test.
46const size_t kMaxConsumerCount =
47 android::dvr::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080048const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080049
50using LibBufferHubTest = ::testing::Test;
51
52TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070053 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080054 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
55 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -070056 std::unique_ptr<ConsumerBuffer> c =
57 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080058 ASSERT_TRUE(c.get() != nullptr);
59 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070060 std::unique_ptr<ConsumerBuffer> c2 =
61 ConsumerBuffer::Import(c->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 ASSERT_TRUE(c2.get() != nullptr);
63
Corey Tabaka52ea25c2017-09-13 18:02:48 -070064 // Producer state mask is unique, i.e. 1.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070065 EXPECT_EQ(p->client_state_mask(), kProducerStateBit);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070066 // Consumer state mask cannot have producer bit on.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070067 EXPECT_EQ(c->client_state_mask() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070068 // Consumer state mask must be a single, i.e. power of 2.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070069 EXPECT_NE(c->client_state_mask(), 0U);
70 EXPECT_EQ(c->client_state_mask() & (c->client_state_mask() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070071 // Consumer state mask cannot have producer bit on.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070072 EXPECT_EQ(c2->client_state_mask() & kProducerStateBit, 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070073 // Consumer state mask must be a single, i.e. power of 2.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070074 EXPECT_NE(c2->client_state_mask(), 0U);
75 EXPECT_EQ(c2->client_state_mask() & (c2->client_state_mask() - 1), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070076 // Each consumer should have unique bit.
Tianyu Jiang7e204b72018-10-26 15:39:18 -070077 EXPECT_EQ(c->client_state_mask() & c2->client_state_mask(), 0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070078
79 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080080 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
81 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
82 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070083
Tianyu58a05a22018-10-10 18:41:27 -070084 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070085
86 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080087 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
88 EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
89 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080091 LocalHandle fence;
Tianyu58a05a22018-10-10 18:41:27 -070092 EXPECT_EQ(0, c->Acquire(&fence));
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
Tianyu58a05a22018-10-10 18:41:27 -070096 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080097 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
98 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080099
100 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800101 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800102 EXPECT_EQ(0, c2->Discard());
103
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800104 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800105 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800106 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
107 EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
108 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700109}
110
111TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700112 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700113 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
114 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700115 std::unique_ptr<ConsumerBuffer> c =
116 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700117 ASSERT_TRUE(c.get() != nullptr);
118
119 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
120 ASSERT_TRUE(epoll_fd.IsValid());
121
122 epoll_event event;
123 std::array<epoll_event, 64> events;
124
125 auto event_sources = p->GetEventSources();
126 ASSERT_LT(event_sources.size(), events.size());
127
128 for (const auto& event_source : event_sources) {
129 event = {.events = event_source.event_mask | EPOLLET,
130 .data = {.fd = p->event_fd()}};
131 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
132 &event));
133 }
134
135 event_sources = c->GetEventSources();
136 ASSERT_LT(event_sources.size(), events.size());
137
138 for (const auto& event_source : event_sources) {
139 event = {.events = event_source.event_mask | EPOLLET,
140 .data = {.fd = c->event_fd()}};
141 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
142 &event));
143 }
144
145 // No events should be signaled initially.
146 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
147
148 // Post the producer and check for consumer signal.
Tianyu58a05a22018-10-10 18:41:27 -0700149 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800150 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
151 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700152 ASSERT_TRUE(events[0].events & EPOLLIN);
153 ASSERT_EQ(c->event_fd(), events[0].data.fd);
154
155 // Save the event bits to translate later.
156 event = events[0];
157
158 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800159 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
160 kPollTimeoutMs));
161 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
162 kPollTimeoutMs));
163 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
164 kPollTimeoutMs));
165 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
166 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700167
168 // Translate the events.
169 auto event_status = c->GetEventMask(event.events);
170 ASSERT_TRUE(event_status);
171 ASSERT_TRUE(event_status.get() & EPOLLIN);
172
173 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800174 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
175 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700176}
177
178TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700179 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700180 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
181 ASSERT_TRUE(p.get() != nullptr);
182
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700183 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700184 uint64_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700185 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700186 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700187 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700188 ASSERT_TRUE(cs[i].get() != nullptr);
189 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700190 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
191 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700192 }
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700193 EXPECT_EQ(client_state_masks, kProducerStateBit | kConsumerStateMask);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700194
195 // The 64th creation will fail with out-of-memory error.
196 auto state = p->CreateConsumer();
197 EXPECT_EQ(state.error(), E2BIG);
198
199 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700200 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700201 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700202 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700203 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700204 ASSERT_TRUE(cs[i].get() != nullptr);
205 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700206 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
207 client_state_masks |= cs[i]->client_state_mask();
208 EXPECT_EQ(client_state_masks, kProducerStateBit | kConsumerStateMask);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700209 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800210}
211
Corey Tabakad53870c2017-07-06 18:04:27 -0700212TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700213 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700214 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
215 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700216 std::unique_ptr<ConsumerBuffer> c =
217 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700218 ASSERT_TRUE(c.get() != nullptr);
219
Corey Tabakad53870c2017-07-06 18:04:27 -0700220 LocalHandle fence;
221
222 // The producer buffer starts in gained state.
223
224 // Acquire, release, and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700225 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700226 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
227 EXPECT_EQ(-EALREADY, p->Gain(&fence));
228
229 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700230 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700231
232 // Post, release, and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700233 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700234 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
235 EXPECT_EQ(-EBUSY, p->Gain(&fence));
236
237 // Acquire in posted state should succeed.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700238 EXPECT_LE(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700239
240 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700241 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700242 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700243 EXPECT_EQ(-EBUSY, p->Gain(&fence));
244
245 // Release in acquired state should succeed.
246 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800247 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700248
249 // Release, acquire, and post in released state should fail.
250 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
Tianyu Jiangee723f52018-10-24 16:37:38 -0700251 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700252 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700253
254 // Gain in released state should succeed.
255 EXPECT_EQ(0, p->Gain(&fence));
256
257 // Acquire, release, and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700258 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700259 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
260 EXPECT_EQ(-EALREADY, p->Gain(&fence));
261}
262
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700263TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700264 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
266 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700267 std::unique_ptr<ConsumerBuffer> c =
268 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700269 ASSERT_TRUE(c.get() != nullptr);
270
271 DvrNativeBufferMetadata metadata;
272 LocalHandle invalid_fence;
273
274 // The producer buffer starts in gained state.
275
276 // Acquire, release, and gain in gained state should fail.
277 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
278 EXPECT_FALSE(invalid_fence.IsValid());
279 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
280 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
281 EXPECT_FALSE(invalid_fence.IsValid());
282
283 // Post in gained state should succeed.
284 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
285 EXPECT_EQ(p->buffer_state(), c->buffer_state());
286 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
287
288 // Post, release, and gain in posted state should fail.
289 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
290 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
291 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
292 EXPECT_FALSE(invalid_fence.IsValid());
293
294 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800295 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700296 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
297 EXPECT_FALSE(invalid_fence.IsValid());
298 EXPECT_EQ(p->buffer_state(), c->buffer_state());
299 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
300
301 // Acquire, post, and gain in acquired state should fail.
302 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
303 EXPECT_FALSE(invalid_fence.IsValid());
304 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
305 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
306 EXPECT_FALSE(invalid_fence.IsValid());
307
308 // Release in acquired state should succeed.
309 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800310 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700311 EXPECT_EQ(p->buffer_state(), c->buffer_state());
312 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
313
314 // Release, acquire, and post in released state should fail.
315 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
316 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
317 EXPECT_FALSE(invalid_fence.IsValid());
318 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
319
320 // Gain in released state should succeed.
321 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
322 EXPECT_FALSE(invalid_fence.IsValid());
323 EXPECT_EQ(p->buffer_state(), c->buffer_state());
324 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
325
326 // Acquire, release, and gain in gained state should fail.
327 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
328 EXPECT_FALSE(invalid_fence.IsValid());
329 EXPECT_EQ(-EBUSY, c->ReleaseAsync(&metadata, invalid_fence));
330 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
331 EXPECT_FALSE(invalid_fence.IsValid());
332}
333
Tianyu5465d6c2018-08-14 13:03:10 -0700334TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
335 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
336 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
337 ASSERT_TRUE(p.get() != nullptr);
338
339 // The producer buffer starts in gained state. Post the buffer.
340 ASSERT_EQ(0, p->Post(LocalHandle()));
341
342 // Gain in posted state should only succeed with gain_posted_buffer = true.
343 LocalHandle invalid_fence;
344 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
345 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
346}
347
348TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
349 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
350 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
351 ASSERT_TRUE(p.get() != nullptr);
352
353 // The producer buffer starts in gained state. Post the buffer.
354 ASSERT_EQ(0, p->Post(LocalHandle()));
355
356 // GainAsync in posted state should only succeed with gain_posted_buffer
357 // equals true.
358 DvrNativeBufferMetadata metadata;
359 LocalHandle invalid_fence;
360 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
361 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
362}
363
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700364TEST_F(LibBufferHubTest, TestZeroConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700365 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700366 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
367 ASSERT_TRUE(p.get() != nullptr);
368
369 DvrNativeBufferMetadata metadata;
370 LocalHandle invalid_fence;
371
372 // Newly created.
373 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
374 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
375 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
376
377 // The buffer should stay in posted stay until a consumer picks it up.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800378 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700379
380 // A new consumer should still be able to acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700381 std::unique_ptr<ConsumerBuffer> c =
382 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700383 ASSERT_TRUE(c.get() != nullptr);
384 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
385 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
386}
387
388TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700389 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700390 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
391 ASSERT_TRUE(p.get() != nullptr);
392
Tianyu1a60bb42018-10-08 14:56:08 -0700393 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700394 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700395 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700396 ASSERT_TRUE(cs[i].get() != nullptr);
397 EXPECT_TRUE(IsBufferGained(cs[i]->buffer_state()));
398 }
399
400 DvrNativeBufferMetadata metadata;
401 LocalHandle invalid_fence;
402
403 // Post the producer should trigger all consumers to be available.
404 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
405 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
406 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700407 EXPECT_TRUE(
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700408 IsBufferPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800409 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700410 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
411 EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
412 }
413
414 // All consumers have to release before the buffer is considered to be
415 // released.
416 for (size_t i = 0; i < kMaxConsumerCount; i++) {
417 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
418 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
419 }
420
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800421 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700422 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
423
424 // Buffer state cross all clients must be consistent.
425 for (size_t i = 0; i < kMaxConsumerCount; i++) {
426 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
427 }
428}
429
430TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700431 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700432 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
433 ASSERT_TRUE(p.get() != nullptr);
434 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
435
Tianyu1a60bb42018-10-08 14:56:08 -0700436 std::unique_ptr<ConsumerBuffer> c =
437 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700438 ASSERT_TRUE(c.get() != nullptr);
439 EXPECT_TRUE(IsBufferGained(c->buffer_state()));
440
441 DvrNativeBufferMetadata metadata;
442 LocalHandle invalid_fence;
443
444 // Post the gained buffer should signal already created consumer.
445 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
446 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800447 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700448 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
449 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
450}
451
452TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferPosted) {
Tianyu1a60bb42018-10-08 14:56:08 -0700453 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700454 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
455 ASSERT_TRUE(p.get() != nullptr);
456 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
457
458 DvrNativeBufferMetadata metadata;
459 LocalHandle invalid_fence;
460
461 // Post the gained buffer before any consumer gets created.
462 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
463 EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
464
465 // Newly created consumer should be automatically sigalled.
Tianyu1a60bb42018-10-08 14:56:08 -0700466 std::unique_ptr<ConsumerBuffer> c =
467 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700468 ASSERT_TRUE(c.get() != nullptr);
469 EXPECT_TRUE(IsBufferPosted(c->buffer_state()));
470 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
471 EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
472}
473
474TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700475 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700476 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
477 ASSERT_TRUE(p.get() != nullptr);
478
Tianyu1a60bb42018-10-08 14:56:08 -0700479 std::unique_ptr<ConsumerBuffer> c1 =
480 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700481 ASSERT_TRUE(c1.get() != nullptr);
482
483 DvrNativeBufferMetadata metadata;
484 LocalHandle invalid_fence;
485
486 // Post, acquire, and release the buffer..
487 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800488 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700489 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
490 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
491
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800492 // Note that the next PDX call is on the producer channel, which may be
493 // executed before Release impulse gets executed by bufferhubd. Thus, here we
494 // need to wait until the releasd is confirmed before creating another
495 // consumer.
496 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
497 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
498
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700499 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800500 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700501 std::unique_ptr<ConsumerBuffer> c2 =
502 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700503 ASSERT_TRUE(c2.get() != nullptr);
504
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700505 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
506 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
507 EXPECT_TRUE(IsBufferGained(p->buffer_state()));
508}
509
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800510TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
511 struct Metadata {
512 int64_t field1;
513 int64_t field2;
514 };
Tianyu1a60bb42018-10-08 14:56:08 -0700515 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800516 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
517 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700518 std::unique_ptr<ConsumerBuffer> c =
519 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800520 ASSERT_TRUE(c.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800521 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700522 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800523 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800524 LocalHandle fence;
525 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700526 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800527 EXPECT_EQ(m.field1, m2.field1);
528 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800529 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800530 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800531}
532
533TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
534 struct Metadata {
535 int64_t field1;
536 int64_t field2;
537 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700538 struct OverSizedMetadata {
539 int64_t field1;
540 int64_t field2;
541 int64_t field3;
542 };
Tianyu1a60bb42018-10-08 14:56:08 -0700543 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800544 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
545 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700546 std::unique_ptr<ConsumerBuffer> c =
547 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800548 ASSERT_TRUE(c.get() != nullptr);
549
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700550 // It is illegal to post metadata larger than originally requested during
551 // buffer allocation.
552 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700553 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800554 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700555
556 // It is ok to post metadata smaller than originally requested during
557 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700558 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800559}
560
561TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
562 struct Metadata {
563 int64_t field1;
564 int64_t field2;
565 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700566 struct OverSizedMetadata {
567 int64_t field1;
568 int64_t field2;
569 int64_t field3;
570 };
Tianyu1a60bb42018-10-08 14:56:08 -0700571 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800572 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
573 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700574 std::unique_ptr<ConsumerBuffer> c =
575 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800576 ASSERT_TRUE(c.get() != nullptr);
577
578 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700579 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800580
581 LocalHandle fence;
582 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700583 OverSizedMetadata e;
584
585 // It is illegal to acquire metadata larger than originally requested during
586 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700587 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700588
589 // It is ok to acquire metadata smaller than originally requested during
590 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700591 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700592 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800593}
594
595TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700596 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
598 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700599 std::unique_ptr<ConsumerBuffer> c =
600 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800601 ASSERT_TRUE(c.get() != nullptr);
602
603 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700604 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800605
606 LocalHandle fence;
607 EXPECT_EQ(0, c->Acquire(&fence));
608}
609
610TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700611 std::unique_ptr<ProducerBuffer> p =
612 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800613 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700614 std::unique_ptr<ConsumerBuffer> c =
615 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800616 ASSERT_TRUE(c.get() != nullptr);
617
618 LocalHandle fence;
619
Tianyue6e08ab2018-09-13 18:48:55 -0700620 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800621 EXPECT_EQ(0, c->Acquire(&fence));
622}
623
624TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700625 std::unique_ptr<ProducerBuffer> p =
626 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800627 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700628 std::unique_ptr<ConsumerBuffer> c =
629 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800630 ASSERT_TRUE(c.get() != nullptr);
631
632 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700633 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800634}
635
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700636namespace {
637
638int PollFd(int fd, int timeout_ms) {
639 pollfd p = {fd, POLLIN, 0};
640 return poll(&p, 1, timeout_ms);
641}
642
643} // namespace
644
645TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700646 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700647 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
648 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700649 std::unique_ptr<ConsumerBuffer> c =
650 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700651 ASSERT_TRUE(c.get() != nullptr);
652
653 DvrNativeBufferMetadata meta;
654 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
655
656 // Post with unsignaled fence.
657 EXPECT_EQ(0, p->PostAsync(&meta, f1));
658
659 // Should acquire a valid fence.
660 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800661 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700662 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
663 EXPECT_TRUE(f2.IsValid());
664 // The original fence and acquired fence should have different fd number.
665 EXPECT_NE(f1.Get(), f2.Get());
666 EXPECT_GE(0, PollFd(f2.Get(), 0));
667
668 // Signal the original fence will trigger the new fence.
669 eventfd_write(f1.Get(), 1);
670 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800671 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700672
673 // Release the consumer with an invalid fence.
674 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
675
676 // Should gain an invalid fence.
677 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800678 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700679 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
680 EXPECT_FALSE(f3.IsValid());
681
682 // Post with a signaled fence.
683 EXPECT_EQ(0, p->PostAsync(&meta, f1));
684
685 // Should acquire a valid fence and it's already signalled.
686 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800687 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700688 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
689 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800690 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700691
692 // Release with an unsignalled fence and signal it immediately after release
693 // without producer gainning.
694 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
695 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
696 eventfd_write(f5.Get(), 1);
697
698 // Should gain a valid fence, which is already signaled.
699 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800700 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
702 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800703 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700704}
705
706TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700707 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700708 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
709 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700710 std::unique_ptr<ConsumerBuffer> c1 =
711 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700712 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700713 const uint64_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700714
715 DvrNativeBufferMetadata meta;
716 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
717
718 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800719 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700720 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
721 // Destroy the consumer now will make it orphaned and the buffer is still
722 // acquired.
723 c1 = nullptr;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800724 EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725
Tianyu1a60bb42018-10-08 14:56:08 -0700726 std::unique_ptr<ConsumerBuffer> c2 =
727 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700728 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700729 const uint64_t client_state_mask2 = c2->client_state_mask();
730 EXPECT_NE(client_state_mask1, client_state_mask2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700731
732 // The new consumer is available for acquire.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800733 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700734 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
735 // Releasing the consumer makes the buffer gainable.
736 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
737
738 // The buffer is now available for the producer to gain.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800739 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700740
741 // But if another consumer is created in released state.
Tianyu1a60bb42018-10-08 14:56:08 -0700742 std::unique_ptr<ConsumerBuffer> c3 =
743 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700744 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700745 const uint64_t client_state_mask3 = c3->client_state_mask();
746 EXPECT_NE(client_state_mask2, client_state_mask3);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700747 // The consumer buffer is not acquirable.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800748 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700749 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
750
751 // Producer should be able to gain no matter what.
752 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
753}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700754
755TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700756 // TODO(b/112338294) rewrite test after migration
757 return;
758
Tianyu1a60bb42018-10-08 14:56:08 -0700759 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700760 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700761 std::unique_ptr<ConsumerBuffer> c =
762 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700763 ASSERT_TRUE(p.get() != nullptr);
764 ASSERT_TRUE(c.get() != nullptr);
765
766 DvrNativeBufferMetadata metadata;
767 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700768 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700769
770 // Detach in posted state should fail.
771 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
772 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
773 auto s1 = p->Detach();
774 EXPECT_FALSE(s1);
775
776 // Detach in acquired state should fail.
777 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
778 s1 = p->Detach();
779 EXPECT_FALSE(s1);
780
781 // Detach in released state should fail.
782 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
783 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
784 s1 = p->Detach();
785 EXPECT_FALSE(s1);
786
787 // Detach in gained state should succeed.
788 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
789 s1 = p->Detach();
790 EXPECT_TRUE(s1);
791
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700792 LocalChannelHandle handle = s1.take();
793 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700794
795 // Both producer and consumer should have hangup.
796 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
797 auto s2 = p->GetEventMask(POLLHUP);
798 EXPECT_TRUE(s2);
799 EXPECT_EQ(s2.get(), POLLHUP);
800
801 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
802 s2 = p->GetEventMask(POLLHUP);
803 EXPECT_TRUE(s2);
804 EXPECT_EQ(s2.get(), POLLHUP);
805
806 auto s3 = p->CreateConsumer();
807 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700808 // Note that here the expected error code is EOPNOTSUPP as the socket towards
809 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700810 EXPECT_EQ(s3.error(), EOPNOTSUPP);
811
812 s3 = c->CreateConsumer();
813 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700814 // Note that here the expected error code is EPIPE returned from
815 // ConsumerChannel::HandleMessage as the socket is still open but the producer
816 // is gone.
817 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700818
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700819 // Detached buffer handle can be use to construct a new BufferHubBuffer
820 // object.
821 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700822 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700823 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700824 EXPECT_TRUE(d->IsValid());
825
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700826 EXPECT_EQ(d->id(), p_id);
827}
828
Tianyub61df912018-10-16 14:55:39 -0700829TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
830 // Buffer Creation will fail: BLOB format requires height to be 1.
831 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
832 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
833 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700834
Tianyub61df912018-10-16 14:55:39 -0700835 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700836 EXPECT_FALSE(b1->IsValid());
837
Tianyub61df912018-10-16 14:55:39 -0700838 // Buffer Creation will fail: user metadata size too large.
839 auto b2 = BufferHubBuffer::Create(
840 kWidth, kHeight, kLayerCount, kFormat, kUsage,
841 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700842
Tianyub61df912018-10-16 14:55:39 -0700843 EXPECT_FALSE(b2->IsConnected());
844 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700845
Tianyub61df912018-10-16 14:55:39 -0700846 // Buffer Creation will fail: user metadata size too large.
847 auto b3 = BufferHubBuffer::Create(
848 kWidth, kHeight, kLayerCount, kFormat, kUsage,
849 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
850 kMetadataHeaderSize);
851
852 EXPECT_FALSE(b3->IsConnected());
853 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700854}
855
Tianyub61df912018-10-16 14:55:39 -0700856TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
857 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
858 kUsage, kUserMetadataSize);
859 EXPECT_TRUE(b1->IsConnected());
860 EXPECT_TRUE(b1->IsValid());
861 EXPECT_NE(b1->id(), 0);
862}
863
864TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700865 // TODO(b/112338294) rewrite test after migration
866 return;
867
Tianyu1a60bb42018-10-08 14:56:08 -0700868 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700869 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
870 ASSERT_TRUE(p1.get() != nullptr);
871 int p1_id = p1->id();
872
873 // Detached the producer.
874 auto status_or_handle = p1->Detach();
875 EXPECT_TRUE(status_or_handle.ok());
876 LocalChannelHandle h1 = status_or_handle.take();
877 EXPECT_TRUE(h1.valid());
878
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700879 // Detached buffer handle can be use to construct a new BufferHubBuffer
880 // object.
881 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700882 EXPECT_FALSE(h1.valid());
883 EXPECT_TRUE(b1->IsValid());
884 int b1_id = b1->id();
885 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700886}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700887
Tianyub61df912018-10-16 14:55:39 -0700888TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
889 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
890 kUsage, kUserMetadataSize);
891 int b1_id = b1->id();
892 EXPECT_TRUE(b1->IsValid());
893 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
894
895 auto status_or_handle = b1->Duplicate();
896 EXPECT_TRUE(status_or_handle);
897
898 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700899 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700900 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700901
Tianyub61df912018-10-16 14:55:39 -0700902 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700903 LocalChannelHandle h2 = status_or_handle.take();
904 EXPECT_TRUE(h2.valid());
905
Tianyub61df912018-10-16 14:55:39 -0700906 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700907 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700908 ASSERT_TRUE(b2 != nullptr);
909 EXPECT_TRUE(b2->IsValid());
910 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700911
Tianyub61df912018-10-16 14:55:39 -0700912 int b2_id = b2->id();
913
914 // These two buffer instances are based on the same physical buffer under the
915 // hood, so they should share the same id.
916 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700917 // We use client_state_mask() to tell those two instances apart.
918 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
919 EXPECT_NE(b1->client_state_mask(), 0ULL);
920 EXPECT_NE(b2->client_state_mask(), 0ULL);
921 EXPECT_NE(b1->client_state_mask(), kProducerStateBit);
922 EXPECT_NE(b2->client_state_mask(), kProducerStateBit);
Tianyub61df912018-10-16 14:55:39 -0700923
924 // Both buffer instances should be in gained state.
925 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
926 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
927
928 // TODO(b/112338294) rewrite test after migration
929 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700930}