blob: 487a6048907fe447dd68b4655f48961ab7b16c49 [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>
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -07008#include <ui/BufferHubBuffer.h>
Tianyu Jiang7359dc92018-12-13 11:22:28 -08009#include <ui/BufferHubDefs.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080010
11#include <mutex>
12#include <thread>
13
Alex Vakulenko4fe60582017-02-02 11:35:59 -080014#define RETRY_EINTR(fnc_call) \
15 ([&]() -> decltype(fnc_call) { \
16 decltype(fnc_call) result; \
17 do { \
18 result = (fnc_call); \
19 } while (result == -1 && errno == EINTR); \
20 return result; \
21 })()
22
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -070023using android::BufferHubBuffer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070024using android::GraphicBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070025using android::sp;
Tianyu Jiang7359dc92018-12-13 11:22:28 -080026using android::BufferHubDefs::AnyClientAcquired;
27using android::BufferHubDefs::AnyClientGained;
28using android::BufferHubDefs::AnyClientPosted;
29using android::BufferHubDefs::IsBufferReleased;
30using android::BufferHubDefs::IsClientAcquired;
31using android::BufferHubDefs::IsClientPosted;
32using android::BufferHubDefs::IsClientReleased;
33using android::BufferHubDefs::kFirstClientBitMask;
34using android::BufferHubDefs::kMetadataHeaderSize;
Tianyu1a60bb42018-10-08 14:56:08 -070035using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070036using android::dvr::ProducerBuffer;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070037using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080038using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070039using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080040
41const int kWidth = 640;
42const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070043const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080044const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
45const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070046const size_t kUserMetadataSize = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070047// Maximum number of consumers for the buffer that only has one producer in the
48// test.
49const size_t kMaxConsumerCount =
Tianyu Jiang7359dc92018-12-13 11:22:28 -080050 android::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080051const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052
53using LibBufferHubTest = ::testing::Test;
54
55TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070056 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
58 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070059 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070060 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070061 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070063 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070064 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080065 ASSERT_TRUE(c2.get() != nullptr);
66
Tianyuf669f6a2018-10-10 15:34:32 -070067 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070068 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070069 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
70 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070071
72 // Initial state: producer not available, consumers not 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(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080075 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070076
Tianyuf669f6a2018-10-10 15:34:32 -070077 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070078 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070079
80 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080081 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070082 EXPECT_EQ(1, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080083 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080085 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070086 EXPECT_EQ(0, c1->Acquire(&fence));
87 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080088 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089
Tianyu58a05a22018-10-10 18:41:27 -070090 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080091 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070092 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080093
Tianyuf669f6a2018-10-10 15:34:32 -070094 EXPECT_EQ(0, c1->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080095 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080096 EXPECT_EQ(0, c2->Discard());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080097 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070098
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080099 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800100 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700101 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800102 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700103}
104
105TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700106 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700107 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
108 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700109 std::unique_ptr<ConsumerBuffer> c =
110 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700111 ASSERT_TRUE(c.get() != nullptr);
112
113 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
114 ASSERT_TRUE(epoll_fd.IsValid());
115
116 epoll_event event;
117 std::array<epoll_event, 64> events;
118
119 auto event_sources = p->GetEventSources();
120 ASSERT_LT(event_sources.size(), events.size());
121
122 for (const auto& event_source : event_sources) {
123 event = {.events = event_source.event_mask | EPOLLET,
124 .data = {.fd = p->event_fd()}};
125 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
126 &event));
127 }
128
129 event_sources = c->GetEventSources();
130 ASSERT_LT(event_sources.size(), events.size());
131
132 for (const auto& event_source : event_sources) {
133 event = {.events = event_source.event_mask | EPOLLET,
134 .data = {.fd = c->event_fd()}};
135 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
136 &event));
137 }
138
139 // No events should be signaled initially.
140 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
141
Tianyuf669f6a2018-10-10 15:34:32 -0700142 // Gain and post the producer and check for consumer signal.
143 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700144 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800145 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
146 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700147 ASSERT_TRUE(events[0].events & EPOLLIN);
148 ASSERT_EQ(c->event_fd(), events[0].data.fd);
149
150 // Save the event bits to translate later.
151 event = events[0];
152
153 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800154 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
155 kPollTimeoutMs));
156 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
157 kPollTimeoutMs));
158 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
159 kPollTimeoutMs));
160 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
161 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700162
163 // Translate the events.
164 auto event_status = c->GetEventMask(event.events);
165 ASSERT_TRUE(event_status);
166 ASSERT_TRUE(event_status.get() & EPOLLIN);
167
168 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800169 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
170 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700171}
172
173TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700174 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700175 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
176 ASSERT_TRUE(p.get() != nullptr);
177
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700178 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jianga99f9112018-12-13 18:23:07 -0800179 uint32_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700180 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700181 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700182 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700183 ASSERT_TRUE(cs[i].get() != nullptr);
184 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700185 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
186 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700187 }
Tianyu Jianga99f9112018-12-13 18:23:07 -0800188 EXPECT_EQ(client_state_masks, ~0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700189
190 // The 64th creation will fail with out-of-memory error.
191 auto state = p->CreateConsumer();
192 EXPECT_EQ(state.error(), E2BIG);
193
194 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700195 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700196 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700197 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700198 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700199 ASSERT_TRUE(cs[i].get() != nullptr);
200 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700201 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
202 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700203 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800204}
205
Corey Tabakad53870c2017-07-06 18:04:27 -0700206TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700207 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700208 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
209 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700210 std::unique_ptr<ConsumerBuffer> c =
211 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700212 ASSERT_TRUE(c.get() != nullptr);
213
Corey Tabakad53870c2017-07-06 18:04:27 -0700214 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700215 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700216
Tianyu Jiang60887c92018-11-14 15:52:38 -0800217 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700218 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700219
220 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700221 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700222
Tianyuf669f6a2018-10-10 15:34:32 -0700223 // Post and gain in posted state should fail.
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 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700228 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700229
230 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700231 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700232 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700233 EXPECT_EQ(-EBUSY, p->Gain(&fence));
234
235 // Release in acquired state should succeed.
236 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800237 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700238
Tianyuf669f6a2018-10-10 15:34:32 -0700239 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700240 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700241 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700242
243 // Gain in released state should succeed.
244 EXPECT_EQ(0, p->Gain(&fence));
245
Tianyu Jiang60887c92018-11-14 15:52:38 -0800246 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700247 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700248}
249
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700250TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700251 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700252 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
253 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700254 std::unique_ptr<ConsumerBuffer> c =
255 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700256 ASSERT_TRUE(c.get() != nullptr);
257
258 DvrNativeBufferMetadata metadata;
259 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700260 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700261
Tianyu Jiang60887c92018-11-14 15:52:38 -0800262 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700263 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
264 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265 EXPECT_FALSE(invalid_fence.IsValid());
266
267 // Post in gained state should succeed.
268 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
269 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700270 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700271
Tianyuf669f6a2018-10-10 15:34:32 -0700272 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700273 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700274 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
275 EXPECT_FALSE(invalid_fence.IsValid());
276
277 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800278 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700279 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
280 EXPECT_FALSE(invalid_fence.IsValid());
281 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700282 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700283
284 // Acquire, post, and gain in acquired state should fail.
285 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
286 EXPECT_FALSE(invalid_fence.IsValid());
287 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
288 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
289 EXPECT_FALSE(invalid_fence.IsValid());
290
291 // Release in acquired state should succeed.
292 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800293 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700294 EXPECT_EQ(p->buffer_state(), c->buffer_state());
295 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
296
Tianyuf669f6a2018-10-10 15:34:32 -0700297 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700298 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
299 EXPECT_FALSE(invalid_fence.IsValid());
300 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
301
302 // Gain in released state should succeed.
303 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
304 EXPECT_FALSE(invalid_fence.IsValid());
305 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700306 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700307
Tianyuf669f6a2018-10-10 15:34:32 -0700308 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700309 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
310 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800311}
312
313TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
314 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
315 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
316 ASSERT_TRUE(p.get() != nullptr);
317
318 ASSERT_EQ(0, p->GainAsync());
319 ASSERT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700320}
321
Tianyu5465d6c2018-08-14 13:03:10 -0700322TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
323 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
324 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
325 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700326 std::unique_ptr<ConsumerBuffer> c =
327 ConsumerBuffer::Import(p->CreateConsumer());
328 ASSERT_TRUE(c.get() != nullptr);
329 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700330 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700331 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700332
333 // Gain in posted state should only succeed with gain_posted_buffer = true.
334 LocalHandle invalid_fence;
335 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
336 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
337}
338
339TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
340 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
341 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
342 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700343 std::unique_ptr<ConsumerBuffer> c =
344 ConsumerBuffer::Import(p->CreateConsumer());
345 ASSERT_TRUE(c.get() != nullptr);
346 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700347 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700348 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700349
350 // GainAsync in posted state should only succeed with gain_posted_buffer
351 // equals true.
352 DvrNativeBufferMetadata metadata;
353 LocalHandle invalid_fence;
354 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
355 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
356}
357
Tianyuf669f6a2018-10-10 15:34:32 -0700358TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700359 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700360 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
361 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700362 ASSERT_EQ(0, p->GainAsync());
363 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800364 // Producer state bit is in released state after post, other clients shall be
365 // in posted state although there is no consumer of this buffer yet.
366 ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
367 ASSERT_FALSE(IsBufferReleased(p->buffer_state()));
368 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700369
Tianyuf669f6a2018-10-10 15:34:32 -0700370 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700371 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700372 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700373}
374
375TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700376 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700377 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
378 ASSERT_TRUE(p.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800379 uint32_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700380
Tianyu1a60bb42018-10-08 14:56:08 -0700381 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700382 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700383 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700384 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700385 EXPECT_TRUE(IsBufferReleased(cs[i]->buffer_state()));
386 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700387 }
388
Tianyuf669f6a2018-10-10 15:34:32 -0700389 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700390 DvrNativeBufferMetadata metadata;
391 LocalHandle invalid_fence;
392
393 // Post the producer should trigger all consumers to be available.
394 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700395 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
396 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700397 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700398 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800399 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700400 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700401 EXPECT_TRUE(
402 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700403 }
404
405 // All consumers have to release before the buffer is considered to be
406 // released.
407 for (size_t i = 0; i < kMaxConsumerCount; i++) {
408 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
409 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
410 }
411
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800412 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700413 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
414
415 // Buffer state cross all clients must be consistent.
416 for (size_t i = 0; i < kMaxConsumerCount; i++) {
417 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
418 }
419}
420
421TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700422 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700423 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
424 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700425 EXPECT_EQ(0, p->GainAsync());
426 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700427
Tianyu1a60bb42018-10-08 14:56:08 -0700428 std::unique_ptr<ConsumerBuffer> c =
429 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700430 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700431 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700432
433 DvrNativeBufferMetadata metadata;
434 LocalHandle invalid_fence;
435
436 // Post the gained buffer should signal already created consumer.
437 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700438 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800439 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700440 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700441 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700442}
443
Tianyuf669f6a2018-10-10 15:34:32 -0700444TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700445 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700446 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
447 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700448 EXPECT_EQ(0, p->GainAsync());
449 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700450
451 DvrNativeBufferMetadata metadata;
452 LocalHandle invalid_fence;
453
454 // Post the gained buffer before any consumer gets created.
455 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800456 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
Tianyuf669f6a2018-10-10 15:34:32 -0700457 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700458
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800459 // Newly created consumer will be signalled for the posted buffer although it
460 // is created after producer posting.
Tianyu1a60bb42018-10-08 14:56:08 -0700461 std::unique_ptr<ConsumerBuffer> c =
462 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700463 ASSERT_TRUE(c.get() != nullptr);
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800464 EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700465 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700466}
467
468TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700469 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700470 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
471 ASSERT_TRUE(p.get() != nullptr);
472
Tianyu1a60bb42018-10-08 14:56:08 -0700473 std::unique_ptr<ConsumerBuffer> c1 =
474 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700475 ASSERT_TRUE(c1.get() != nullptr);
476
Tianyuf669f6a2018-10-10 15:34:32 -0700477 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700478 DvrNativeBufferMetadata metadata;
479 LocalHandle invalid_fence;
480
481 // Post, acquire, and release the buffer..
482 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800483 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700484 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
485 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
486
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800487 // Note that the next PDX call is on the producer channel, which may be
488 // executed before Release impulse gets executed by bufferhubd. Thus, here we
489 // need to wait until the releasd is confirmed before creating another
490 // consumer.
491 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
492 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
493
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700494 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800495 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700496 std::unique_ptr<ConsumerBuffer> c2 =
497 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700498 ASSERT_TRUE(c2.get() != nullptr);
499
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700500 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
501 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700502 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700503}
504
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800505TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
506 struct Metadata {
507 int64_t field1;
508 int64_t field2;
509 };
Tianyu1a60bb42018-10-08 14:56:08 -0700510 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800511 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
512 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700513 std::unique_ptr<ConsumerBuffer> c =
514 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800515 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700516 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800517 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700518 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800519 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800520 LocalHandle fence;
521 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700522 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800523 EXPECT_EQ(m.field1, m2.field1);
524 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800525 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800526 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800527}
528
529TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
530 struct Metadata {
531 int64_t field1;
532 int64_t field2;
533 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700534 struct OverSizedMetadata {
535 int64_t field1;
536 int64_t field2;
537 int64_t field3;
538 };
Tianyu1a60bb42018-10-08 14:56:08 -0700539 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800540 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
541 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700542 std::unique_ptr<ConsumerBuffer> c =
543 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800544 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700545 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800546
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700547 // It is illegal to post metadata larger than originally requested during
548 // buffer allocation.
549 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700550 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800551 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700552
553 // It is ok to post metadata smaller than originally requested during
554 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700555 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800556}
557
558TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
559 struct Metadata {
560 int64_t field1;
561 int64_t field2;
562 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700563 struct OverSizedMetadata {
564 int64_t field1;
565 int64_t field2;
566 int64_t field3;
567 };
Tianyu1a60bb42018-10-08 14:56:08 -0700568 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800569 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
570 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700571 std::unique_ptr<ConsumerBuffer> c =
572 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800573 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700574 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800575
576 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700577 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800578
579 LocalHandle fence;
580 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700581 OverSizedMetadata e;
582
583 // It is illegal to acquire metadata larger than originally requested during
584 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700585 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700586
587 // It is ok to acquire metadata smaller than originally requested during
588 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700589 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700590 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800591}
592
593TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700594 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800595 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
596 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700597 std::unique_ptr<ConsumerBuffer> c =
598 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800599 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700600 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800601
602 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700603 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800604
605 LocalHandle fence;
606 EXPECT_EQ(0, c->Acquire(&fence));
607}
608
609TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700610 std::unique_ptr<ProducerBuffer> p =
611 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800612 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700613 std::unique_ptr<ConsumerBuffer> c =
614 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800615 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700616 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800617
618 LocalHandle fence;
619
Tianyue6e08ab2018-09-13 18:48:55 -0700620 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800621 EXPECT_EQ(0, c->Acquire(&fence));
622}
623
624TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700625 std::unique_ptr<ProducerBuffer> p =
626 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800627 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700628 std::unique_ptr<ConsumerBuffer> c =
629 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800630 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700631 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800632
633 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700634 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800635}
636
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700637namespace {
638
639int PollFd(int fd, int timeout_ms) {
640 pollfd p = {fd, POLLIN, 0};
641 return poll(&p, 1, timeout_ms);
642}
643
644} // namespace
645
646TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700647 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700648 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
649 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700650 std::unique_ptr<ConsumerBuffer> c =
651 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700652 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700653 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700654
655 DvrNativeBufferMetadata meta;
656 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
657
658 // Post with unsignaled fence.
659 EXPECT_EQ(0, p->PostAsync(&meta, f1));
660
661 // Should acquire a valid fence.
662 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800663 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700664 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
665 EXPECT_TRUE(f2.IsValid());
666 // The original fence and acquired fence should have different fd number.
667 EXPECT_NE(f1.Get(), f2.Get());
668 EXPECT_GE(0, PollFd(f2.Get(), 0));
669
670 // Signal the original fence will trigger the new fence.
671 eventfd_write(f1.Get(), 1);
672 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800673 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700674
675 // Release the consumer with an invalid fence.
676 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
677
678 // Should gain an invalid fence.
679 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800680 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700681 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
682 EXPECT_FALSE(f3.IsValid());
683
684 // Post with a signaled fence.
685 EXPECT_EQ(0, p->PostAsync(&meta, f1));
686
687 // Should acquire a valid fence and it's already signalled.
688 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800689 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700690 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
691 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800692 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700693
694 // Release with an unsignalled fence and signal it immediately after release
695 // without producer gainning.
696 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
697 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
698 eventfd_write(f5.Get(), 1);
699
700 // Should gain a valid fence, which is already signaled.
701 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800702 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700703 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
704 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800705 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700706}
707
708TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700709 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700710 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
711 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700712 std::unique_ptr<ConsumerBuffer> c1 =
713 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700714 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800715 const uint32_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716
Tianyuf669f6a2018-10-10 15:34:32 -0700717 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700718 DvrNativeBufferMetadata meta;
719 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
720
721 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800722 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700723 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700724
Tianyuf669f6a2018-10-10 15:34:32 -0700725 // Destroy the consumer who has acquired but not released the buffer.
726 c1 = nullptr;
727
728 // The buffer is now available for the producer to gain.
729 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
730
731 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700732 std::unique_ptr<ConsumerBuffer> c2 =
733 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700734 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800735 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700736 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700737 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
738 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700739
Tianyuf669f6a2018-10-10 15:34:32 -0700740 // Producer should be able to gain.
741 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
742}
743
744TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
745 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
746 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
747 ASSERT_TRUE(p.get() != nullptr);
748 std::unique_ptr<ConsumerBuffer> c1 =
749 ConsumerBuffer::Import(p->CreateConsumer());
750 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800751 const uint32_t client_state_mask1 = c1->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700752
753 EXPECT_EQ(0, p->GainAsync());
754 DvrNativeBufferMetadata meta;
755 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
756 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
757
758 // c2 is created when the buffer is in posted state. buffer state for c1 is
759 // posted. Thus, c2 should be automatically set to posted and able to acquire.
760 std::unique_ptr<ConsumerBuffer> c2 =
761 ConsumerBuffer::Import(p->CreateConsumer());
762 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800763 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700764 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800765 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700766 LocalHandle invalid_fence;
767 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700768
Tianyuf669f6a2018-10-10 15:34:32 -0700769 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700770
Tianyuf669f6a2018-10-10 15:34:32 -0700771 // c3 is created when the buffer is in acquired state. buffer state for c1 and
772 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
773 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700774 std::unique_ptr<ConsumerBuffer> c3 =
775 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700776 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800777 const uint32_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700778 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700779 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700780 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
781 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700782
Tianyuf669f6a2018-10-10 15:34:32 -0700783 // Releasing c2 and c3 in normal ways.
784 EXPECT_EQ(0, c2->Release(LocalHandle()));
785 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
786
787 // Destroy the c1 who has not released the buffer.
788 c1 = nullptr;
789
790 // The buffer is now available for the producer to gain.
791 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
792
793 // C4 is created in released state. Thus, it cannot gain the just posted
794 // buffer.
795 std::unique_ptr<ConsumerBuffer> c4 =
796 ConsumerBuffer::Import(p->CreateConsumer());
797 ASSERT_TRUE(c4.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800798 const uint32_t client_state_mask4 = c4->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700799 EXPECT_NE(client_state_mask3, client_state_mask4);
800 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
801 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
802
803 // Producer should be able to gain.
804 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700805}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700806
807TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700808 // TODO(b/112338294) rewrite test after migration
809 return;
810
Tianyu1a60bb42018-10-08 14:56:08 -0700811 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700812 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700813 std::unique_ptr<ConsumerBuffer> c =
814 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700815 ASSERT_TRUE(p.get() != nullptr);
816 ASSERT_TRUE(c.get() != nullptr);
817
818 DvrNativeBufferMetadata metadata;
819 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700820 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700821
822 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700823 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700824 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
825 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
826 auto s1 = p->Detach();
827 EXPECT_FALSE(s1);
828
829 // Detach in acquired state should fail.
830 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
831 s1 = p->Detach();
832 EXPECT_FALSE(s1);
833
834 // Detach in released state should fail.
835 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
836 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
837 s1 = p->Detach();
838 EXPECT_FALSE(s1);
839
840 // Detach in gained state should succeed.
841 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
842 s1 = p->Detach();
843 EXPECT_TRUE(s1);
844
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700845 LocalChannelHandle handle = s1.take();
846 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700847
848 // Both producer and consumer should have hangup.
849 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
850 auto s2 = p->GetEventMask(POLLHUP);
851 EXPECT_TRUE(s2);
852 EXPECT_EQ(s2.get(), POLLHUP);
853
854 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
855 s2 = p->GetEventMask(POLLHUP);
856 EXPECT_TRUE(s2);
857 EXPECT_EQ(s2.get(), POLLHUP);
858
859 auto s3 = p->CreateConsumer();
860 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700861 // Note that here the expected error code is EOPNOTSUPP as the socket towards
862 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700863 EXPECT_EQ(s3.error(), EOPNOTSUPP);
864
865 s3 = c->CreateConsumer();
866 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700867 // Note that here the expected error code is EPIPE returned from
868 // ConsumerChannel::HandleMessage as the socket is still open but the producer
869 // is gone.
870 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700871
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700872 // Detached buffer handle can be use to construct a new BufferHubBuffer
873 // object.
874 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700875 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700876 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700877 EXPECT_TRUE(d->IsValid());
878
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700879 EXPECT_EQ(d->id(), p_id);
880}
881
Tianyub61df912018-10-16 14:55:39 -0700882TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
883 // Buffer Creation will fail: BLOB format requires height to be 1.
884 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
885 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
886 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700887
Tianyub61df912018-10-16 14:55:39 -0700888 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700889 EXPECT_FALSE(b1->IsValid());
890
Tianyub61df912018-10-16 14:55:39 -0700891 // Buffer Creation will fail: user metadata size too large.
892 auto b2 = BufferHubBuffer::Create(
893 kWidth, kHeight, kLayerCount, kFormat, kUsage,
894 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700895
Tianyub61df912018-10-16 14:55:39 -0700896 EXPECT_FALSE(b2->IsConnected());
897 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700898
Tianyub61df912018-10-16 14:55:39 -0700899 // Buffer Creation will fail: user metadata size too large.
900 auto b3 = BufferHubBuffer::Create(
901 kWidth, kHeight, kLayerCount, kFormat, kUsage,
902 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
903 kMetadataHeaderSize);
904
905 EXPECT_FALSE(b3->IsConnected());
906 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700907}
908
Tianyub61df912018-10-16 14:55:39 -0700909TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
910 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
911 kUsage, kUserMetadataSize);
912 EXPECT_TRUE(b1->IsConnected());
913 EXPECT_TRUE(b1->IsValid());
914 EXPECT_NE(b1->id(), 0);
915}
916
917TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700918 // TODO(b/112338294) rewrite test after migration
919 return;
920
Tianyu1a60bb42018-10-08 14:56:08 -0700921 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700922 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
923 ASSERT_TRUE(p1.get() != nullptr);
924 int p1_id = p1->id();
925
Tianyuf669f6a2018-10-10 15:34:32 -0700926 // Detached the producer from gained state.
927 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700928 auto status_or_handle = p1->Detach();
929 EXPECT_TRUE(status_or_handle.ok());
930 LocalChannelHandle h1 = status_or_handle.take();
931 EXPECT_TRUE(h1.valid());
932
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700933 // Detached buffer handle can be use to construct a new BufferHubBuffer
934 // object.
935 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700936 EXPECT_FALSE(h1.valid());
937 EXPECT_TRUE(b1->IsValid());
938 int b1_id = b1->id();
939 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700940}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700941
Tianyub61df912018-10-16 14:55:39 -0700942TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
943 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
944 kUsage, kUserMetadataSize);
945 int b1_id = b1->id();
946 EXPECT_TRUE(b1->IsValid());
947 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800948 EXPECT_NE(b1->client_state_mask(), 0U);
Tianyub61df912018-10-16 14:55:39 -0700949
950 auto status_or_handle = b1->Duplicate();
951 EXPECT_TRUE(status_or_handle);
952
953 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700954 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700955 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700956
Tianyub61df912018-10-16 14:55:39 -0700957 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700958 LocalChannelHandle h2 = status_or_handle.take();
959 EXPECT_TRUE(h2.valid());
960
Tianyub61df912018-10-16 14:55:39 -0700961 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700962 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700963 ASSERT_TRUE(b2 != nullptr);
964 EXPECT_TRUE(b2->IsValid());
965 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800966 EXPECT_NE(b2->client_state_mask(), 0U);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700967
Tianyub61df912018-10-16 14:55:39 -0700968 int b2_id = b2->id();
969
970 // These two buffer instances are based on the same physical buffer under the
971 // hood, so they should share the same id.
972 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700973 // We use client_state_mask() to tell those two instances apart.
974 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
Tianyub61df912018-10-16 14:55:39 -0700975
976 // Both buffer instances should be in gained state.
Tianyuf669f6a2018-10-10 15:34:32 -0700977 EXPECT_TRUE(IsBufferReleased(b1->buffer_state()));
978 EXPECT_TRUE(IsBufferReleased(b2->buffer_state()));
Tianyub61df912018-10-16 14:55:39 -0700979
980 // TODO(b/112338294) rewrite test after migration
981 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700982}