blob: 9bcfaa1cde2611cfa2b35390a751498184156b6b [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
Tianyu Jiang60887c92018-11-14 15:52:38 -0800215 // Acquire 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
218 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700219 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700220
Tianyuf669f6a2018-10-10 15:34:32 -0700221 // Post and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700222 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700223 EXPECT_EQ(-EBUSY, p->Gain(&fence));
224
225 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700226 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700227
228 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700229 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700230 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700231 EXPECT_EQ(-EBUSY, p->Gain(&fence));
232
233 // Release in acquired state should succeed.
234 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800235 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700236
Tianyuf669f6a2018-10-10 15:34:32 -0700237 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700238 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700239 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700240
241 // Gain in released state should succeed.
242 EXPECT_EQ(0, p->Gain(&fence));
243
Tianyu Jiang60887c92018-11-14 15:52:38 -0800244 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700245 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700246}
247
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700248TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700249 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700250 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
251 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700252 std::unique_ptr<ConsumerBuffer> c =
253 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700254 ASSERT_TRUE(c.get() != nullptr);
255
256 DvrNativeBufferMetadata metadata;
257 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700258 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700259
Tianyu Jiang60887c92018-11-14 15:52:38 -0800260 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700261 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
262 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700263 EXPECT_FALSE(invalid_fence.IsValid());
264
265 // Post in gained state should succeed.
266 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
267 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700268 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700269
Tianyuf669f6a2018-10-10 15:34:32 -0700270 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700271 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700272 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
273 EXPECT_FALSE(invalid_fence.IsValid());
274
275 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800276 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700277 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
278 EXPECT_FALSE(invalid_fence.IsValid());
279 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700280 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700281
282 // Acquire, post, and gain in acquired state should fail.
283 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
284 EXPECT_FALSE(invalid_fence.IsValid());
285 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
286 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
287 EXPECT_FALSE(invalid_fence.IsValid());
288
289 // Release in acquired state should succeed.
290 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800291 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700292 EXPECT_EQ(p->buffer_state(), c->buffer_state());
293 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
294
Tianyuf669f6a2018-10-10 15:34:32 -0700295 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700296 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
297 EXPECT_FALSE(invalid_fence.IsValid());
298 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
299
300 // Gain in released state should succeed.
301 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
302 EXPECT_FALSE(invalid_fence.IsValid());
303 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700304 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700305
Tianyuf669f6a2018-10-10 15:34:32 -0700306 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700307 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
308 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800309}
310
311TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
312 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
313 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
314 ASSERT_TRUE(p.get() != nullptr);
315
316 ASSERT_EQ(0, p->GainAsync());
317 ASSERT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700318}
319
Tianyu5465d6c2018-08-14 13:03:10 -0700320TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
321 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
322 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
323 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700324 std::unique_ptr<ConsumerBuffer> c =
325 ConsumerBuffer::Import(p->CreateConsumer());
326 ASSERT_TRUE(c.get() != nullptr);
327 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700328 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700329 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700330
331 // Gain in posted state should only succeed with gain_posted_buffer = true.
332 LocalHandle invalid_fence;
333 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
334 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
335}
336
337TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
338 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
339 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
340 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700341 std::unique_ptr<ConsumerBuffer> c =
342 ConsumerBuffer::Import(p->CreateConsumer());
343 ASSERT_TRUE(c.get() != nullptr);
344 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700345 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700346 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700347
348 // GainAsync in posted state should only succeed with gain_posted_buffer
349 // equals true.
350 DvrNativeBufferMetadata metadata;
351 LocalHandle invalid_fence;
352 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
353 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
354}
355
Tianyuf669f6a2018-10-10 15:34:32 -0700356TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700357 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700358 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
359 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700360 ASSERT_EQ(0, p->GainAsync());
361 ASSERT_EQ(0, p->Post(LocalHandle()));
362 // Producer state bit is in released state after post. The overall state of
363 // the buffer is also released because there is no consumer of this buffer.
364 ASSERT_TRUE(IsBufferReleased(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700365
Tianyuf669f6a2018-10-10 15:34:32 -0700366 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700367 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700368 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700369}
370
371TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700372 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700373 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
374 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700375 uint64_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700376
Tianyu1a60bb42018-10-08 14:56:08 -0700377 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700378 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700379 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700380 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700381 EXPECT_TRUE(IsBufferReleased(cs[i]->buffer_state()));
382 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700383 }
384
Tianyuf669f6a2018-10-10 15:34:32 -0700385 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700386 DvrNativeBufferMetadata metadata;
387 LocalHandle invalid_fence;
388
389 // Post the producer should trigger all consumers to be available.
390 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700391 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
392 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700393 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700394 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800395 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700396 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700397 EXPECT_TRUE(
398 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700399 }
400
401 // All consumers have to release before the buffer is considered to be
402 // released.
403 for (size_t i = 0; i < kMaxConsumerCount; i++) {
404 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
405 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
406 }
407
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800408 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700409 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
410
411 // Buffer state cross all clients must be consistent.
412 for (size_t i = 0; i < kMaxConsumerCount; i++) {
413 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
414 }
415}
416
417TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700418 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700419 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
420 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700421 EXPECT_EQ(0, p->GainAsync());
422 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700423
Tianyu1a60bb42018-10-08 14:56:08 -0700424 std::unique_ptr<ConsumerBuffer> c =
425 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700426 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700427 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700428
429 DvrNativeBufferMetadata metadata;
430 LocalHandle invalid_fence;
431
432 // Post the gained buffer should signal already created consumer.
433 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700434 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800435 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700436 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700437 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700438}
439
Tianyuf669f6a2018-10-10 15:34:32 -0700440TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700441 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700442 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
443 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700444 EXPECT_EQ(0, p->GainAsync());
445 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700446
447 DvrNativeBufferMetadata metadata;
448 LocalHandle invalid_fence;
449
450 // Post the gained buffer before any consumer gets created.
Tianyuf669f6a2018-10-10 15:34:32 -0700451 // The buffer should be in released state because it is not expected to be
452 // read by any clients.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700453 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700454 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
455 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700456
Tianyuf669f6a2018-10-10 15:34:32 -0700457 // Newly created consumer will not be signalled for the posted buffer before
458 // its creation. It cannot acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700459 std::unique_ptr<ConsumerBuffer> c =
460 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700461 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700462 EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
463 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
464
465 // Producer should be able to gain back and post the buffer
466 EXPECT_EQ(0, p->GainAsync());
467 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
468
469 // Consumer should be able to pick up the buffer this time.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700470 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700471 EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700472}
473
474TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700475 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700476 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
477 ASSERT_TRUE(p.get() != nullptr);
478
Tianyu1a60bb42018-10-08 14:56:08 -0700479 std::unique_ptr<ConsumerBuffer> c1 =
480 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700481 ASSERT_TRUE(c1.get() != nullptr);
482
Tianyuf669f6a2018-10-10 15:34:32 -0700483 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700484 DvrNativeBufferMetadata metadata;
485 LocalHandle invalid_fence;
486
487 // Post, acquire, and release the buffer..
488 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800489 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700490 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
491 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
492
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800493 // Note that the next PDX call is on the producer channel, which may be
494 // executed before Release impulse gets executed by bufferhubd. Thus, here we
495 // need to wait until the releasd is confirmed before creating another
496 // consumer.
497 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
498 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
499
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700500 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800501 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700502 std::unique_ptr<ConsumerBuffer> c2 =
503 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700504 ASSERT_TRUE(c2.get() != nullptr);
505
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700506 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
507 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700508 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700509}
510
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800511TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
512 struct Metadata {
513 int64_t field1;
514 int64_t field2;
515 };
Tianyu1a60bb42018-10-08 14:56:08 -0700516 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800517 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
518 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700519 std::unique_ptr<ConsumerBuffer> c =
520 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800521 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700522 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800523 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700524 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800525 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800526 LocalHandle fence;
527 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700528 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800529 EXPECT_EQ(m.field1, m2.field1);
530 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800531 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800532 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800533}
534
535TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
536 struct Metadata {
537 int64_t field1;
538 int64_t field2;
539 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700540 struct OverSizedMetadata {
541 int64_t field1;
542 int64_t field2;
543 int64_t field3;
544 };
Tianyu1a60bb42018-10-08 14:56:08 -0700545 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800546 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
547 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700548 std::unique_ptr<ConsumerBuffer> c =
549 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800550 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700551 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800552
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700553 // It is illegal to post metadata larger than originally requested during
554 // buffer allocation.
555 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700556 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800557 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700558
559 // It is ok to post metadata smaller than originally requested during
560 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700561 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800562}
563
564TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
565 struct Metadata {
566 int64_t field1;
567 int64_t field2;
568 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700569 struct OverSizedMetadata {
570 int64_t field1;
571 int64_t field2;
572 int64_t field3;
573 };
Tianyu1a60bb42018-10-08 14:56:08 -0700574 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800575 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
576 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700577 std::unique_ptr<ConsumerBuffer> c =
578 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800579 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700580 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800581
582 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700583 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800584
585 LocalHandle fence;
586 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700587 OverSizedMetadata e;
588
589 // It is illegal to acquire metadata larger than originally requested during
590 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700591 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700592
593 // It is ok to acquire metadata smaller than originally requested during
594 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700595 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700596 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597}
598
599TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700600 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800601 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
602 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700603 std::unique_ptr<ConsumerBuffer> c =
604 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800605 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700606 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800607
608 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700609 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800610
611 LocalHandle fence;
612 EXPECT_EQ(0, c->Acquire(&fence));
613}
614
615TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700616 std::unique_ptr<ProducerBuffer> p =
617 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800618 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700619 std::unique_ptr<ConsumerBuffer> c =
620 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800621 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700622 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800623
624 LocalHandle fence;
625
Tianyue6e08ab2018-09-13 18:48:55 -0700626 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800627 EXPECT_EQ(0, c->Acquire(&fence));
628}
629
630TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700631 std::unique_ptr<ProducerBuffer> p =
632 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800633 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700634 std::unique_ptr<ConsumerBuffer> c =
635 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800636 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700637 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800638
639 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700640 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800641}
642
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700643namespace {
644
645int PollFd(int fd, int timeout_ms) {
646 pollfd p = {fd, POLLIN, 0};
647 return poll(&p, 1, timeout_ms);
648}
649
650} // namespace
651
652TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700653 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700654 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
655 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700656 std::unique_ptr<ConsumerBuffer> c =
657 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700658 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700659 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700660
661 DvrNativeBufferMetadata meta;
662 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
663
664 // Post with unsignaled fence.
665 EXPECT_EQ(0, p->PostAsync(&meta, f1));
666
667 // Should acquire a valid fence.
668 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800669 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700670 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
671 EXPECT_TRUE(f2.IsValid());
672 // The original fence and acquired fence should have different fd number.
673 EXPECT_NE(f1.Get(), f2.Get());
674 EXPECT_GE(0, PollFd(f2.Get(), 0));
675
676 // Signal the original fence will trigger the new fence.
677 eventfd_write(f1.Get(), 1);
678 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800679 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700680
681 // Release the consumer with an invalid fence.
682 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
683
684 // Should gain an invalid fence.
685 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800686 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700687 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
688 EXPECT_FALSE(f3.IsValid());
689
690 // Post with a signaled fence.
691 EXPECT_EQ(0, p->PostAsync(&meta, f1));
692
693 // Should acquire a valid fence and it's already signalled.
694 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800695 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700696 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
697 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800698 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700699
700 // Release with an unsignalled fence and signal it immediately after release
701 // without producer gainning.
702 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
703 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
704 eventfd_write(f5.Get(), 1);
705
706 // Should gain a valid fence, which is already signaled.
707 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800708 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700709 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
710 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800711 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700712}
713
714TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700715 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700716 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
717 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700718 std::unique_ptr<ConsumerBuffer> c1 =
719 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700720 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700721 const uint64_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700722
Tianyuf669f6a2018-10-10 15:34:32 -0700723 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700724 DvrNativeBufferMetadata meta;
725 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
726
727 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800728 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700729 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700730
Tianyuf669f6a2018-10-10 15:34:32 -0700731 // Destroy the consumer who has acquired but not released the buffer.
732 c1 = nullptr;
733
734 // The buffer is now available for the producer to gain.
735 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
736
737 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700738 std::unique_ptr<ConsumerBuffer> c2 =
739 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700740 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700741 const uint64_t client_state_mask2 = c2->client_state_mask();
742 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700743 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
744 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700745
Tianyuf669f6a2018-10-10 15:34:32 -0700746 // Producer should be able to gain.
747 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
748}
749
750TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
751 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
752 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
753 ASSERT_TRUE(p.get() != nullptr);
754 std::unique_ptr<ConsumerBuffer> c1 =
755 ConsumerBuffer::Import(p->CreateConsumer());
756 ASSERT_TRUE(c1.get() != nullptr);
757 const uint64_t client_state_mask1 = c1->client_state_mask();
758
759 EXPECT_EQ(0, p->GainAsync());
760 DvrNativeBufferMetadata meta;
761 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
762 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
763
764 // c2 is created when the buffer is in posted state. buffer state for c1 is
765 // posted. Thus, c2 should be automatically set to posted and able to acquire.
766 std::unique_ptr<ConsumerBuffer> c2 =
767 ConsumerBuffer::Import(p->CreateConsumer());
768 ASSERT_TRUE(c2.get() != nullptr);
769 const uint64_t client_state_mask2 = c2->client_state_mask();
770 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800771 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700772 LocalHandle invalid_fence;
773 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700774
Tianyuf669f6a2018-10-10 15:34:32 -0700775 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700776
Tianyuf669f6a2018-10-10 15:34:32 -0700777 // c3 is created when the buffer is in acquired state. buffer state for c1 and
778 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
779 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700780 std::unique_ptr<ConsumerBuffer> c3 =
781 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700782 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700783 const uint64_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700784 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700785 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700786 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
787 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700788
Tianyuf669f6a2018-10-10 15:34:32 -0700789 // Releasing c2 and c3 in normal ways.
790 EXPECT_EQ(0, c2->Release(LocalHandle()));
791 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
792
793 // Destroy the c1 who has not released the buffer.
794 c1 = nullptr;
795
796 // The buffer is now available for the producer to gain.
797 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
798
799 // C4 is created in released state. Thus, it cannot gain the just posted
800 // buffer.
801 std::unique_ptr<ConsumerBuffer> c4 =
802 ConsumerBuffer::Import(p->CreateConsumer());
803 ASSERT_TRUE(c4.get() != nullptr);
804 const uint64_t client_state_mask4 = c4->client_state_mask();
805 EXPECT_NE(client_state_mask3, client_state_mask4);
806 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
807 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
808
809 // Producer should be able to gain.
810 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700811}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700812
813TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700814 // TODO(b/112338294) rewrite test after migration
815 return;
816
Tianyu1a60bb42018-10-08 14:56:08 -0700817 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700818 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700819 std::unique_ptr<ConsumerBuffer> c =
820 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700821 ASSERT_TRUE(p.get() != nullptr);
822 ASSERT_TRUE(c.get() != nullptr);
823
824 DvrNativeBufferMetadata metadata;
825 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700826 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700827
828 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700829 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700830 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
831 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
832 auto s1 = p->Detach();
833 EXPECT_FALSE(s1);
834
835 // Detach in acquired state should fail.
836 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
837 s1 = p->Detach();
838 EXPECT_FALSE(s1);
839
840 // Detach in released state should fail.
841 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
842 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
843 s1 = p->Detach();
844 EXPECT_FALSE(s1);
845
846 // Detach in gained state should succeed.
847 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
848 s1 = p->Detach();
849 EXPECT_TRUE(s1);
850
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700851 LocalChannelHandle handle = s1.take();
852 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700853
854 // Both producer and consumer should have hangup.
855 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
856 auto s2 = p->GetEventMask(POLLHUP);
857 EXPECT_TRUE(s2);
858 EXPECT_EQ(s2.get(), POLLHUP);
859
860 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
861 s2 = p->GetEventMask(POLLHUP);
862 EXPECT_TRUE(s2);
863 EXPECT_EQ(s2.get(), POLLHUP);
864
865 auto s3 = p->CreateConsumer();
866 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700867 // Note that here the expected error code is EOPNOTSUPP as the socket towards
868 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700869 EXPECT_EQ(s3.error(), EOPNOTSUPP);
870
871 s3 = c->CreateConsumer();
872 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700873 // Note that here the expected error code is EPIPE returned from
874 // ConsumerChannel::HandleMessage as the socket is still open but the producer
875 // is gone.
876 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700877
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700878 // Detached buffer handle can be use to construct a new BufferHubBuffer
879 // object.
880 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700881 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700882 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700883 EXPECT_TRUE(d->IsValid());
884
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700885 EXPECT_EQ(d->id(), p_id);
886}
887
Tianyub61df912018-10-16 14:55:39 -0700888TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
889 // Buffer Creation will fail: BLOB format requires height to be 1.
890 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
891 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
892 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700893
Tianyub61df912018-10-16 14:55:39 -0700894 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700895 EXPECT_FALSE(b1->IsValid());
896
Tianyub61df912018-10-16 14:55:39 -0700897 // Buffer Creation will fail: user metadata size too large.
898 auto b2 = BufferHubBuffer::Create(
899 kWidth, kHeight, kLayerCount, kFormat, kUsage,
900 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700901
Tianyub61df912018-10-16 14:55:39 -0700902 EXPECT_FALSE(b2->IsConnected());
903 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700904
Tianyub61df912018-10-16 14:55:39 -0700905 // Buffer Creation will fail: user metadata size too large.
906 auto b3 = BufferHubBuffer::Create(
907 kWidth, kHeight, kLayerCount, kFormat, kUsage,
908 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
909 kMetadataHeaderSize);
910
911 EXPECT_FALSE(b3->IsConnected());
912 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700913}
914
Tianyub61df912018-10-16 14:55:39 -0700915TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
916 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
917 kUsage, kUserMetadataSize);
918 EXPECT_TRUE(b1->IsConnected());
919 EXPECT_TRUE(b1->IsValid());
920 EXPECT_NE(b1->id(), 0);
921}
922
923TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700924 // TODO(b/112338294) rewrite test after migration
925 return;
926
Tianyu1a60bb42018-10-08 14:56:08 -0700927 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700928 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
929 ASSERT_TRUE(p1.get() != nullptr);
930 int p1_id = p1->id();
931
Tianyuf669f6a2018-10-10 15:34:32 -0700932 // Detached the producer from gained state.
933 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700934 auto status_or_handle = p1->Detach();
935 EXPECT_TRUE(status_or_handle.ok());
936 LocalChannelHandle h1 = status_or_handle.take();
937 EXPECT_TRUE(h1.valid());
938
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700939 // Detached buffer handle can be use to construct a new BufferHubBuffer
940 // object.
941 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700942 EXPECT_FALSE(h1.valid());
943 EXPECT_TRUE(b1->IsValid());
944 int b1_id = b1->id();
945 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700946}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700947
Tianyub61df912018-10-16 14:55:39 -0700948TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
949 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
950 kUsage, kUserMetadataSize);
951 int b1_id = b1->id();
952 EXPECT_TRUE(b1->IsValid());
953 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700954 EXPECT_NE(b1->client_state_mask(), 0ULL);
Tianyub61df912018-10-16 14:55:39 -0700955
956 auto status_or_handle = b1->Duplicate();
957 EXPECT_TRUE(status_or_handle);
958
959 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700960 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700961 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700962
Tianyub61df912018-10-16 14:55:39 -0700963 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700964 LocalChannelHandle h2 = status_or_handle.take();
965 EXPECT_TRUE(h2.valid());
966
Tianyub61df912018-10-16 14:55:39 -0700967 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700968 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700969 ASSERT_TRUE(b2 != nullptr);
970 EXPECT_TRUE(b2->IsValid());
971 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Tianyu Jiang63dd7c32018-10-30 18:35:06 -0700972 EXPECT_NE(b2->client_state_mask(), 0ULL);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700973
Tianyub61df912018-10-16 14:55:39 -0700974 int b2_id = b2->id();
975
976 // These two buffer instances are based on the same physical buffer under the
977 // hood, so they should share the same id.
978 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700979 // We use client_state_mask() to tell those two instances apart.
980 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
Tianyub61df912018-10-16 14:55:39 -0700981
982 // Both buffer instances should be in gained state.
Tianyuf669f6a2018-10-10 15:34:32 -0700983 EXPECT_TRUE(IsBufferReleased(b1->buffer_state()));
984 EXPECT_TRUE(IsBufferReleased(b2->buffer_state()));
Tianyub61df912018-10-16 14:55:39 -0700985
986 // TODO(b/112338294) rewrite test after migration
987 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700988}