blob: 2d9a42b3d2c31443ffa348eb8d9f895465e2ecdc [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>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08008
9#include <mutex>
10#include <thread>
11
Alex Vakulenko4fe60582017-02-02 11:35:59 -080012#define RETRY_EINTR(fnc_call) \
13 ([&]() -> decltype(fnc_call) { \
14 decltype(fnc_call) result; \
15 do { \
16 result = (fnc_call); \
17 } while (result == -1 && errno == EINTR); \
18 return result; \
19 })()
20
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -070021using android::BufferHubBuffer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070022using android::GraphicBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070023using android::sp;
Tianyu1a60bb42018-10-08 14:56:08 -070024using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070025using android::dvr::ProducerBuffer;
Tianyuf669f6a2018-10-10 15:34:32 -070026using android::dvr::BufferHubDefs::AnyClientAcquired;
27using android::dvr::BufferHubDefs::AnyClientGained;
28using android::dvr::BufferHubDefs::AnyClientPosted;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070029using android::dvr::BufferHubDefs::IsBufferReleased;
Tianyuf669f6a2018-10-10 15:34:32 -070030using android::dvr::BufferHubDefs::IsClientAcquired;
31using android::dvr::BufferHubDefs::IsClientPosted;
32using android::dvr::BufferHubDefs::IsClientReleased;
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070033using android::dvr::BufferHubDefs::kFirstClientBitMask;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070034using android::dvr::BufferHubDefs::kMetadataHeaderSize;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070035using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070037using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080038
39const int kWidth = 640;
40const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070041const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080042const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
43const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070044const size_t kUserMetadataSize = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070045// Maximum number of consumers for the buffer that only has one producer in the
46// test.
47const size_t kMaxConsumerCount =
48 android::dvr::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080049const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080050
51using LibBufferHubTest = ::testing::Test;
52
53TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070054 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080055 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
56 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070057 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070058 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070059 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080060 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070061 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070062 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080063 ASSERT_TRUE(c2.get() != nullptr);
64
Tianyuf669f6a2018-10-10 15:34:32 -070065 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070066 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070067 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
68 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070069
70 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080071 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070072 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080073 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070074
Tianyuf669f6a2018-10-10 15:34:32 -070075 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070076 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070077
78 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080079 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070080 EXPECT_EQ(1, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080081 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080082
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080083 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070084 EXPECT_EQ(0, c1->Acquire(&fence));
85 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080086 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080087
Tianyu58a05a22018-10-10 18:41:27 -070088 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080089 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070090 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080091
Tianyuf669f6a2018-10-10 15:34:32 -070092 EXPECT_EQ(0, c1->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080093 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080094 EXPECT_EQ(0, c2->Discard());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080095 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070096
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080097 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080098 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070099 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800100 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700101}
102
103TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700104 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700105 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
106 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700107 std::unique_ptr<ConsumerBuffer> c =
108 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700109 ASSERT_TRUE(c.get() != nullptr);
110
111 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
112 ASSERT_TRUE(epoll_fd.IsValid());
113
114 epoll_event event;
115 std::array<epoll_event, 64> events;
116
117 auto event_sources = p->GetEventSources();
118 ASSERT_LT(event_sources.size(), events.size());
119
120 for (const auto& event_source : event_sources) {
121 event = {.events = event_source.event_mask | EPOLLET,
122 .data = {.fd = p->event_fd()}};
123 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
124 &event));
125 }
126
127 event_sources = c->GetEventSources();
128 ASSERT_LT(event_sources.size(), events.size());
129
130 for (const auto& event_source : event_sources) {
131 event = {.events = event_source.event_mask | EPOLLET,
132 .data = {.fd = c->event_fd()}};
133 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
134 &event));
135 }
136
137 // No events should be signaled initially.
138 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
139
Tianyuf669f6a2018-10-10 15:34:32 -0700140 // Gain and post the producer and check for consumer signal.
141 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700142 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800143 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
144 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700145 ASSERT_TRUE(events[0].events & EPOLLIN);
146 ASSERT_EQ(c->event_fd(), events[0].data.fd);
147
148 // Save the event bits to translate later.
149 event = events[0];
150
151 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800152 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
153 kPollTimeoutMs));
154 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));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700160
161 // Translate the events.
162 auto event_status = c->GetEventMask(event.events);
163 ASSERT_TRUE(event_status);
164 ASSERT_TRUE(event_status.get() & EPOLLIN);
165
166 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800167 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
168 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700169}
170
171TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700172 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700173 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
174 ASSERT_TRUE(p.get() != nullptr);
175
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700176 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700177 uint64_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700178 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700179 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700180 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700181 ASSERT_TRUE(cs[i].get() != nullptr);
182 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700183 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
184 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700185 }
Tianyuf669f6a2018-10-10 15:34:32 -0700186 EXPECT_EQ(client_state_masks, ~0ULL);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700187
188 // The 64th creation will fail with out-of-memory error.
189 auto state = p->CreateConsumer();
190 EXPECT_EQ(state.error(), E2BIG);
191
192 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700193 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700194 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700195 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700196 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700197 ASSERT_TRUE(cs[i].get() != nullptr);
198 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700199 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
200 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700201 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800202}
203
Corey Tabakad53870c2017-07-06 18:04:27 -0700204TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700205 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700206 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
207 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700208 std::unique_ptr<ConsumerBuffer> c =
209 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700210 ASSERT_TRUE(c.get() != nullptr);
211
Corey Tabakad53870c2017-07-06 18:04:27 -0700212 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700213 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700214
Tianyuf669f6a2018-10-10 15:34:32 -0700215 // Acquire and gain in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700216 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700217 EXPECT_EQ(-EALREADY, p->Gain(&fence));
218
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
Tianyuf669f6a2018-10-10 15:34:32 -0700245 // Acquire and gain 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 EXPECT_EQ(-EALREADY, p->Gain(&fence));
248}
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
Tianyuf669f6a2018-10-10 15:34:32 -0700262 // Acquire and gain 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_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
266 EXPECT_FALSE(invalid_fence.IsValid());
267
268 // Post in gained state should succeed.
269 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
270 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700271 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700272
Tianyuf669f6a2018-10-10 15:34:32 -0700273 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700274 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700275 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
276 EXPECT_FALSE(invalid_fence.IsValid());
277
278 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800279 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700280 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
281 EXPECT_FALSE(invalid_fence.IsValid());
282 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700283 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700284
285 // Acquire, post, and gain in acquired state should fail.
286 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
287 EXPECT_FALSE(invalid_fence.IsValid());
288 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
289 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
290 EXPECT_FALSE(invalid_fence.IsValid());
291
292 // Release in acquired state should succeed.
293 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800294 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700295 EXPECT_EQ(p->buffer_state(), c->buffer_state());
296 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
297
Tianyuf669f6a2018-10-10 15:34:32 -0700298 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700299 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
300 EXPECT_FALSE(invalid_fence.IsValid());
301 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
302
303 // Gain in released state should succeed.
304 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
305 EXPECT_FALSE(invalid_fence.IsValid());
306 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700307 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700308
Tianyuf669f6a2018-10-10 15:34:32 -0700309 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700310 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
311 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700312 EXPECT_EQ(-EALREADY, p->GainAsync(&metadata, &invalid_fence));
313 EXPECT_FALSE(invalid_fence.IsValid());
314}
315
Tianyu5465d6c2018-08-14 13:03:10 -0700316TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
317 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
318 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
319 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700320 std::unique_ptr<ConsumerBuffer> c =
321 ConsumerBuffer::Import(p->CreateConsumer());
322 ASSERT_TRUE(c.get() != nullptr);
323 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700324 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700325 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700326
327 // Gain in posted state should only succeed with gain_posted_buffer = true.
328 LocalHandle invalid_fence;
329 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
330 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
331}
332
333TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
334 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
335 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
336 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700337 std::unique_ptr<ConsumerBuffer> c =
338 ConsumerBuffer::Import(p->CreateConsumer());
339 ASSERT_TRUE(c.get() != nullptr);
340 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700341 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700342 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700343
344 // GainAsync in posted state should only succeed with gain_posted_buffer
345 // equals true.
346 DvrNativeBufferMetadata metadata;
347 LocalHandle invalid_fence;
348 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
349 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
350}
351
Tianyuf669f6a2018-10-10 15:34:32 -0700352TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700353 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700354 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
355 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700356 ASSERT_EQ(0, p->GainAsync());
357 ASSERT_EQ(0, p->Post(LocalHandle()));
358 // Producer state bit is in released state after post. The overall state of
359 // the buffer is also released because there is no consumer of this buffer.
360 ASSERT_TRUE(IsBufferReleased(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700361
Tianyuf669f6a2018-10-10 15:34:32 -0700362 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700363 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700364 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700365}
366
367TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700368 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700369 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
370 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700371 uint64_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700372
Tianyu1a60bb42018-10-08 14:56:08 -0700373 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700374 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700375 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700376 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700377 EXPECT_TRUE(IsBufferReleased(cs[i]->buffer_state()));
378 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700379 }
380
Tianyuf669f6a2018-10-10 15:34:32 -0700381 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700382 DvrNativeBufferMetadata metadata;
383 LocalHandle invalid_fence;
384
385 // Post the producer should trigger all consumers to be available.
386 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700387 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
388 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700389 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700390 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800391 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700392 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700393 EXPECT_TRUE(
394 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700395 }
396
397 // All consumers have to release before the buffer is considered to be
398 // released.
399 for (size_t i = 0; i < kMaxConsumerCount; i++) {
400 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
401 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
402 }
403
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800404 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700405 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
406
407 // Buffer state cross all clients must be consistent.
408 for (size_t i = 0; i < kMaxConsumerCount; i++) {
409 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
410 }
411}
412
413TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700414 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700415 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
416 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700417 EXPECT_EQ(0, p->GainAsync());
418 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700419
Tianyu1a60bb42018-10-08 14:56:08 -0700420 std::unique_ptr<ConsumerBuffer> c =
421 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700422 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700423 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700424
425 DvrNativeBufferMetadata metadata;
426 LocalHandle invalid_fence;
427
428 // Post the gained buffer should signal already created consumer.
429 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700430 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800431 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700432 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700433 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700434}
435
Tianyuf669f6a2018-10-10 15:34:32 -0700436TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700437 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700438 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
439 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700440 EXPECT_EQ(0, p->GainAsync());
441 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700442
443 DvrNativeBufferMetadata metadata;
444 LocalHandle invalid_fence;
445
446 // Post the gained buffer before any consumer gets created.
Tianyuf669f6a2018-10-10 15:34:32 -0700447 // The buffer should be in released state because it is not expected to be
448 // read by any clients.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700449 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700450 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
451 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700452
Tianyuf669f6a2018-10-10 15:34:32 -0700453 // Newly created consumer will not be signalled for the posted buffer before
454 // its creation. It cannot acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700455 std::unique_ptr<ConsumerBuffer> c =
456 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700457 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700458 EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
459 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
460
461 // Producer should be able to gain back and post the buffer
462 EXPECT_EQ(0, p->GainAsync());
463 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
464
465 // Consumer should be able to pick up the buffer this time.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700466 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700467 EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700468}
469
470TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700471 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700472 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
473 ASSERT_TRUE(p.get() != nullptr);
474
Tianyu1a60bb42018-10-08 14:56:08 -0700475 std::unique_ptr<ConsumerBuffer> c1 =
476 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700477 ASSERT_TRUE(c1.get() != nullptr);
478
Tianyuf669f6a2018-10-10 15:34:32 -0700479 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700480 DvrNativeBufferMetadata metadata;
481 LocalHandle invalid_fence;
482
483 // Post, acquire, and release the buffer..
484 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800485 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700486 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
487 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
488
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800489 // Note that the next PDX call is on the producer channel, which may be
490 // executed before Release impulse gets executed by bufferhubd. Thus, here we
491 // need to wait until the releasd is confirmed before creating another
492 // consumer.
493 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
494 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
495
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700496 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800497 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700498 std::unique_ptr<ConsumerBuffer> c2 =
499 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700500 ASSERT_TRUE(c2.get() != nullptr);
501
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700502 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
503 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700504 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700505}
506
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800507TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
508 struct Metadata {
509 int64_t field1;
510 int64_t field2;
511 };
Tianyu1a60bb42018-10-08 14:56:08 -0700512 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800513 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
514 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700515 std::unique_ptr<ConsumerBuffer> c =
516 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800517 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700518 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700520 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800521 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800522 LocalHandle fence;
523 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700524 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800525 EXPECT_EQ(m.field1, m2.field1);
526 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800527 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800528 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800529}
530
531TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
532 struct Metadata {
533 int64_t field1;
534 int64_t field2;
535 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700536 struct OverSizedMetadata {
537 int64_t field1;
538 int64_t field2;
539 int64_t field3;
540 };
Tianyu1a60bb42018-10-08 14:56:08 -0700541 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800542 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
543 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700544 std::unique_ptr<ConsumerBuffer> c =
545 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800546 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700547 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800548
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700549 // It is illegal to post metadata larger than originally requested during
550 // buffer allocation.
551 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700552 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800553 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700554
555 // It is ok to post metadata smaller than originally requested during
556 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700557 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800558}
559
560TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
561 struct Metadata {
562 int64_t field1;
563 int64_t field2;
564 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700565 struct OverSizedMetadata {
566 int64_t field1;
567 int64_t field2;
568 int64_t field3;
569 };
Tianyu1a60bb42018-10-08 14:56:08 -0700570 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800571 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
572 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700573 std::unique_ptr<ConsumerBuffer> c =
574 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800575 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700576 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800577
578 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700579 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800580
581 LocalHandle fence;
582 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700583 OverSizedMetadata e;
584
585 // It is illegal to acquire metadata larger than originally requested during
586 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700587 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700588
589 // It is ok to acquire metadata smaller than originally requested during
590 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700591 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700592 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800593}
594
595TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700596 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
598 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700599 std::unique_ptr<ConsumerBuffer> c =
600 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800601 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700602 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800603
604 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700605 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800606
607 LocalHandle fence;
608 EXPECT_EQ(0, c->Acquire(&fence));
609}
610
611TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700612 std::unique_ptr<ProducerBuffer> p =
613 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800614 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700615 std::unique_ptr<ConsumerBuffer> c =
616 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800617 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700618 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800619
620 LocalHandle fence;
621
Tianyue6e08ab2018-09-13 18:48:55 -0700622 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800623 EXPECT_EQ(0, c->Acquire(&fence));
624}
625
626TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700627 std::unique_ptr<ProducerBuffer> p =
628 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800629 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700630 std::unique_ptr<ConsumerBuffer> c =
631 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800632 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700633 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800634
635 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700636 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800637}
638
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700639namespace {
640
641int PollFd(int fd, int timeout_ms) {
642 pollfd p = {fd, POLLIN, 0};
643 return poll(&p, 1, timeout_ms);
644}
645
646} // namespace
647
648TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700649 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700650 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
651 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700652 std::unique_ptr<ConsumerBuffer> c =
653 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700654 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700655 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700656
657 DvrNativeBufferMetadata meta;
658 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
659
660 // Post with unsignaled fence.
661 EXPECT_EQ(0, p->PostAsync(&meta, f1));
662
663 // Should acquire a valid fence.
664 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800665 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700666 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
667 EXPECT_TRUE(f2.IsValid());
668 // The original fence and acquired fence should have different fd number.
669 EXPECT_NE(f1.Get(), f2.Get());
670 EXPECT_GE(0, PollFd(f2.Get(), 0));
671
672 // Signal the original fence will trigger the new fence.
673 eventfd_write(f1.Get(), 1);
674 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800675 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700676
677 // Release the consumer with an invalid fence.
678 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
679
680 // Should gain an invalid fence.
681 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800682 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700683 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
684 EXPECT_FALSE(f3.IsValid());
685
686 // Post with a signaled fence.
687 EXPECT_EQ(0, p->PostAsync(&meta, f1));
688
689 // Should acquire a valid fence and it's already signalled.
690 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800691 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700692 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
693 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800694 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700695
696 // Release with an unsignalled fence and signal it immediately after release
697 // without producer gainning.
698 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
699 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
700 eventfd_write(f5.Get(), 1);
701
702 // Should gain a valid fence, which is already signaled.
703 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800704 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700705 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
706 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800707 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700708}
709
710TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700711 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700712 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
713 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700714 std::unique_ptr<ConsumerBuffer> c1 =
715 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700717 const uint64_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700718
Tianyuf669f6a2018-10-10 15:34:32 -0700719 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700720 DvrNativeBufferMetadata meta;
721 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
722
723 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800724 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700725 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700726
Tianyuf669f6a2018-10-10 15:34:32 -0700727 // Destroy the consumer who has acquired but not released the buffer.
728 c1 = nullptr;
729
730 // The buffer is now available for the producer to gain.
731 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
732
733 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700734 std::unique_ptr<ConsumerBuffer> c2 =
735 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700736 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700737 const uint64_t client_state_mask2 = c2->client_state_mask();
738 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700739 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
740 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700741
Tianyuf669f6a2018-10-10 15:34:32 -0700742 // Producer should be able to gain.
743 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
744}
745
746TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
747 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
748 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
749 ASSERT_TRUE(p.get() != nullptr);
750 std::unique_ptr<ConsumerBuffer> c1 =
751 ConsumerBuffer::Import(p->CreateConsumer());
752 ASSERT_TRUE(c1.get() != nullptr);
753 const uint64_t client_state_mask1 = c1->client_state_mask();
754
755 EXPECT_EQ(0, p->GainAsync());
756 DvrNativeBufferMetadata meta;
757 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
758 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
759
760 // c2 is created when the buffer is in posted state. buffer state for c1 is
761 // posted. Thus, c2 should be automatically set to posted and able to acquire.
762 std::unique_ptr<ConsumerBuffer> c2 =
763 ConsumerBuffer::Import(p->CreateConsumer());
764 ASSERT_TRUE(c2.get() != nullptr);
765 const uint64_t client_state_mask2 = c2->client_state_mask();
766 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800767 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700768 LocalHandle invalid_fence;
769 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700770
Tianyuf669f6a2018-10-10 15:34:32 -0700771 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700772
Tianyuf669f6a2018-10-10 15:34:32 -0700773 // c3 is created when the buffer is in acquired state. buffer state for c1 and
774 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
775 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700776 std::unique_ptr<ConsumerBuffer> c3 =
777 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700778 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700779 const uint64_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700780 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700781 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700782 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
783 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700784
Tianyuf669f6a2018-10-10 15:34:32 -0700785 // Releasing c2 and c3 in normal ways.
786 EXPECT_EQ(0, c2->Release(LocalHandle()));
787 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
788
789 // Destroy the c1 who has not released the buffer.
790 c1 = nullptr;
791
792 // The buffer is now available for the producer to gain.
793 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
794
795 // C4 is created in released state. Thus, it cannot gain the just posted
796 // buffer.
797 std::unique_ptr<ConsumerBuffer> c4 =
798 ConsumerBuffer::Import(p->CreateConsumer());
799 ASSERT_TRUE(c4.get() != nullptr);
800 const uint64_t client_state_mask4 = c4->client_state_mask();
801 EXPECT_NE(client_state_mask3, client_state_mask4);
802 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
803 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
804
805 // Producer should be able to gain.
806 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700807}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700808
809TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700810 // TODO(b/112338294) rewrite test after migration
811 return;
812
Tianyu1a60bb42018-10-08 14:56:08 -0700813 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700814 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700815 std::unique_ptr<ConsumerBuffer> c =
816 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700817 ASSERT_TRUE(p.get() != nullptr);
818 ASSERT_TRUE(c.get() != nullptr);
819
820 DvrNativeBufferMetadata metadata;
821 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700822 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700823
824 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700825 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700826 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
827 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
828 auto s1 = p->Detach();
829 EXPECT_FALSE(s1);
830
831 // Detach in acquired state should fail.
832 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
833 s1 = p->Detach();
834 EXPECT_FALSE(s1);
835
836 // Detach in released state should fail.
837 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
838 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
839 s1 = p->Detach();
840 EXPECT_FALSE(s1);
841
842 // Detach in gained state should succeed.
843 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
844 s1 = p->Detach();
845 EXPECT_TRUE(s1);
846
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700847 LocalChannelHandle handle = s1.take();
848 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700849
850 // Both producer and consumer should have hangup.
851 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
852 auto s2 = p->GetEventMask(POLLHUP);
853 EXPECT_TRUE(s2);
854 EXPECT_EQ(s2.get(), POLLHUP);
855
856 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
857 s2 = p->GetEventMask(POLLHUP);
858 EXPECT_TRUE(s2);
859 EXPECT_EQ(s2.get(), POLLHUP);
860
861 auto s3 = p->CreateConsumer();
862 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700863 // Note that here the expected error code is EOPNOTSUPP as the socket towards
864 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700865 EXPECT_EQ(s3.error(), EOPNOTSUPP);
866
867 s3 = c->CreateConsumer();
868 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700869 // Note that here the expected error code is EPIPE returned from
870 // ConsumerChannel::HandleMessage as the socket is still open but the producer
871 // is gone.
872 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700873
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700874 // Detached buffer handle can be use to construct a new BufferHubBuffer
875 // object.
876 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700877 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700878 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700879 EXPECT_TRUE(d->IsValid());
880
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700881 EXPECT_EQ(d->id(), p_id);
882}
883
Tianyub61df912018-10-16 14:55:39 -0700884TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
885 // Buffer Creation will fail: BLOB format requires height to be 1.
886 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
887 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
888 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700889
Tianyub61df912018-10-16 14:55:39 -0700890 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700891 EXPECT_FALSE(b1->IsValid());
892
Tianyub61df912018-10-16 14:55:39 -0700893 // Buffer Creation will fail: user metadata size too large.
894 auto b2 = BufferHubBuffer::Create(
895 kWidth, kHeight, kLayerCount, kFormat, kUsage,
896 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700897
Tianyub61df912018-10-16 14:55:39 -0700898 EXPECT_FALSE(b2->IsConnected());
899 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700900
Tianyub61df912018-10-16 14:55:39 -0700901 // Buffer Creation will fail: user metadata size too large.
902 auto b3 = BufferHubBuffer::Create(
903 kWidth, kHeight, kLayerCount, kFormat, kUsage,
904 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
905 kMetadataHeaderSize);
906
907 EXPECT_FALSE(b3->IsConnected());
908 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700909}
910
Tianyub61df912018-10-16 14:55:39 -0700911TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
912 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
913 kUsage, kUserMetadataSize);
914 EXPECT_TRUE(b1->IsConnected());
915 EXPECT_TRUE(b1->IsValid());
916 EXPECT_NE(b1->id(), 0);
917}
918
919TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700920 // TODO(b/112338294) rewrite test after migration
921 return;
922
Tianyu1a60bb42018-10-08 14:56:08 -0700923 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700924 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
925 ASSERT_TRUE(p1.get() != nullptr);
926 int p1_id = p1->id();
927
Tianyuf669f6a2018-10-10 15:34:32 -0700928 // Detached the producer from gained state.
929 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700930 auto status_or_handle = p1->Detach();
931 EXPECT_TRUE(status_or_handle.ok());
932 LocalChannelHandle h1 = status_or_handle.take();
933 EXPECT_TRUE(h1.valid());
934
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700935 // Detached buffer handle can be use to construct a new BufferHubBuffer
936 // object.
937 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700938 EXPECT_FALSE(h1.valid());
939 EXPECT_TRUE(b1->IsValid());
940 int b1_id = b1->id();
941 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700942}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700943
Tianyub61df912018-10-16 14:55:39 -0700944TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
945 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
946 kUsage, kUserMetadataSize);
947 int b1_id = b1->id();
948 EXPECT_TRUE(b1->IsValid());
949 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700950 EXPECT_NE(b1->client_state_mask(), 0ULL);
Tianyub61df912018-10-16 14:55:39 -0700951
952 auto status_or_handle = b1->Duplicate();
953 EXPECT_TRUE(status_or_handle);
954
955 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700956 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700957 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700958
Tianyub61df912018-10-16 14:55:39 -0700959 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700960 LocalChannelHandle h2 = status_or_handle.take();
961 EXPECT_TRUE(h2.valid());
962
Tianyub61df912018-10-16 14:55:39 -0700963 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700964 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700965 ASSERT_TRUE(b2 != nullptr);
966 EXPECT_TRUE(b2->IsValid());
967 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700968 EXPECT_NE(b2->client_state_mask(), 0ULL);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700969
Tianyub61df912018-10-16 14:55:39 -0700970 int b2_id = b2->id();
971
972 // These two buffer instances are based on the same physical buffer under the
973 // hood, so they should share the same id.
974 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700975 // We use client_state_mask() to tell those two instances apart.
976 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
Tianyub61df912018-10-16 14:55:39 -0700977
978 // Both buffer instances should be in gained state.
Tianyuf669f6a2018-10-10 15:34:32 -0700979 EXPECT_TRUE(IsBufferReleased(b1->buffer_state()));
980 EXPECT_TRUE(IsBufferReleased(b2->buffer_state()));
Tianyub61df912018-10-16 14:55:39 -0700981
982 // TODO(b/112338294) rewrite test after migration
983 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700984}