blob: a47a98f3b6b7f704435609c3ac3a1602c4bb16fa [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>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07003#include <private/dvr/bufferhub_rpc.h>
Tianyu Jiang49642322018-12-18 11:08:03 -08004#include <private/dvr/consumer_buffer.h>
5#include <private/dvr/producer_buffer.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07006#include <sys/epoll.h>
7#include <sys/eventfd.h>
Tianyu Jiang7359dc92018-12-13 11:22:28 -08008#include <ui/BufferHubDefs.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
Tianyu Jiang7359dc92018-12-13 11:22:28 -080022using android::BufferHubDefs::AnyClientAcquired;
23using android::BufferHubDefs::AnyClientGained;
24using android::BufferHubDefs::AnyClientPosted;
Tianyu Jiang7359dc92018-12-13 11:22:28 -080025using android::BufferHubDefs::IsClientAcquired;
26using android::BufferHubDefs::IsClientPosted;
27using android::BufferHubDefs::IsClientReleased;
28using android::BufferHubDefs::kFirstClientBitMask;
Tianyu1a60bb42018-10-08 14:56:08 -070029using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070030using android::dvr::ProducerBuffer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080031using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070032using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080033
34const int kWidth = 640;
35const int kHeight = 480;
36const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
37const int kUsage = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070038// Maximum number of consumers for the buffer that only has one producer in the
39// test.
40const size_t kMaxConsumerCount =
Tianyu Jiang7359dc92018-12-13 11:22:28 -080041 android::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080042const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080043
44using LibBufferHubTest = ::testing::Test;
45
46TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070047 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080048 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
49 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070050 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070051 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070052 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080053 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070054 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070055 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080056 ASSERT_TRUE(c2.get() != nullptr);
57
Tianyuf669f6a2018-10-10 15:34:32 -070058 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070059 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070060 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
61 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070062
63 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080064 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070065 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080066 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070067
Tianyuf669f6a2018-10-10 15:34:32 -070068 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070069 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070070
71 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080072 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070073 EXPECT_EQ(1, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080074 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080075
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080076 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070077 EXPECT_EQ(0, c1->Acquire(&fence));
78 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080079 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080080
Tianyu58a05a22018-10-10 18:41:27 -070081 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080082 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070083 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084
Tianyuf669f6a2018-10-10 15:34:32 -070085 EXPECT_EQ(0, c1->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080086 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080087 EXPECT_EQ(0, c2->Discard());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080088 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070089
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080091 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070092 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080093 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070094}
95
96TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -070097 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -070098 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
99 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700100 std::unique_ptr<ConsumerBuffer> c =
101 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700102 ASSERT_TRUE(c.get() != nullptr);
103
104 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
105 ASSERT_TRUE(epoll_fd.IsValid());
106
107 epoll_event event;
108 std::array<epoll_event, 64> events;
109
110 auto event_sources = p->GetEventSources();
111 ASSERT_LT(event_sources.size(), events.size());
112
113 for (const auto& event_source : event_sources) {
114 event = {.events = event_source.event_mask | EPOLLET,
115 .data = {.fd = p->event_fd()}};
116 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
117 &event));
118 }
119
120 event_sources = c->GetEventSources();
121 ASSERT_LT(event_sources.size(), events.size());
122
123 for (const auto& event_source : event_sources) {
124 event = {.events = event_source.event_mask | EPOLLET,
125 .data = {.fd = c->event_fd()}};
126 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
127 &event));
128 }
129
130 // No events should be signaled initially.
131 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
132
Tianyuf669f6a2018-10-10 15:34:32 -0700133 // Gain and post the producer and check for consumer signal.
134 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700135 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800136 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
137 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700138 ASSERT_TRUE(events[0].events & EPOLLIN);
139 ASSERT_EQ(c->event_fd(), events[0].data.fd);
140
141 // Save the event bits to translate later.
142 event = events[0];
143
144 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800145 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
146 kPollTimeoutMs));
147 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
148 kPollTimeoutMs));
149 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
150 kPollTimeoutMs));
151 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
152 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700153
154 // Translate the events.
155 auto event_status = c->GetEventMask(event.events);
156 ASSERT_TRUE(event_status);
157 ASSERT_TRUE(event_status.get() & EPOLLIN);
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));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700162}
163
164TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700165 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700166 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
167 ASSERT_TRUE(p.get() != nullptr);
168
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700169 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jianga99f9112018-12-13 18:23:07 -0800170 uint32_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700171 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700172 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700173 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700174 ASSERT_TRUE(cs[i].get() != nullptr);
175 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700176 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
177 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700178 }
Tianyu Jianga99f9112018-12-13 18:23:07 -0800179 EXPECT_EQ(client_state_masks, ~0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700180
181 // The 64th creation will fail with out-of-memory error.
182 auto state = p->CreateConsumer();
183 EXPECT_EQ(state.error(), E2BIG);
184
185 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700186 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700187 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700188 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700189 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700190 ASSERT_TRUE(cs[i].get() != nullptr);
191 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700192 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
193 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700194 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800195}
196
Corey Tabakad53870c2017-07-06 18:04:27 -0700197TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700198 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700199 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
200 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700201 std::unique_ptr<ConsumerBuffer> c =
202 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700203 ASSERT_TRUE(c.get() != nullptr);
204
Corey Tabakad53870c2017-07-06 18:04:27 -0700205 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700206 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700207
Tianyu Jiang60887c92018-11-14 15:52:38 -0800208 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700209 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700210
211 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700212 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700213
Tianyuf669f6a2018-10-10 15:34:32 -0700214 // Post and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700215 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700216 EXPECT_EQ(-EBUSY, p->Gain(&fence));
217
218 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700219 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700220
221 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700222 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700223 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700224 EXPECT_EQ(-EBUSY, p->Gain(&fence));
225
226 // Release in acquired state should succeed.
227 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800228 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700229
Tianyuf669f6a2018-10-10 15:34:32 -0700230 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700231 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700232 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700233
234 // Gain in released state should succeed.
235 EXPECT_EQ(0, p->Gain(&fence));
236
Tianyu Jiang60887c92018-11-14 15:52:38 -0800237 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700238 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700239}
240
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700241TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700242 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700243 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
244 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700245 std::unique_ptr<ConsumerBuffer> c =
246 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700247 ASSERT_TRUE(c.get() != nullptr);
248
249 DvrNativeBufferMetadata metadata;
250 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700251 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700252
Tianyu Jiang60887c92018-11-14 15:52:38 -0800253 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700254 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
255 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700256 EXPECT_FALSE(invalid_fence.IsValid());
257
258 // Post in gained state should succeed.
259 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
260 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700261 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700262
Tianyuf669f6a2018-10-10 15:34:32 -0700263 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700264 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
266 EXPECT_FALSE(invalid_fence.IsValid());
267
268 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800269 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700270 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
271 EXPECT_FALSE(invalid_fence.IsValid());
272 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700273 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700274
275 // Acquire, post, and gain in acquired state should fail.
276 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
277 EXPECT_FALSE(invalid_fence.IsValid());
278 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
279 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
280 EXPECT_FALSE(invalid_fence.IsValid());
281
282 // Release in acquired state should succeed.
283 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800284 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700285 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800286 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700287
Tianyuf669f6a2018-10-10 15:34:32 -0700288 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700289 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
290 EXPECT_FALSE(invalid_fence.IsValid());
291 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
292
293 // Gain in released state should succeed.
294 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
295 EXPECT_FALSE(invalid_fence.IsValid());
296 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700297 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700298
Tianyuf669f6a2018-10-10 15:34:32 -0700299 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700300 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
301 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800302}
303
304TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
305 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
306 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
307 ASSERT_TRUE(p.get() != nullptr);
308
309 ASSERT_EQ(0, p->GainAsync());
310 ASSERT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700311}
312
Tianyu5465d6c2018-08-14 13:03:10 -0700313TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
314 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
315 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
316 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700317 std::unique_ptr<ConsumerBuffer> c =
318 ConsumerBuffer::Import(p->CreateConsumer());
319 ASSERT_TRUE(c.get() != nullptr);
320 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700321 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700322 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700323
324 // Gain in posted state should only succeed with gain_posted_buffer = true.
325 LocalHandle invalid_fence;
326 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
327 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
328}
329
330TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
331 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
332 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
333 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700334 std::unique_ptr<ConsumerBuffer> c =
335 ConsumerBuffer::Import(p->CreateConsumer());
336 ASSERT_TRUE(c.get() != nullptr);
337 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700338 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700339 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700340
341 // GainAsync in posted state should only succeed with gain_posted_buffer
342 // equals true.
343 DvrNativeBufferMetadata metadata;
344 LocalHandle invalid_fence;
345 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
346 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
347}
348
Tianyuf669f6a2018-10-10 15:34:32 -0700349TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700350 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700351 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
352 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700353 ASSERT_EQ(0, p->GainAsync());
354 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800355 // Producer state bit is in released state after post, other clients shall be
356 // in posted state although there is no consumer of this buffer yet.
357 ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800358 ASSERT_TRUE(p->is_released());
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800359 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700360
Tianyuf669f6a2018-10-10 15:34:32 -0700361 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700362 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700363 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700364}
365
366TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700367 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700368 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
369 ASSERT_TRUE(p.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800370 uint32_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700371
Tianyu1a60bb42018-10-08 14:56:08 -0700372 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700373 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700374 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700375 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800376 EXPECT_TRUE(cs[i]->is_released());
Tianyuf669f6a2018-10-10 15:34:32 -0700377 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700378 }
379
Tianyuf669f6a2018-10-10 15:34:32 -0700380 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700381 DvrNativeBufferMetadata metadata;
382 LocalHandle invalid_fence;
383
384 // Post the producer should trigger all consumers to be available.
385 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700386 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
387 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700388 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700389 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800390 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700391 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700392 EXPECT_TRUE(
393 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700394 }
395
396 // All consumers have to release before the buffer is considered to be
397 // released.
398 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800399 EXPECT_FALSE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700400 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
401 }
402
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800403 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800404 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700405
406 // Buffer state cross all clients must be consistent.
407 for (size_t i = 0; i < kMaxConsumerCount; i++) {
408 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
409 }
410}
411
412TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700413 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700414 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
415 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700416 EXPECT_EQ(0, p->GainAsync());
417 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700418
Tianyu1a60bb42018-10-08 14:56:08 -0700419 std::unique_ptr<ConsumerBuffer> c =
420 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700421 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700422 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700423
424 DvrNativeBufferMetadata metadata;
425 LocalHandle invalid_fence;
426
427 // Post the gained buffer should signal already created consumer.
428 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700429 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800430 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700431 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700432 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700433}
434
Tianyuf669f6a2018-10-10 15:34:32 -0700435TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700436 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700437 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
438 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700439 EXPECT_EQ(0, p->GainAsync());
440 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700441
442 DvrNativeBufferMetadata metadata;
443 LocalHandle invalid_fence;
444
445 // Post the gained buffer before any consumer gets created.
446 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800447 EXPECT_TRUE(p->is_released());
Tianyuf669f6a2018-10-10 15:34:32 -0700448 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700449
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800450 // Newly created consumer will be signalled for the posted buffer although it
451 // is created after producer posting.
Tianyu1a60bb42018-10-08 14:56:08 -0700452 std::unique_ptr<ConsumerBuffer> c =
453 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700454 ASSERT_TRUE(c.get() != nullptr);
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800455 EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700456 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700457}
458
459TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700460 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700461 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
462 ASSERT_TRUE(p.get() != nullptr);
463
Tianyu1a60bb42018-10-08 14:56:08 -0700464 std::unique_ptr<ConsumerBuffer> c1 =
465 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700466 ASSERT_TRUE(c1.get() != nullptr);
467
Tianyuf669f6a2018-10-10 15:34:32 -0700468 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700469 DvrNativeBufferMetadata metadata;
470 LocalHandle invalid_fence;
471
472 // Post, acquire, and release the buffer..
473 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800474 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700475 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
476 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
477
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800478 // Note that the next PDX call is on the producer channel, which may be
479 // executed before Release impulse gets executed by bufferhubd. Thus, here we
480 // need to wait until the releasd is confirmed before creating another
481 // consumer.
482 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800483 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800484
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700485 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800486 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700487 std::unique_ptr<ConsumerBuffer> c2 =
488 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700489 ASSERT_TRUE(c2.get() != nullptr);
490
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800491 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700492 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700493 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700494}
495
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800496TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
497 struct Metadata {
498 int64_t field1;
499 int64_t field2;
500 };
Tianyu1a60bb42018-10-08 14:56:08 -0700501 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800502 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
503 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700504 std::unique_ptr<ConsumerBuffer> c =
505 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800506 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700507 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800508 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700509 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800510 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800511 LocalHandle fence;
512 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700513 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800514 EXPECT_EQ(m.field1, m2.field1);
515 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800516 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800517 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800518}
519
520TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
521 struct Metadata {
522 int64_t field1;
523 int64_t field2;
524 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700525 struct OverSizedMetadata {
526 int64_t field1;
527 int64_t field2;
528 int64_t field3;
529 };
Tianyu1a60bb42018-10-08 14:56:08 -0700530 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800531 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
532 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700533 std::unique_ptr<ConsumerBuffer> c =
534 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800535 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700536 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800537
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700538 // It is illegal to post metadata larger than originally requested during
539 // buffer allocation.
540 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700541 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800542 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700543
544 // It is ok to post metadata smaller than originally requested during
545 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700546 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800547}
548
549TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
550 struct Metadata {
551 int64_t field1;
552 int64_t field2;
553 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700554 struct OverSizedMetadata {
555 int64_t field1;
556 int64_t field2;
557 int64_t field3;
558 };
Tianyu1a60bb42018-10-08 14:56:08 -0700559 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800560 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
561 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700562 std::unique_ptr<ConsumerBuffer> c =
563 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800564 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700565 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800566
567 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700568 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569
570 LocalHandle fence;
571 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700572 OverSizedMetadata e;
573
574 // It is illegal to acquire metadata larger than originally requested during
575 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700576 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700577
578 // It is ok to acquire metadata smaller than originally requested during
579 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700580 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700581 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800582}
583
584TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700585 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800586 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
587 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700588 std::unique_ptr<ConsumerBuffer> c =
589 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800590 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700591 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800592
593 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700594 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800595
596 LocalHandle fence;
597 EXPECT_EQ(0, c->Acquire(&fence));
598}
599
600TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700601 std::unique_ptr<ProducerBuffer> p =
602 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800603 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700604 std::unique_ptr<ConsumerBuffer> c =
605 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800606 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700607 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800608
609 LocalHandle fence;
610
Tianyue6e08ab2018-09-13 18:48:55 -0700611 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800612 EXPECT_EQ(0, c->Acquire(&fence));
613}
614
615TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700616 std::unique_ptr<ProducerBuffer> p =
617 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800618 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700619 std::unique_ptr<ConsumerBuffer> c =
620 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800621 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700622 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800623
624 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700625 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800626}
627
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700628namespace {
629
630int PollFd(int fd, int timeout_ms) {
631 pollfd p = {fd, POLLIN, 0};
632 return poll(&p, 1, timeout_ms);
633}
634
635} // namespace
636
637TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700638 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700639 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
640 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700641 std::unique_ptr<ConsumerBuffer> c =
642 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700643 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700644 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700645
646 DvrNativeBufferMetadata meta;
647 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
648
649 // Post with unsignaled fence.
650 EXPECT_EQ(0, p->PostAsync(&meta, f1));
651
652 // Should acquire a valid fence.
653 LocalHandle f2;
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, &f2));
656 EXPECT_TRUE(f2.IsValid());
657 // The original fence and acquired fence should have different fd number.
658 EXPECT_NE(f1.Get(), f2.Get());
659 EXPECT_GE(0, PollFd(f2.Get(), 0));
660
661 // Signal the original fence will trigger the new fence.
662 eventfd_write(f1.Get(), 1);
663 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800664 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700665
666 // Release the consumer with an invalid fence.
667 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
668
669 // Should gain an invalid fence.
670 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800671 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700672 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
673 EXPECT_FALSE(f3.IsValid());
674
675 // Post with a signaled fence.
676 EXPECT_EQ(0, p->PostAsync(&meta, f1));
677
678 // Should acquire a valid fence and it's already signalled.
679 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800680 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700681 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
682 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800683 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700684
685 // Release with an unsignalled fence and signal it immediately after release
686 // without producer gainning.
687 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
688 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
689 eventfd_write(f5.Get(), 1);
690
691 // Should gain a valid fence, which is already signaled.
692 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800693 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700694 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
695 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800696 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700697}
698
699TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700700 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
702 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700703 std::unique_ptr<ConsumerBuffer> c1 =
704 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700705 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800706 const uint32_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700707
Tianyuf669f6a2018-10-10 15:34:32 -0700708 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700709 DvrNativeBufferMetadata meta;
710 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
711
712 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800713 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700714 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700715
Tianyuf669f6a2018-10-10 15:34:32 -0700716 // Destroy the consumer who has acquired but not released the buffer.
717 c1 = nullptr;
718
719 // The buffer is now available for the producer to gain.
720 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
721
722 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700723 std::unique_ptr<ConsumerBuffer> c2 =
724 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800726 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700727 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700728 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
729 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700730
Tianyuf669f6a2018-10-10 15:34:32 -0700731 // Producer should be able to gain.
732 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
733}
734
735TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
736 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
737 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
738 ASSERT_TRUE(p.get() != nullptr);
739 std::unique_ptr<ConsumerBuffer> c1 =
740 ConsumerBuffer::Import(p->CreateConsumer());
741 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800742 const uint32_t client_state_mask1 = c1->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700743
744 EXPECT_EQ(0, p->GainAsync());
745 DvrNativeBufferMetadata meta;
746 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
747 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
748
749 // c2 is created when the buffer is in posted state. buffer state for c1 is
750 // posted. Thus, c2 should be automatically set to posted and able to acquire.
751 std::unique_ptr<ConsumerBuffer> c2 =
752 ConsumerBuffer::Import(p->CreateConsumer());
753 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800754 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700755 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800756 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700757 LocalHandle invalid_fence;
758 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700759
Tianyuf669f6a2018-10-10 15:34:32 -0700760 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700761
Tianyuf669f6a2018-10-10 15:34:32 -0700762 // c3 is created when the buffer is in acquired state. buffer state for c1 and
763 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
764 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700765 std::unique_ptr<ConsumerBuffer> c3 =
766 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700767 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800768 const uint32_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700769 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700770 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700771 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
772 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700773
Tianyuf669f6a2018-10-10 15:34:32 -0700774 // Releasing c2 and c3 in normal ways.
775 EXPECT_EQ(0, c2->Release(LocalHandle()));
776 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
777
778 // Destroy the c1 who has not released the buffer.
779 c1 = nullptr;
780
781 // The buffer is now available for the producer to gain.
782 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
783
784 // C4 is created in released state. Thus, it cannot gain the just posted
785 // buffer.
786 std::unique_ptr<ConsumerBuffer> c4 =
787 ConsumerBuffer::Import(p->CreateConsumer());
788 ASSERT_TRUE(c4.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800789 const uint32_t client_state_mask4 = c4->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700790 EXPECT_NE(client_state_mask3, client_state_mask4);
791 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
792 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
793
794 // Producer should be able to gain.
795 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700796}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700797
798TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700799 // TODO(b/112338294) rewrite test after migration
800 return;
801
Fan Xu021776e2018-12-05 13:34:48 -0800802 /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700803 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700804 std::unique_ptr<ConsumerBuffer> c =
805 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700806 ASSERT_TRUE(p.get() != nullptr);
807 ASSERT_TRUE(c.get() != nullptr);
808
809 DvrNativeBufferMetadata metadata;
810 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700811 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700812
813 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700814 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700815 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
816 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
817 auto s1 = p->Detach();
818 EXPECT_FALSE(s1);
819
820 // Detach in acquired state should fail.
821 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
822 s1 = p->Detach();
823 EXPECT_FALSE(s1);
824
825 // Detach in released state should fail.
826 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
827 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
828 s1 = p->Detach();
829 EXPECT_FALSE(s1);
830
831 // Detach in gained state should succeed.
832 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
833 s1 = p->Detach();
834 EXPECT_TRUE(s1);
835
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700836 LocalChannelHandle handle = s1.take();
837 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700838
839 // Both producer and consumer should have hangup.
840 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
841 auto s2 = p->GetEventMask(POLLHUP);
842 EXPECT_TRUE(s2);
843 EXPECT_EQ(s2.get(), POLLHUP);
844
845 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
846 s2 = p->GetEventMask(POLLHUP);
847 EXPECT_TRUE(s2);
848 EXPECT_EQ(s2.get(), POLLHUP);
849
850 auto s3 = p->CreateConsumer();
851 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700852 // Note that here the expected error code is EOPNOTSUPP as the socket towards
853 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700854 EXPECT_EQ(s3.error(), EOPNOTSUPP);
855
856 s3 = c->CreateConsumer();
857 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700858 // Note that here the expected error code is EPIPE returned from
859 // ConsumerChannel::HandleMessage as the socket is still open but the producer
860 // is gone.
861 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700862
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700863 // Detached buffer handle can be use to construct a new BufferHubBuffer
864 // object.
865 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700866 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700867 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700868 EXPECT_TRUE(d->IsValid());
869
Fan Xu021776e2018-12-05 13:34:48 -0800870 EXPECT_EQ(d->id(), p_id); */
Tianyub61df912018-10-16 14:55:39 -0700871}
872
873TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700874 // TODO(b/112338294) rewrite test after migration
875 return;
876
Fan Xu021776e2018-12-05 13:34:48 -0800877 /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700878 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
879 ASSERT_TRUE(p1.get() != nullptr);
880 int p1_id = p1->id();
881
Tianyuf669f6a2018-10-10 15:34:32 -0700882 // Detached the producer from gained state.
883 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700884 auto status_or_handle = p1->Detach();
885 EXPECT_TRUE(status_or_handle.ok());
886 LocalChannelHandle h1 = status_or_handle.take();
887 EXPECT_TRUE(h1.valid());
888
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700889 // Detached buffer handle can be use to construct a new BufferHubBuffer
890 // object.
891 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700892 EXPECT_FALSE(h1.valid());
893 EXPECT_TRUE(b1->IsValid());
894 int b1_id = b1->id();
Fan Xu021776e2018-12-05 13:34:48 -0800895 EXPECT_EQ(b1_id, p1_id); */
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700896}