blob: c3fa77b95872a6a064ec3a2021501ee9d4873ff9 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <gtest/gtest.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07002#include <poll.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <private/dvr/buffer_hub_client.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07004#include <private/dvr/bufferhub_rpc.h>
5#include <sys/epoll.h>
6#include <sys/eventfd.h>
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -07007#include <ui/BufferHubBuffer.h>
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
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -070022using android::BufferHubBuffer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070023using android::GraphicBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070024using android::sp;
Tianyu Jiang7359dc92018-12-13 11:22:28 -080025using android::BufferHubDefs::AnyClientAcquired;
26using android::BufferHubDefs::AnyClientGained;
27using android::BufferHubDefs::AnyClientPosted;
28using android::BufferHubDefs::IsBufferReleased;
29using android::BufferHubDefs::IsClientAcquired;
30using android::BufferHubDefs::IsClientPosted;
31using android::BufferHubDefs::IsClientReleased;
32using android::BufferHubDefs::kFirstClientBitMask;
33using android::BufferHubDefs::kMetadataHeaderSize;
Tianyu1a60bb42018-10-08 14:56:08 -070034using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070035using android::dvr::ProducerBuffer;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070036using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080037using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070038using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080039
40const int kWidth = 640;
41const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070042const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080043const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
44const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070045const size_t kUserMetadataSize = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070046// Maximum number of consumers for the buffer that only has one producer in the
47// test.
48const size_t kMaxConsumerCount =
Tianyu Jiang7359dc92018-12-13 11:22:28 -080049 android::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080050const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080051
52using LibBufferHubTest = ::testing::Test;
53
54TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070055 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080056 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
57 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070058 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070059 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070060 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080061 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070062 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070063 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080064 ASSERT_TRUE(c2.get() != nullptr);
65
Tianyuf669f6a2018-10-10 15:34:32 -070066 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070067 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070068 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
69 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070070
71 // Initial state: producer not available, consumers not 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(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080074 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070075
Tianyuf669f6a2018-10-10 15:34:32 -070076 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070077 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070078
79 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080080 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070081 EXPECT_EQ(1, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080082 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080083
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070085 EXPECT_EQ(0, c1->Acquire(&fence));
86 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080087 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088
Tianyu58a05a22018-10-10 18:41:27 -070089 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080090 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070091 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080092
Tianyuf669f6a2018-10-10 15:34:32 -070093 EXPECT_EQ(0, c1->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080094 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080095 EXPECT_EQ(0, c2->Discard());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080096 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070097
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080098 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080099 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700100 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800101 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700102}
103
104TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700105 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700106 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
107 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700108 std::unique_ptr<ConsumerBuffer> c =
109 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700110 ASSERT_TRUE(c.get() != nullptr);
111
112 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
113 ASSERT_TRUE(epoll_fd.IsValid());
114
115 epoll_event event;
116 std::array<epoll_event, 64> events;
117
118 auto event_sources = p->GetEventSources();
119 ASSERT_LT(event_sources.size(), events.size());
120
121 for (const auto& event_source : event_sources) {
122 event = {.events = event_source.event_mask | EPOLLET,
123 .data = {.fd = p->event_fd()}};
124 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
125 &event));
126 }
127
128 event_sources = c->GetEventSources();
129 ASSERT_LT(event_sources.size(), events.size());
130
131 for (const auto& event_source : event_sources) {
132 event = {.events = event_source.event_mask | EPOLLET,
133 .data = {.fd = c->event_fd()}};
134 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
135 &event));
136 }
137
138 // No events should be signaled initially.
139 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
140
Tianyuf669f6a2018-10-10 15:34:32 -0700141 // Gain and post the producer and check for consumer signal.
142 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700143 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800144 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
145 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700146 ASSERT_TRUE(events[0].events & EPOLLIN);
147 ASSERT_EQ(c->event_fd(), events[0].data.fd);
148
149 // Save the event bits to translate later.
150 event = events[0];
151
152 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800153 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
154 kPollTimeoutMs));
155 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
156 kPollTimeoutMs));
157 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
158 kPollTimeoutMs));
159 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
160 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700161
162 // Translate the events.
163 auto event_status = c->GetEventMask(event.events);
164 ASSERT_TRUE(event_status);
165 ASSERT_TRUE(event_status.get() & EPOLLIN);
166
167 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800168 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
169 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700170}
171
172TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700173 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700174 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
175 ASSERT_TRUE(p.get() != nullptr);
176
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700177 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700178 uint64_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700179 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700180 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700181 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700182 ASSERT_TRUE(cs[i].get() != nullptr);
183 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700184 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
185 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700186 }
Tianyuf669f6a2018-10-10 15:34:32 -0700187 EXPECT_EQ(client_state_masks, ~0ULL);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700188
189 // The 64th creation will fail with out-of-memory error.
190 auto state = p->CreateConsumer();
191 EXPECT_EQ(state.error(), E2BIG);
192
193 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700194 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700195 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700196 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700197 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700198 ASSERT_TRUE(cs[i].get() != nullptr);
199 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700200 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
201 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700202 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800203}
204
Corey Tabakad53870c2017-07-06 18:04:27 -0700205TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700206 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700207 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
208 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700209 std::unique_ptr<ConsumerBuffer> c =
210 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700211 ASSERT_TRUE(c.get() != nullptr);
212
Corey Tabakad53870c2017-07-06 18:04:27 -0700213 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700214 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700215
Tianyu Jiang60887c92018-11-14 15:52:38 -0800216 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700217 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700218
219 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700220 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700221
Tianyuf669f6a2018-10-10 15:34:32 -0700222 // Post and gain in posted state should fail.
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 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700227 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700228
229 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700230 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700231 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700232 EXPECT_EQ(-EBUSY, p->Gain(&fence));
233
234 // Release in acquired state should succeed.
235 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800236 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700237
Tianyuf669f6a2018-10-10 15:34:32 -0700238 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700239 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700240 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700241
242 // Gain in released state should succeed.
243 EXPECT_EQ(0, p->Gain(&fence));
244
Tianyu Jiang60887c92018-11-14 15:52:38 -0800245 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700246 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700247}
248
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700249TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700250 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700251 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
252 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700253 std::unique_ptr<ConsumerBuffer> c =
254 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700255 ASSERT_TRUE(c.get() != nullptr);
256
257 DvrNativeBufferMetadata metadata;
258 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700259 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700260
Tianyu Jiang60887c92018-11-14 15:52:38 -0800261 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700262 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
263 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700264 EXPECT_FALSE(invalid_fence.IsValid());
265
266 // Post in gained state should succeed.
267 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
268 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700269 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700270
Tianyuf669f6a2018-10-10 15:34:32 -0700271 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700272 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700273 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
274 EXPECT_FALSE(invalid_fence.IsValid());
275
276 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800277 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700278 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
279 EXPECT_FALSE(invalid_fence.IsValid());
280 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700281 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700282
283 // Acquire, post, and gain in acquired state should fail.
284 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
285 EXPECT_FALSE(invalid_fence.IsValid());
286 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
287 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
288 EXPECT_FALSE(invalid_fence.IsValid());
289
290 // Release in acquired state should succeed.
291 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800292 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700293 EXPECT_EQ(p->buffer_state(), c->buffer_state());
294 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
295
Tianyuf669f6a2018-10-10 15:34:32 -0700296 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700297 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
298 EXPECT_FALSE(invalid_fence.IsValid());
299 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
300
301 // Gain in released state should succeed.
302 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
303 EXPECT_FALSE(invalid_fence.IsValid());
304 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700305 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700306
Tianyuf669f6a2018-10-10 15:34:32 -0700307 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700308 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
309 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800310}
311
312TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
313 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
314 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
315 ASSERT_TRUE(p.get() != nullptr);
316
317 ASSERT_EQ(0, p->GainAsync());
318 ASSERT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700319}
320
Tianyu5465d6c2018-08-14 13:03:10 -0700321TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
322 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
323 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
324 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700325 std::unique_ptr<ConsumerBuffer> c =
326 ConsumerBuffer::Import(p->CreateConsumer());
327 ASSERT_TRUE(c.get() != nullptr);
328 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700329 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700330 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700331
332 // Gain in posted state should only succeed with gain_posted_buffer = true.
333 LocalHandle invalid_fence;
334 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
335 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
336}
337
338TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
339 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
340 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
341 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700342 std::unique_ptr<ConsumerBuffer> c =
343 ConsumerBuffer::Import(p->CreateConsumer());
344 ASSERT_TRUE(c.get() != nullptr);
345 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700346 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700347 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700348
349 // GainAsync in posted state should only succeed with gain_posted_buffer
350 // equals true.
351 DvrNativeBufferMetadata metadata;
352 LocalHandle invalid_fence;
353 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
354 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
355}
356
Tianyuf669f6a2018-10-10 15:34:32 -0700357TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700358 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700359 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
360 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700361 ASSERT_EQ(0, p->GainAsync());
362 ASSERT_EQ(0, p->Post(LocalHandle()));
363 // Producer state bit is in released state after post. The overall state of
364 // the buffer is also released because there is no consumer of this buffer.
365 ASSERT_TRUE(IsBufferReleased(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700366
Tianyuf669f6a2018-10-10 15:34:32 -0700367 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700368 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700369 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700370}
371
372TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700373 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700374 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
375 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700376 uint64_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700377
Tianyu1a60bb42018-10-08 14:56:08 -0700378 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700379 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700380 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700381 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700382 EXPECT_TRUE(IsBufferReleased(cs[i]->buffer_state()));
383 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700384 }
385
Tianyuf669f6a2018-10-10 15:34:32 -0700386 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700387 DvrNativeBufferMetadata metadata;
388 LocalHandle invalid_fence;
389
390 // Post the producer should trigger all consumers to be available.
391 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700392 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
393 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700394 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700395 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800396 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700397 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700398 EXPECT_TRUE(
399 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700400 }
401
402 // All consumers have to release before the buffer is considered to be
403 // released.
404 for (size_t i = 0; i < kMaxConsumerCount; i++) {
405 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
406 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
407 }
408
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800409 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700410 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
411
412 // Buffer state cross all clients must be consistent.
413 for (size_t i = 0; i < kMaxConsumerCount; i++) {
414 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
415 }
416}
417
418TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700419 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700420 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
421 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700422 EXPECT_EQ(0, p->GainAsync());
423 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700424
Tianyu1a60bb42018-10-08 14:56:08 -0700425 std::unique_ptr<ConsumerBuffer> c =
426 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700427 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700428 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700429
430 DvrNativeBufferMetadata metadata;
431 LocalHandle invalid_fence;
432
433 // Post the gained buffer should signal already created consumer.
434 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700435 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800436 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700437 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700438 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700439}
440
Tianyuf669f6a2018-10-10 15:34:32 -0700441TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700442 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700443 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
444 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700445 EXPECT_EQ(0, p->GainAsync());
446 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700447
448 DvrNativeBufferMetadata metadata;
449 LocalHandle invalid_fence;
450
451 // Post the gained buffer before any consumer gets created.
Tianyuf669f6a2018-10-10 15:34:32 -0700452 // The buffer should be in released state because it is not expected to be
453 // read by any clients.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700454 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700455 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
456 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700457
Tianyuf669f6a2018-10-10 15:34:32 -0700458 // Newly created consumer will not be signalled for the posted buffer before
459 // its creation. It cannot acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700460 std::unique_ptr<ConsumerBuffer> c =
461 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700462 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700463 EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
464 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
465
466 // Producer should be able to gain back and post the buffer
467 EXPECT_EQ(0, p->GainAsync());
468 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
469
470 // Consumer should be able to pick up the buffer this time.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700471 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700472 EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700473}
474
475TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700476 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700477 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
478 ASSERT_TRUE(p.get() != nullptr);
479
Tianyu1a60bb42018-10-08 14:56:08 -0700480 std::unique_ptr<ConsumerBuffer> c1 =
481 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700482 ASSERT_TRUE(c1.get() != nullptr);
483
Tianyuf669f6a2018-10-10 15:34:32 -0700484 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700485 DvrNativeBufferMetadata metadata;
486 LocalHandle invalid_fence;
487
488 // Post, acquire, and release the buffer..
489 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800490 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700491 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
492 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
493
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800494 // Note that the next PDX call is on the producer channel, which may be
495 // executed before Release impulse gets executed by bufferhubd. Thus, here we
496 // need to wait until the releasd is confirmed before creating another
497 // consumer.
498 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
499 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
500
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700501 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800502 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700503 std::unique_ptr<ConsumerBuffer> c2 =
504 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700505 ASSERT_TRUE(c2.get() != nullptr);
506
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700507 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
508 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700509 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700510}
511
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800512TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
513 struct Metadata {
514 int64_t field1;
515 int64_t field2;
516 };
Tianyu1a60bb42018-10-08 14:56:08 -0700517 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800518 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
519 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700520 std::unique_ptr<ConsumerBuffer> c =
521 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800522 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700523 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800524 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700525 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800526 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800527 LocalHandle fence;
528 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700529 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800530 EXPECT_EQ(m.field1, m2.field1);
531 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800532 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800533 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800534}
535
536TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
537 struct Metadata {
538 int64_t field1;
539 int64_t field2;
540 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700541 struct OverSizedMetadata {
542 int64_t field1;
543 int64_t field2;
544 int64_t field3;
545 };
Tianyu1a60bb42018-10-08 14:56:08 -0700546 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800547 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
548 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700549 std::unique_ptr<ConsumerBuffer> c =
550 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800551 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700552 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800553
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700554 // It is illegal to post metadata larger than originally requested during
555 // buffer allocation.
556 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700557 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800558 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700559
560 // It is ok to post metadata smaller than originally requested during
561 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700562 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800563}
564
565TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
566 struct Metadata {
567 int64_t field1;
568 int64_t field2;
569 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700570 struct OverSizedMetadata {
571 int64_t field1;
572 int64_t field2;
573 int64_t field3;
574 };
Tianyu1a60bb42018-10-08 14:56:08 -0700575 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800576 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
577 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700578 std::unique_ptr<ConsumerBuffer> c =
579 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800580 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700581 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800582
583 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700584 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800585
586 LocalHandle fence;
587 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700588 OverSizedMetadata e;
589
590 // It is illegal to acquire metadata larger than originally requested during
591 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700592 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700593
594 // It is ok to acquire metadata smaller than originally requested during
595 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700596 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700597 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800598}
599
600TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700601 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800602 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
603 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 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700610 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800611
612 LocalHandle fence;
613 EXPECT_EQ(0, c->Acquire(&fence));
614}
615
616TEST_F(LibBufferHubTest, TestWithNoMeta) {
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 LocalHandle fence;
626
Tianyue6e08ab2018-09-13 18:48:55 -0700627 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800628 EXPECT_EQ(0, c->Acquire(&fence));
629}
630
631TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700632 std::unique_ptr<ProducerBuffer> p =
633 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800634 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700635 std::unique_ptr<ConsumerBuffer> c =
636 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800637 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700638 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800639
640 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700641 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800642}
643
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700644namespace {
645
646int PollFd(int fd, int timeout_ms) {
647 pollfd p = {fd, POLLIN, 0};
648 return poll(&p, 1, timeout_ms);
649}
650
651} // namespace
652
653TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700654 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700655 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
656 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700657 std::unique_ptr<ConsumerBuffer> c =
658 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700659 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700660 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700661
662 DvrNativeBufferMetadata meta;
663 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
664
665 // Post with unsignaled fence.
666 EXPECT_EQ(0, p->PostAsync(&meta, f1));
667
668 // Should acquire a valid fence.
669 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800670 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700671 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
672 EXPECT_TRUE(f2.IsValid());
673 // The original fence and acquired fence should have different fd number.
674 EXPECT_NE(f1.Get(), f2.Get());
675 EXPECT_GE(0, PollFd(f2.Get(), 0));
676
677 // Signal the original fence will trigger the new fence.
678 eventfd_write(f1.Get(), 1);
679 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800680 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700681
682 // Release the consumer with an invalid fence.
683 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
684
685 // Should gain an invalid fence.
686 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800687 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700688 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
689 EXPECT_FALSE(f3.IsValid());
690
691 // Post with a signaled fence.
692 EXPECT_EQ(0, p->PostAsync(&meta, f1));
693
694 // Should acquire a valid fence and it's already signalled.
695 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800696 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700697 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
698 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800699 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700700
701 // Release with an unsignalled fence and signal it immediately after release
702 // without producer gainning.
703 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
704 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
705 eventfd_write(f5.Get(), 1);
706
707 // Should gain a valid fence, which is already signaled.
708 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800709 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700710 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
711 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800712 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700713}
714
715TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700716 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700717 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
718 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700719 std::unique_ptr<ConsumerBuffer> c1 =
720 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700721 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700722 const uint64_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700723
Tianyuf669f6a2018-10-10 15:34:32 -0700724 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725 DvrNativeBufferMetadata meta;
726 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
727
728 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800729 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700730 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700731
Tianyuf669f6a2018-10-10 15:34:32 -0700732 // Destroy the consumer who has acquired but not released the buffer.
733 c1 = nullptr;
734
735 // The buffer is now available for the producer to gain.
736 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
737
738 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700739 std::unique_ptr<ConsumerBuffer> c2 =
740 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700741 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700742 const uint64_t client_state_mask2 = c2->client_state_mask();
743 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700744 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
745 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700746
Tianyuf669f6a2018-10-10 15:34:32 -0700747 // Producer should be able to gain.
748 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
749}
750
751TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
752 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
753 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
754 ASSERT_TRUE(p.get() != nullptr);
755 std::unique_ptr<ConsumerBuffer> c1 =
756 ConsumerBuffer::Import(p->CreateConsumer());
757 ASSERT_TRUE(c1.get() != nullptr);
758 const uint64_t client_state_mask1 = c1->client_state_mask();
759
760 EXPECT_EQ(0, p->GainAsync());
761 DvrNativeBufferMetadata meta;
762 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
763 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
764
765 // c2 is created when the buffer is in posted state. buffer state for c1 is
766 // posted. Thus, c2 should be automatically set to posted and able to acquire.
767 std::unique_ptr<ConsumerBuffer> c2 =
768 ConsumerBuffer::Import(p->CreateConsumer());
769 ASSERT_TRUE(c2.get() != nullptr);
770 const uint64_t client_state_mask2 = c2->client_state_mask();
771 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800772 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700773 LocalHandle invalid_fence;
774 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700775
Tianyuf669f6a2018-10-10 15:34:32 -0700776 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700777
Tianyuf669f6a2018-10-10 15:34:32 -0700778 // c3 is created when the buffer is in acquired state. buffer state for c1 and
779 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
780 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700781 std::unique_ptr<ConsumerBuffer> c3 =
782 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700783 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700784 const uint64_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700785 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700786 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700787 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
788 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700789
Tianyuf669f6a2018-10-10 15:34:32 -0700790 // Releasing c2 and c3 in normal ways.
791 EXPECT_EQ(0, c2->Release(LocalHandle()));
792 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
793
794 // Destroy the c1 who has not released the buffer.
795 c1 = nullptr;
796
797 // The buffer is now available for the producer to gain.
798 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
799
800 // C4 is created in released state. Thus, it cannot gain the just posted
801 // buffer.
802 std::unique_ptr<ConsumerBuffer> c4 =
803 ConsumerBuffer::Import(p->CreateConsumer());
804 ASSERT_TRUE(c4.get() != nullptr);
805 const uint64_t client_state_mask4 = c4->client_state_mask();
806 EXPECT_NE(client_state_mask3, client_state_mask4);
807 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
808 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
809
810 // Producer should be able to gain.
811 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700812}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700813
814TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700815 // TODO(b/112338294) rewrite test after migration
816 return;
817
Tianyu1a60bb42018-10-08 14:56:08 -0700818 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700819 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700820 std::unique_ptr<ConsumerBuffer> c =
821 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700822 ASSERT_TRUE(p.get() != nullptr);
823 ASSERT_TRUE(c.get() != nullptr);
824
825 DvrNativeBufferMetadata metadata;
826 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700827 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700828
829 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700830 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700831 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
832 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
833 auto s1 = p->Detach();
834 EXPECT_FALSE(s1);
835
836 // Detach in acquired state should fail.
837 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
838 s1 = p->Detach();
839 EXPECT_FALSE(s1);
840
841 // Detach in released state should fail.
842 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
843 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
844 s1 = p->Detach();
845 EXPECT_FALSE(s1);
846
847 // Detach in gained state should succeed.
848 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
849 s1 = p->Detach();
850 EXPECT_TRUE(s1);
851
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700852 LocalChannelHandle handle = s1.take();
853 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700854
855 // Both producer and consumer should have hangup.
856 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
857 auto s2 = p->GetEventMask(POLLHUP);
858 EXPECT_TRUE(s2);
859 EXPECT_EQ(s2.get(), POLLHUP);
860
861 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
862 s2 = p->GetEventMask(POLLHUP);
863 EXPECT_TRUE(s2);
864 EXPECT_EQ(s2.get(), POLLHUP);
865
866 auto s3 = p->CreateConsumer();
867 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700868 // Note that here the expected error code is EOPNOTSUPP as the socket towards
869 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700870 EXPECT_EQ(s3.error(), EOPNOTSUPP);
871
872 s3 = c->CreateConsumer();
873 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700874 // Note that here the expected error code is EPIPE returned from
875 // ConsumerChannel::HandleMessage as the socket is still open but the producer
876 // is gone.
877 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700878
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700879 // Detached buffer handle can be use to construct a new BufferHubBuffer
880 // object.
881 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700882 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700883 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700884 EXPECT_TRUE(d->IsValid());
885
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700886 EXPECT_EQ(d->id(), p_id);
887}
888
Tianyub61df912018-10-16 14:55:39 -0700889TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
890 // Buffer Creation will fail: BLOB format requires height to be 1.
891 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
892 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
893 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700894
Tianyub61df912018-10-16 14:55:39 -0700895 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700896 EXPECT_FALSE(b1->IsValid());
897
Tianyub61df912018-10-16 14:55:39 -0700898 // Buffer Creation will fail: user metadata size too large.
899 auto b2 = BufferHubBuffer::Create(
900 kWidth, kHeight, kLayerCount, kFormat, kUsage,
901 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700902
Tianyub61df912018-10-16 14:55:39 -0700903 EXPECT_FALSE(b2->IsConnected());
904 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700905
Tianyub61df912018-10-16 14:55:39 -0700906 // Buffer Creation will fail: user metadata size too large.
907 auto b3 = BufferHubBuffer::Create(
908 kWidth, kHeight, kLayerCount, kFormat, kUsage,
909 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
910 kMetadataHeaderSize);
911
912 EXPECT_FALSE(b3->IsConnected());
913 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700914}
915
Tianyub61df912018-10-16 14:55:39 -0700916TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
917 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
918 kUsage, kUserMetadataSize);
919 EXPECT_TRUE(b1->IsConnected());
920 EXPECT_TRUE(b1->IsValid());
921 EXPECT_NE(b1->id(), 0);
922}
923
924TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700925 // TODO(b/112338294) rewrite test after migration
926 return;
927
Tianyu1a60bb42018-10-08 14:56:08 -0700928 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700929 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
930 ASSERT_TRUE(p1.get() != nullptr);
931 int p1_id = p1->id();
932
Tianyuf669f6a2018-10-10 15:34:32 -0700933 // Detached the producer from gained state.
934 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700935 auto status_or_handle = p1->Detach();
936 EXPECT_TRUE(status_or_handle.ok());
937 LocalChannelHandle h1 = status_or_handle.take();
938 EXPECT_TRUE(h1.valid());
939
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700940 // Detached buffer handle can be use to construct a new BufferHubBuffer
941 // object.
942 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700943 EXPECT_FALSE(h1.valid());
944 EXPECT_TRUE(b1->IsValid());
945 int b1_id = b1->id();
946 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700947}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700948
Tianyub61df912018-10-16 14:55:39 -0700949TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
950 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
951 kUsage, kUserMetadataSize);
952 int b1_id = b1->id();
953 EXPECT_TRUE(b1->IsValid());
954 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700955 EXPECT_NE(b1->client_state_mask(), 0ULL);
Tianyub61df912018-10-16 14:55:39 -0700956
957 auto status_or_handle = b1->Duplicate();
958 EXPECT_TRUE(status_or_handle);
959
960 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700961 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700962 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700963
Tianyub61df912018-10-16 14:55:39 -0700964 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700965 LocalChannelHandle h2 = status_or_handle.take();
966 EXPECT_TRUE(h2.valid());
967
Tianyub61df912018-10-16 14:55:39 -0700968 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700969 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700970 ASSERT_TRUE(b2 != nullptr);
971 EXPECT_TRUE(b2->IsValid());
972 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700973 EXPECT_NE(b2->client_state_mask(), 0ULL);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700974
Tianyub61df912018-10-16 14:55:39 -0700975 int b2_id = b2->id();
976
977 // These two buffer instances are based on the same physical buffer under the
978 // hood, so they should share the same id.
979 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700980 // We use client_state_mask() to tell those two instances apart.
981 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
Tianyub61df912018-10-16 14:55:39 -0700982
983 // Both buffer instances should be in gained state.
Tianyuf669f6a2018-10-10 15:34:32 -0700984 EXPECT_TRUE(IsBufferReleased(b1->buffer_state()));
985 EXPECT_TRUE(IsBufferReleased(b2->buffer_state()));
Tianyub61df912018-10-16 14:55:39 -0700986
987 // TODO(b/112338294) rewrite test after migration
988 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700989}