blob: ed5a992f3c54ed94ec3f223115ea6b0fd98d3ad7 [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;
25using android::BufferHubDefs::IsBufferReleased;
26using android::BufferHubDefs::IsClientAcquired;
27using android::BufferHubDefs::IsClientPosted;
28using android::BufferHubDefs::IsClientReleased;
29using android::BufferHubDefs::kFirstClientBitMask;
Tianyu1a60bb42018-10-08 14:56:08 -070030using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070031using android::dvr::ProducerBuffer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080032using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070033using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080034
35const int kWidth = 640;
36const int kHeight = 480;
37const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
38const int kUsage = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070039// Maximum number of consumers for the buffer that only has one producer in the
40// test.
41const size_t kMaxConsumerCount =
Tianyu Jiang7359dc92018-12-13 11:22:28 -080042 android::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080043const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080044
45using LibBufferHubTest = ::testing::Test;
46
47TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070048 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080049 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
50 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070051 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070052 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070053 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080054 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070055 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070056 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057 ASSERT_TRUE(c2.get() != nullptr);
58
Tianyuf669f6a2018-10-10 15:34:32 -070059 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070060 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070061 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
62 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070063
64 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080065 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070066 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080067 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070068
Tianyuf669f6a2018-10-10 15:34:32 -070069 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070070 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070071
72 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080073 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070074 EXPECT_EQ(1, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080075 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080076
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080077 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070078 EXPECT_EQ(0, c1->Acquire(&fence));
79 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080080 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081
Tianyu58a05a22018-10-10 18:41:27 -070082 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080083 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070084 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080085
Tianyuf669f6a2018-10-10 15:34:32 -070086 EXPECT_EQ(0, c1->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080087 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088 EXPECT_EQ(0, c2->Discard());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080089 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070090
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080091 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080092 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070093 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080094 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070095}
96
97TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -070098 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -070099 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
100 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700101 std::unique_ptr<ConsumerBuffer> c =
102 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700103 ASSERT_TRUE(c.get() != nullptr);
104
105 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
106 ASSERT_TRUE(epoll_fd.IsValid());
107
108 epoll_event event;
109 std::array<epoll_event, 64> events;
110
111 auto event_sources = p->GetEventSources();
112 ASSERT_LT(event_sources.size(), events.size());
113
114 for (const auto& event_source : event_sources) {
115 event = {.events = event_source.event_mask | EPOLLET,
116 .data = {.fd = p->event_fd()}};
117 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
118 &event));
119 }
120
121 event_sources = c->GetEventSources();
122 ASSERT_LT(event_sources.size(), events.size());
123
124 for (const auto& event_source : event_sources) {
125 event = {.events = event_source.event_mask | EPOLLET,
126 .data = {.fd = c->event_fd()}};
127 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
128 &event));
129 }
130
131 // No events should be signaled initially.
132 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
133
Tianyuf669f6a2018-10-10 15:34:32 -0700134 // Gain and post the producer and check for consumer signal.
135 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700136 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800137 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
138 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700139 ASSERT_TRUE(events[0].events & EPOLLIN);
140 ASSERT_EQ(c->event_fd(), events[0].data.fd);
141
142 // Save the event bits to translate later.
143 event = events[0];
144
145 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800146 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
147 kPollTimeoutMs));
148 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
149 kPollTimeoutMs));
150 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
151 kPollTimeoutMs));
152 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
153 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700154
155 // Translate the events.
156 auto event_status = c->GetEventMask(event.events);
157 ASSERT_TRUE(event_status);
158 ASSERT_TRUE(event_status.get() & EPOLLIN);
159
160 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800161 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
162 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700163}
164
165TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700166 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700167 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
168 ASSERT_TRUE(p.get() != nullptr);
169
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700170 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jianga99f9112018-12-13 18:23:07 -0800171 uint32_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700172 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700173 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700174 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700175 ASSERT_TRUE(cs[i].get() != nullptr);
176 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700177 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
178 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700179 }
Tianyu Jianga99f9112018-12-13 18:23:07 -0800180 EXPECT_EQ(client_state_masks, ~0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700181
182 // The 64th creation will fail with out-of-memory error.
183 auto state = p->CreateConsumer();
184 EXPECT_EQ(state.error(), E2BIG);
185
186 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700187 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700188 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700189 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700190 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700191 ASSERT_TRUE(cs[i].get() != nullptr);
192 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700193 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
194 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700195 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800196}
197
Corey Tabakad53870c2017-07-06 18:04:27 -0700198TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700199 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700200 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
201 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700202 std::unique_ptr<ConsumerBuffer> c =
203 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700204 ASSERT_TRUE(c.get() != nullptr);
205
Corey Tabakad53870c2017-07-06 18:04:27 -0700206 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700207 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700208
Tianyu Jiang60887c92018-11-14 15:52:38 -0800209 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700210 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700211
212 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700213 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700214
Tianyuf669f6a2018-10-10 15:34:32 -0700215 // Post and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700216 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700217 EXPECT_EQ(-EBUSY, p->Gain(&fence));
218
219 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700220 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700221
222 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700223 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700224 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700225 EXPECT_EQ(-EBUSY, p->Gain(&fence));
226
227 // Release in acquired state should succeed.
228 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800229 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700230
Tianyuf669f6a2018-10-10 15:34:32 -0700231 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700232 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700233 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700234
235 // Gain in released state should succeed.
236 EXPECT_EQ(0, p->Gain(&fence));
237
Tianyu Jiang60887c92018-11-14 15:52:38 -0800238 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700239 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700240}
241
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700242TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700243 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700244 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
245 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700246 std::unique_ptr<ConsumerBuffer> c =
247 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700248 ASSERT_TRUE(c.get() != nullptr);
249
250 DvrNativeBufferMetadata metadata;
251 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700252 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700253
Tianyu Jiang60887c92018-11-14 15:52:38 -0800254 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700255 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
256 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700257 EXPECT_FALSE(invalid_fence.IsValid());
258
259 // Post in gained state should succeed.
260 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
261 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700262 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700263
Tianyuf669f6a2018-10-10 15:34:32 -0700264 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700266 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
267 EXPECT_FALSE(invalid_fence.IsValid());
268
269 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800270 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700271 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
272 EXPECT_FALSE(invalid_fence.IsValid());
273 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700274 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700275
276 // Acquire, post, and gain in acquired state should fail.
277 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
278 EXPECT_FALSE(invalid_fence.IsValid());
279 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
280 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
281 EXPECT_FALSE(invalid_fence.IsValid());
282
283 // Release in acquired state should succeed.
284 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800285 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700286 EXPECT_EQ(p->buffer_state(), c->buffer_state());
287 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
288
Tianyuf669f6a2018-10-10 15:34:32 -0700289 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700290 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
291 EXPECT_FALSE(invalid_fence.IsValid());
292 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
293
294 // Gain in released state should succeed.
295 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
296 EXPECT_FALSE(invalid_fence.IsValid());
297 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700298 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700299
Tianyuf669f6a2018-10-10 15:34:32 -0700300 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700301 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
302 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800303}
304
305TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
306 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
307 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
308 ASSERT_TRUE(p.get() != nullptr);
309
310 ASSERT_EQ(0, p->GainAsync());
311 ASSERT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700312}
313
Tianyu5465d6c2018-08-14 13:03:10 -0700314TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
315 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
316 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
317 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700318 std::unique_ptr<ConsumerBuffer> c =
319 ConsumerBuffer::Import(p->CreateConsumer());
320 ASSERT_TRUE(c.get() != nullptr);
321 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700322 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700323 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700324
325 // Gain in posted state should only succeed with gain_posted_buffer = true.
326 LocalHandle invalid_fence;
327 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
328 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
329}
330
331TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
332 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
333 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
334 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700335 std::unique_ptr<ConsumerBuffer> c =
336 ConsumerBuffer::Import(p->CreateConsumer());
337 ASSERT_TRUE(c.get() != nullptr);
338 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700339 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700340 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700341
342 // GainAsync in posted state should only succeed with gain_posted_buffer
343 // equals true.
344 DvrNativeBufferMetadata metadata;
345 LocalHandle invalid_fence;
346 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
347 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
348}
349
Tianyuf669f6a2018-10-10 15:34:32 -0700350TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700351 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700352 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
353 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700354 ASSERT_EQ(0, p->GainAsync());
355 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800356 // Producer state bit is in released state after post, other clients shall be
357 // in posted state although there is no consumer of this buffer yet.
358 ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
359 ASSERT_FALSE(IsBufferReleased(p->buffer_state()));
360 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700361
Tianyuf669f6a2018-10-10 15:34:32 -0700362 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700363 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700364 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700365}
366
367TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700368 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700369 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
370 ASSERT_TRUE(p.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800371 uint32_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700372
Tianyu1a60bb42018-10-08 14:56:08 -0700373 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700374 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700375 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700376 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700377 EXPECT_TRUE(IsBufferReleased(cs[i]->buffer_state()));
378 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700379 }
380
Tianyuf669f6a2018-10-10 15:34:32 -0700381 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700382 DvrNativeBufferMetadata metadata;
383 LocalHandle invalid_fence;
384
385 // Post the producer should trigger all consumers to be available.
386 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700387 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
388 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700389 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700390 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800391 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700392 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700393 EXPECT_TRUE(
394 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700395 }
396
397 // All consumers have to release before the buffer is considered to be
398 // released.
399 for (size_t i = 0; i < kMaxConsumerCount; i++) {
400 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
401 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
402 }
403
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800404 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700405 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
406
407 // Buffer state cross all clients must be consistent.
408 for (size_t i = 0; i < kMaxConsumerCount; i++) {
409 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
410 }
411}
412
413TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700414 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700415 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
416 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700417 EXPECT_EQ(0, p->GainAsync());
418 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700419
Tianyu1a60bb42018-10-08 14:56:08 -0700420 std::unique_ptr<ConsumerBuffer> c =
421 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700422 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700423 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700424
425 DvrNativeBufferMetadata metadata;
426 LocalHandle invalid_fence;
427
428 // Post the gained buffer should signal already created consumer.
429 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700430 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800431 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700432 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700433 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700434}
435
Tianyuf669f6a2018-10-10 15:34:32 -0700436TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700437 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700438 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
439 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700440 EXPECT_EQ(0, p->GainAsync());
441 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700442
443 DvrNativeBufferMetadata metadata;
444 LocalHandle invalid_fence;
445
446 // Post the gained buffer before any consumer gets created.
447 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800448 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
Tianyuf669f6a2018-10-10 15:34:32 -0700449 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700450
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800451 // Newly created consumer will be signalled for the posted buffer although it
452 // is created after producer posting.
Tianyu1a60bb42018-10-08 14:56:08 -0700453 std::unique_ptr<ConsumerBuffer> c =
454 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700455 ASSERT_TRUE(c.get() != nullptr);
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800456 EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700457 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700458}
459
460TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700461 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700462 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
463 ASSERT_TRUE(p.get() != nullptr);
464
Tianyu1a60bb42018-10-08 14:56:08 -0700465 std::unique_ptr<ConsumerBuffer> c1 =
466 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700467 ASSERT_TRUE(c1.get() != nullptr);
468
Tianyuf669f6a2018-10-10 15:34:32 -0700469 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700470 DvrNativeBufferMetadata metadata;
471 LocalHandle invalid_fence;
472
473 // Post, acquire, and release the buffer..
474 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800475 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700476 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
477 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
478
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800479 // Note that the next PDX call is on the producer channel, which may be
480 // executed before Release impulse gets executed by bufferhubd. Thus, here we
481 // need to wait until the releasd is confirmed before creating another
482 // consumer.
483 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
484 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
485
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700486 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800487 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700488 std::unique_ptr<ConsumerBuffer> c2 =
489 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700490 ASSERT_TRUE(c2.get() != nullptr);
491
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700492 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
493 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700494 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700495}
496
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800497TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
498 struct Metadata {
499 int64_t field1;
500 int64_t field2;
501 };
Tianyu1a60bb42018-10-08 14:56:08 -0700502 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800503 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
504 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700505 std::unique_ptr<ConsumerBuffer> c =
506 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800507 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700508 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800509 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700510 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800511 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800512 LocalHandle fence;
513 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700514 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800515 EXPECT_EQ(m.field1, m2.field1);
516 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800517 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800518 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519}
520
521TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
522 struct Metadata {
523 int64_t field1;
524 int64_t field2;
525 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700526 struct OverSizedMetadata {
527 int64_t field1;
528 int64_t field2;
529 int64_t field3;
530 };
Tianyu1a60bb42018-10-08 14:56:08 -0700531 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800532 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
533 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700534 std::unique_ptr<ConsumerBuffer> c =
535 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800536 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700537 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800538
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700539 // It is illegal to post metadata larger than originally requested during
540 // buffer allocation.
541 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700542 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800543 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700544
545 // It is ok to post metadata smaller than originally requested during
546 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700547 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800548}
549
550TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
551 struct Metadata {
552 int64_t field1;
553 int64_t field2;
554 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700555 struct OverSizedMetadata {
556 int64_t field1;
557 int64_t field2;
558 int64_t field3;
559 };
Tianyu1a60bb42018-10-08 14:56:08 -0700560 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800561 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
562 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700563 std::unique_ptr<ConsumerBuffer> c =
564 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800565 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700566 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800567
568 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700569 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800570
571 LocalHandle fence;
572 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700573 OverSizedMetadata e;
574
575 // It is illegal to acquire metadata larger than originally requested during
576 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700577 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700578
579 // It is ok to acquire metadata smaller than originally requested during
580 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700581 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700582 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800583}
584
585TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700586 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800587 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
588 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700589 std::unique_ptr<ConsumerBuffer> c =
590 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800591 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700592 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800593
594 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700595 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800596
597 LocalHandle fence;
598 EXPECT_EQ(0, c->Acquire(&fence));
599}
600
601TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700602 std::unique_ptr<ProducerBuffer> p =
603 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800604 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700605 std::unique_ptr<ConsumerBuffer> c =
606 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800607 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700608 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800609
610 LocalHandle fence;
611
Tianyue6e08ab2018-09-13 18:48:55 -0700612 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800613 EXPECT_EQ(0, c->Acquire(&fence));
614}
615
616TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700617 std::unique_ptr<ProducerBuffer> p =
618 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800619 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700620 std::unique_ptr<ConsumerBuffer> c =
621 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800622 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700623 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800624
625 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700626 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800627}
628
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700629namespace {
630
631int PollFd(int fd, int timeout_ms) {
632 pollfd p = {fd, POLLIN, 0};
633 return poll(&p, 1, timeout_ms);
634}
635
636} // namespace
637
638TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700639 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700640 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
641 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700642 std::unique_ptr<ConsumerBuffer> c =
643 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700644 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700645 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700646
647 DvrNativeBufferMetadata meta;
648 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
649
650 // Post with unsignaled fence.
651 EXPECT_EQ(0, p->PostAsync(&meta, f1));
652
653 // Should acquire a valid fence.
654 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800655 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700656 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
657 EXPECT_TRUE(f2.IsValid());
658 // The original fence and acquired fence should have different fd number.
659 EXPECT_NE(f1.Get(), f2.Get());
660 EXPECT_GE(0, PollFd(f2.Get(), 0));
661
662 // Signal the original fence will trigger the new fence.
663 eventfd_write(f1.Get(), 1);
664 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800665 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700666
667 // Release the consumer with an invalid fence.
668 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
669
670 // Should gain an invalid fence.
671 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800672 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700673 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
674 EXPECT_FALSE(f3.IsValid());
675
676 // Post with a signaled fence.
677 EXPECT_EQ(0, p->PostAsync(&meta, f1));
678
679 // Should acquire a valid fence and it's already signalled.
680 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800681 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700682 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
683 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800684 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700685
686 // Release with an unsignalled fence and signal it immediately after release
687 // without producer gainning.
688 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
689 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
690 eventfd_write(f5.Get(), 1);
691
692 // Should gain a valid fence, which is already signaled.
693 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800694 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700695 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
696 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800697 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700698}
699
700TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700701 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700702 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
703 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700704 std::unique_ptr<ConsumerBuffer> c1 =
705 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700706 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800707 const uint32_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700708
Tianyuf669f6a2018-10-10 15:34:32 -0700709 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700710 DvrNativeBufferMetadata meta;
711 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
712
713 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800714 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700715 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716
Tianyuf669f6a2018-10-10 15:34:32 -0700717 // Destroy the consumer who has acquired but not released the buffer.
718 c1 = nullptr;
719
720 // The buffer is now available for the producer to gain.
721 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
722
723 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700724 std::unique_ptr<ConsumerBuffer> c2 =
725 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700726 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800727 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700728 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700729 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
730 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700731
Tianyuf669f6a2018-10-10 15:34:32 -0700732 // Producer should be able to gain.
733 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
734}
735
736TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
737 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
738 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
739 ASSERT_TRUE(p.get() != nullptr);
740 std::unique_ptr<ConsumerBuffer> c1 =
741 ConsumerBuffer::Import(p->CreateConsumer());
742 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800743 const uint32_t client_state_mask1 = c1->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700744
745 EXPECT_EQ(0, p->GainAsync());
746 DvrNativeBufferMetadata meta;
747 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
748 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
749
750 // c2 is created when the buffer is in posted state. buffer state for c1 is
751 // posted. Thus, c2 should be automatically set to posted and able to acquire.
752 std::unique_ptr<ConsumerBuffer> c2 =
753 ConsumerBuffer::Import(p->CreateConsumer());
754 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800755 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700756 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800757 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700758 LocalHandle invalid_fence;
759 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700760
Tianyuf669f6a2018-10-10 15:34:32 -0700761 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700762
Tianyuf669f6a2018-10-10 15:34:32 -0700763 // c3 is created when the buffer is in acquired state. buffer state for c1 and
764 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
765 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700766 std::unique_ptr<ConsumerBuffer> c3 =
767 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700768 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800769 const uint32_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700770 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700771 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700772 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
773 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700774
Tianyuf669f6a2018-10-10 15:34:32 -0700775 // Releasing c2 and c3 in normal ways.
776 EXPECT_EQ(0, c2->Release(LocalHandle()));
777 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
778
779 // Destroy the c1 who has not released the buffer.
780 c1 = nullptr;
781
782 // The buffer is now available for the producer to gain.
783 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
784
785 // C4 is created in released state. Thus, it cannot gain the just posted
786 // buffer.
787 std::unique_ptr<ConsumerBuffer> c4 =
788 ConsumerBuffer::Import(p->CreateConsumer());
789 ASSERT_TRUE(c4.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800790 const uint32_t client_state_mask4 = c4->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700791 EXPECT_NE(client_state_mask3, client_state_mask4);
792 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
793 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
794
795 // Producer should be able to gain.
796 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700797}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700798
799TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700800 // TODO(b/112338294) rewrite test after migration
801 return;
802
Fan Xu021776e2018-12-05 13:34:48 -0800803 /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700804 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700805 std::unique_ptr<ConsumerBuffer> c =
806 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700807 ASSERT_TRUE(p.get() != nullptr);
808 ASSERT_TRUE(c.get() != nullptr);
809
810 DvrNativeBufferMetadata metadata;
811 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700812 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700813
814 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700815 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700816 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
817 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
818 auto s1 = p->Detach();
819 EXPECT_FALSE(s1);
820
821 // Detach in acquired state should fail.
822 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
823 s1 = p->Detach();
824 EXPECT_FALSE(s1);
825
826 // Detach in released state should fail.
827 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
828 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
829 s1 = p->Detach();
830 EXPECT_FALSE(s1);
831
832 // Detach in gained state should succeed.
833 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
834 s1 = p->Detach();
835 EXPECT_TRUE(s1);
836
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700837 LocalChannelHandle handle = s1.take();
838 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700839
840 // Both producer and consumer should have hangup.
841 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
842 auto s2 = p->GetEventMask(POLLHUP);
843 EXPECT_TRUE(s2);
844 EXPECT_EQ(s2.get(), POLLHUP);
845
846 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
847 s2 = p->GetEventMask(POLLHUP);
848 EXPECT_TRUE(s2);
849 EXPECT_EQ(s2.get(), POLLHUP);
850
851 auto s3 = p->CreateConsumer();
852 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700853 // Note that here the expected error code is EOPNOTSUPP as the socket towards
854 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700855 EXPECT_EQ(s3.error(), EOPNOTSUPP);
856
857 s3 = c->CreateConsumer();
858 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700859 // Note that here the expected error code is EPIPE returned from
860 // ConsumerChannel::HandleMessage as the socket is still open but the producer
861 // is gone.
862 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700863
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700864 // Detached buffer handle can be use to construct a new BufferHubBuffer
865 // object.
866 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700867 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700868 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700869 EXPECT_TRUE(d->IsValid());
870
Fan Xu021776e2018-12-05 13:34:48 -0800871 EXPECT_EQ(d->id(), p_id); */
Tianyub61df912018-10-16 14:55:39 -0700872}
873
874TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700875 // TODO(b/112338294) rewrite test after migration
876 return;
877
Fan Xu021776e2018-12-05 13:34:48 -0800878 /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700879 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
880 ASSERT_TRUE(p1.get() != nullptr);
881 int p1_id = p1->id();
882
Tianyuf669f6a2018-10-10 15:34:32 -0700883 // Detached the producer from gained state.
884 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700885 auto status_or_handle = p1->Detach();
886 EXPECT_TRUE(status_or_handle.ok());
887 LocalChannelHandle h1 = status_or_handle.take();
888 EXPECT_TRUE(h1.valid());
889
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700890 // Detached buffer handle can be use to construct a new BufferHubBuffer
891 // object.
892 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700893 EXPECT_FALSE(h1.valid());
894 EXPECT_TRUE(b1->IsValid());
895 int b1_id = b1->id();
Fan Xu021776e2018-12-05 13:34:48 -0800896 EXPECT_EQ(b1_id, p1_id); */
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700897}