blob: 1359f4c13705ee6a9ae77e7e1b7f6f69f1b25872 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <gtest/gtest.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07002#include <poll.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07003#include <private/dvr/bufferhub_rpc.h>
Tianyu Jiang49642322018-12-18 11:08:03 -08004#include <private/dvr/consumer_buffer.h>
5#include <private/dvr/producer_buffer.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07006#include <sys/epoll.h>
7#include <sys/eventfd.h>
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -07008#include <ui/BufferHubBuffer.h>
Tianyu Jiang7359dc92018-12-13 11:22:28 -08009#include <ui/BufferHubDefs.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080010
11#include <mutex>
12#include <thread>
13
Alex Vakulenko4fe60582017-02-02 11:35:59 -080014#define RETRY_EINTR(fnc_call) \
15 ([&]() -> decltype(fnc_call) { \
16 decltype(fnc_call) result; \
17 do { \
18 result = (fnc_call); \
19 } while (result == -1 && errno == EINTR); \
20 return result; \
21 })()
22
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -070023using android::BufferHubBuffer;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070024using android::GraphicBuffer;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070025using android::sp;
Tianyu Jiang7359dc92018-12-13 11:22:28 -080026using android::BufferHubDefs::AnyClientAcquired;
27using android::BufferHubDefs::AnyClientGained;
28using android::BufferHubDefs::AnyClientPosted;
29using android::BufferHubDefs::IsBufferReleased;
30using android::BufferHubDefs::IsClientAcquired;
31using android::BufferHubDefs::IsClientPosted;
32using android::BufferHubDefs::IsClientReleased;
33using android::BufferHubDefs::kFirstClientBitMask;
34using android::BufferHubDefs::kMetadataHeaderSize;
Tianyu1a60bb42018-10-08 14:56:08 -070035using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070036using android::dvr::ProducerBuffer;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070037using android::pdx::LocalChannelHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080038using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070039using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080040
41const int kWidth = 640;
42const int kHeight = 480;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070043const int kLayerCount = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080044const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
45const int kUsage = 0;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070046const size_t kUserMetadataSize = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070047// Maximum number of consumers for the buffer that only has one producer in the
48// test.
49const size_t kMaxConsumerCount =
Tianyu Jiang7359dc92018-12-13 11:22:28 -080050 android::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080051const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052
53using LibBufferHubTest = ::testing::Test;
54
55TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070056 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
58 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070059 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070060 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070061 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070063 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070064 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080065 ASSERT_TRUE(c2.get() != nullptr);
66
Tianyuf669f6a2018-10-10 15:34:32 -070067 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070068 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070069 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
70 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070071
72 // Initial state: producer not available, consumers not available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080073 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070074 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080075 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070076
Tianyuf669f6a2018-10-10 15:34:32 -070077 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070078 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070079
80 // New state: producer not available, consumers available.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080081 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070082 EXPECT_EQ(1, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080083 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080085 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070086 EXPECT_EQ(0, c1->Acquire(&fence));
87 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080088 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089
Tianyu58a05a22018-10-10 18:41:27 -070090 EXPECT_EQ(0, c2->Acquire(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080091 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070092 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080093
Tianyuf669f6a2018-10-10 15:34:32 -070094 EXPECT_EQ(0, c1->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080095 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080096 EXPECT_EQ(0, c2->Discard());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080097 EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -070098
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080099 EXPECT_EQ(0, p->Gain(&fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800100 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700101 EXPECT_EQ(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800102 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700103}
104
105TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700106 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700107 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
108 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700109 std::unique_ptr<ConsumerBuffer> c =
110 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700111 ASSERT_TRUE(c.get() != nullptr);
112
113 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
114 ASSERT_TRUE(epoll_fd.IsValid());
115
116 epoll_event event;
117 std::array<epoll_event, 64> events;
118
119 auto event_sources = p->GetEventSources();
120 ASSERT_LT(event_sources.size(), events.size());
121
122 for (const auto& event_source : event_sources) {
123 event = {.events = event_source.event_mask | EPOLLET,
124 .data = {.fd = p->event_fd()}};
125 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
126 &event));
127 }
128
129 event_sources = c->GetEventSources();
130 ASSERT_LT(event_sources.size(), events.size());
131
132 for (const auto& event_source : event_sources) {
133 event = {.events = event_source.event_mask | EPOLLET,
134 .data = {.fd = c->event_fd()}};
135 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
136 &event));
137 }
138
139 // No events should be signaled initially.
140 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
141
Tianyuf669f6a2018-10-10 15:34:32 -0700142 // Gain and post the producer and check for consumer signal.
143 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700144 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800145 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
146 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700147 ASSERT_TRUE(events[0].events & EPOLLIN);
148 ASSERT_EQ(c->event_fd(), events[0].data.fd);
149
150 // Save the event bits to translate later.
151 event = events[0];
152
153 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800154 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
155 kPollTimeoutMs));
156 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
157 kPollTimeoutMs));
158 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
159 kPollTimeoutMs));
160 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
161 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700162
163 // Translate the events.
164 auto event_status = c->GetEventMask(event.events);
165 ASSERT_TRUE(event_status);
166 ASSERT_TRUE(event_status.get() & EPOLLIN);
167
168 // Check for events again. Edge-triggered mode should prevent any.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800169 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
170 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700171}
172
173TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700174 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700175 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
176 ASSERT_TRUE(p.get() != nullptr);
177
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700178 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jianga99f9112018-12-13 18:23:07 -0800179 uint32_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700180 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700181 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700182 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700183 ASSERT_TRUE(cs[i].get() != nullptr);
184 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700185 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
186 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700187 }
Tianyu Jianga99f9112018-12-13 18:23:07 -0800188 EXPECT_EQ(client_state_masks, ~0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700189
190 // The 64th creation will fail with out-of-memory error.
191 auto state = p->CreateConsumer();
192 EXPECT_EQ(state.error(), E2BIG);
193
194 // Release any consumer should allow us to re-create.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700195 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700196 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700197 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700198 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700199 ASSERT_TRUE(cs[i].get() != nullptr);
200 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700201 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
202 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700203 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800204}
205
Corey Tabakad53870c2017-07-06 18:04:27 -0700206TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700207 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700208 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
209 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700210 std::unique_ptr<ConsumerBuffer> c =
211 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700212 ASSERT_TRUE(c.get() != nullptr);
213
Corey Tabakad53870c2017-07-06 18:04:27 -0700214 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700215 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700216
Tianyu Jiang60887c92018-11-14 15:52:38 -0800217 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700218 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700219
220 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700221 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700222
Tianyuf669f6a2018-10-10 15:34:32 -0700223 // Post and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700224 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700225 EXPECT_EQ(-EBUSY, p->Gain(&fence));
226
227 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700228 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700229
230 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700231 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700232 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700233 EXPECT_EQ(-EBUSY, p->Gain(&fence));
234
235 // Release in acquired state should succeed.
236 EXPECT_EQ(0, c->Release(LocalHandle()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800237 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700238
Tianyuf669f6a2018-10-10 15:34:32 -0700239 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700240 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700241 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700242
243 // Gain in released state should succeed.
244 EXPECT_EQ(0, p->Gain(&fence));
245
Tianyu Jiang60887c92018-11-14 15:52:38 -0800246 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700247 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700248}
249
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700250TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700251 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700252 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
253 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700254 std::unique_ptr<ConsumerBuffer> c =
255 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700256 ASSERT_TRUE(c.get() != nullptr);
257
258 DvrNativeBufferMetadata metadata;
259 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700260 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700261
Tianyu Jiang60887c92018-11-14 15:52:38 -0800262 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700263 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
264 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700265 EXPECT_FALSE(invalid_fence.IsValid());
266
267 // Post in gained state should succeed.
268 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
269 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700270 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700271
Tianyuf669f6a2018-10-10 15:34:32 -0700272 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700273 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700274 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
275 EXPECT_FALSE(invalid_fence.IsValid());
276
277 // Acquire in posted state should succeed.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800278 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700279 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
280 EXPECT_FALSE(invalid_fence.IsValid());
281 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700282 EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700283
284 // Acquire, post, and gain in acquired state should fail.
285 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
286 EXPECT_FALSE(invalid_fence.IsValid());
287 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
288 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
289 EXPECT_FALSE(invalid_fence.IsValid());
290
291 // Release in acquired state should succeed.
292 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800293 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700294 EXPECT_EQ(p->buffer_state(), c->buffer_state());
295 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
296
Tianyuf669f6a2018-10-10 15:34:32 -0700297 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700298 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
299 EXPECT_FALSE(invalid_fence.IsValid());
300 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
301
302 // Gain in released state should succeed.
303 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
304 EXPECT_FALSE(invalid_fence.IsValid());
305 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyuf669f6a2018-10-10 15:34:32 -0700306 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700307
Tianyuf669f6a2018-10-10 15:34:32 -0700308 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700309 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
310 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800311}
312
313TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
314 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
315 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
316 ASSERT_TRUE(p.get() != nullptr);
317
318 ASSERT_EQ(0, p->GainAsync());
319 ASSERT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700320}
321
Tianyu5465d6c2018-08-14 13:03:10 -0700322TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
323 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
324 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
325 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700326 std::unique_ptr<ConsumerBuffer> c =
327 ConsumerBuffer::Import(p->CreateConsumer());
328 ASSERT_TRUE(c.get() != nullptr);
329 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700330 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700331 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700332
333 // Gain in posted state should only succeed with gain_posted_buffer = true.
334 LocalHandle invalid_fence;
335 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
336 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
337}
338
339TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
340 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
341 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
342 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700343 std::unique_ptr<ConsumerBuffer> c =
344 ConsumerBuffer::Import(p->CreateConsumer());
345 ASSERT_TRUE(c.get() != nullptr);
346 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700347 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyuf669f6a2018-10-10 15:34:32 -0700348 ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700349
350 // GainAsync in posted state should only succeed with gain_posted_buffer
351 // equals true.
352 DvrNativeBufferMetadata metadata;
353 LocalHandle invalid_fence;
354 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
355 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
356}
357
Tianyuf669f6a2018-10-10 15:34:32 -0700358TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700359 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700360 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
361 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700362 ASSERT_EQ(0, p->GainAsync());
363 ASSERT_EQ(0, p->Post(LocalHandle()));
364 // Producer state bit is in released state after post. The overall state of
365 // the buffer is also released because there is no consumer of this buffer.
366 ASSERT_TRUE(IsBufferReleased(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700367
Tianyuf669f6a2018-10-10 15:34:32 -0700368 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700369 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700370 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700371}
372
373TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700374 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700375 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
376 ASSERT_TRUE(p.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800377 uint32_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700378
Tianyu1a60bb42018-10-08 14:56:08 -0700379 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700380 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700381 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700382 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700383 EXPECT_TRUE(IsBufferReleased(cs[i]->buffer_state()));
384 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700385 }
386
Tianyuf669f6a2018-10-10 15:34:32 -0700387 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700388 DvrNativeBufferMetadata metadata;
389 LocalHandle invalid_fence;
390
391 // Post the producer should trigger all consumers to be available.
392 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700393 EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
394 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700395 EXPECT_TRUE(
Tianyuf669f6a2018-10-10 15:34:32 -0700396 IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800397 EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700398 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700399 EXPECT_TRUE(
400 IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700401 }
402
403 // All consumers have to release before the buffer is considered to be
404 // released.
405 for (size_t i = 0; i < kMaxConsumerCount; i++) {
406 EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
407 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
408 }
409
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800410 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700411 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
412
413 // Buffer state cross all clients must be consistent.
414 for (size_t i = 0; i < kMaxConsumerCount; i++) {
415 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
416 }
417}
418
419TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700420 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700421 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
422 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700423 EXPECT_EQ(0, p->GainAsync());
424 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700425
Tianyu1a60bb42018-10-08 14:56:08 -0700426 std::unique_ptr<ConsumerBuffer> c =
427 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700428 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700429 EXPECT_TRUE(AnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700430
431 DvrNativeBufferMetadata metadata;
432 LocalHandle invalid_fence;
433
434 // Post the gained buffer should signal already created consumer.
435 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700436 EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800437 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700438 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700439 EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700440}
441
Tianyuf669f6a2018-10-10 15:34:32 -0700442TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700443 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700444 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
445 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700446 EXPECT_EQ(0, p->GainAsync());
447 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700448
449 DvrNativeBufferMetadata metadata;
450 LocalHandle invalid_fence;
451
452 // Post the gained buffer before any consumer gets created.
Tianyuf669f6a2018-10-10 15:34:32 -0700453 // The buffer should be in released state because it is not expected to be
454 // read by any clients.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700455 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700456 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
457 EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700458
Tianyuf669f6a2018-10-10 15:34:32 -0700459 // Newly created consumer will not be signalled for the posted buffer before
460 // its creation. It cannot acquire the buffer immediately.
Tianyu1a60bb42018-10-08 14:56:08 -0700461 std::unique_ptr<ConsumerBuffer> c =
462 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700463 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700464 EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
465 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
466
467 // Producer should be able to gain back and post the buffer
468 EXPECT_EQ(0, p->GainAsync());
469 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
470
471 // Consumer should be able to pick up the buffer this time.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700472 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700473 EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700474}
475
476TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700477 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700478 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
479 ASSERT_TRUE(p.get() != nullptr);
480
Tianyu1a60bb42018-10-08 14:56:08 -0700481 std::unique_ptr<ConsumerBuffer> c1 =
482 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700483 ASSERT_TRUE(c1.get() != nullptr);
484
Tianyuf669f6a2018-10-10 15:34:32 -0700485 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700486 DvrNativeBufferMetadata metadata;
487 LocalHandle invalid_fence;
488
489 // Post, acquire, and release the buffer..
490 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800491 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700492 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
493 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
494
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800495 // Note that the next PDX call is on the producer channel, which may be
496 // executed before Release impulse gets executed by bufferhubd. Thus, here we
497 // need to wait until the releasd is confirmed before creating another
498 // consumer.
499 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
500 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
501
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700502 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800503 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700504 std::unique_ptr<ConsumerBuffer> c2 =
505 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700506 ASSERT_TRUE(c2.get() != nullptr);
507
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700508 EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
509 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700510 EXPECT_TRUE(AnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700511}
512
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800513TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
514 struct Metadata {
515 int64_t field1;
516 int64_t field2;
517 };
Tianyu1a60bb42018-10-08 14:56:08 -0700518 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
520 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700521 std::unique_ptr<ConsumerBuffer> c =
522 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800523 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700524 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800525 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700526 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800527 EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800528 LocalHandle fence;
529 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700530 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800531 EXPECT_EQ(m.field1, m2.field1);
532 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800533 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800534 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800535}
536
537TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
538 struct Metadata {
539 int64_t field1;
540 int64_t field2;
541 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700542 struct OverSizedMetadata {
543 int64_t field1;
544 int64_t field2;
545 int64_t field3;
546 };
Tianyu1a60bb42018-10-08 14:56:08 -0700547 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800548 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
549 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700550 std::unique_ptr<ConsumerBuffer> c =
551 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800552 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700553 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800554
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700555 // It is illegal to post metadata larger than originally requested during
556 // buffer allocation.
557 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700558 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800559 EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700560
561 // It is ok to post metadata smaller than originally requested during
562 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700563 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800564}
565
566TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
567 struct Metadata {
568 int64_t field1;
569 int64_t field2;
570 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700571 struct OverSizedMetadata {
572 int64_t field1;
573 int64_t field2;
574 int64_t field3;
575 };
Tianyu1a60bb42018-10-08 14:56:08 -0700576 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800577 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
578 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700579 std::unique_ptr<ConsumerBuffer> c =
580 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800581 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700582 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800583
584 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700585 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800586
587 LocalHandle fence;
588 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700589 OverSizedMetadata e;
590
591 // It is illegal to acquire metadata larger than originally requested during
592 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700593 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700594
595 // It is ok to acquire metadata smaller than originally requested during
596 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700597 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700598 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800599}
600
601TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700602 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800603 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
604 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700605 std::unique_ptr<ConsumerBuffer> c =
606 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800607 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700608 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800609
610 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700611 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800612
613 LocalHandle fence;
614 EXPECT_EQ(0, c->Acquire(&fence));
615}
616
617TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700618 std::unique_ptr<ProducerBuffer> p =
619 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800620 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700621 std::unique_ptr<ConsumerBuffer> c =
622 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800623 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700624 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800625
626 LocalHandle fence;
627
Tianyue6e08ab2018-09-13 18:48:55 -0700628 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800629 EXPECT_EQ(0, c->Acquire(&fence));
630}
631
632TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700633 std::unique_ptr<ProducerBuffer> p =
634 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800635 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700636 std::unique_ptr<ConsumerBuffer> c =
637 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800638 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700639 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800640
641 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700642 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800643}
644
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700645namespace {
646
647int PollFd(int fd, int timeout_ms) {
648 pollfd p = {fd, POLLIN, 0};
649 return poll(&p, 1, timeout_ms);
650}
651
652} // namespace
653
654TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700655 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700656 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
657 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700658 std::unique_ptr<ConsumerBuffer> c =
659 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700660 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700661 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700662
663 DvrNativeBufferMetadata meta;
664 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
665
666 // Post with unsignaled fence.
667 EXPECT_EQ(0, p->PostAsync(&meta, f1));
668
669 // Should acquire a valid fence.
670 LocalHandle f2;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800671 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700672 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
673 EXPECT_TRUE(f2.IsValid());
674 // The original fence and acquired fence should have different fd number.
675 EXPECT_NE(f1.Get(), f2.Get());
676 EXPECT_GE(0, PollFd(f2.Get(), 0));
677
678 // Signal the original fence will trigger the new fence.
679 eventfd_write(f1.Get(), 1);
680 // Now the original FD has been signaled.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800681 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700682
683 // Release the consumer with an invalid fence.
684 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
685
686 // Should gain an invalid fence.
687 LocalHandle f3;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800688 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700689 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
690 EXPECT_FALSE(f3.IsValid());
691
692 // Post with a signaled fence.
693 EXPECT_EQ(0, p->PostAsync(&meta, f1));
694
695 // Should acquire a valid fence and it's already signalled.
696 LocalHandle f4;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800697 EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700698 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
699 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800700 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700701
702 // Release with an unsignalled fence and signal it immediately after release
703 // without producer gainning.
704 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
705 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
706 eventfd_write(f5.Get(), 1);
707
708 // Should gain a valid fence, which is already signaled.
709 LocalHandle f6;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800710 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700711 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
712 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800713 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700714}
715
716TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700717 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700718 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
719 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700720 std::unique_ptr<ConsumerBuffer> c1 =
721 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700722 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800723 const uint32_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700724
Tianyuf669f6a2018-10-10 15:34:32 -0700725 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700726 DvrNativeBufferMetadata meta;
727 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
728
729 LocalHandle fence;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800730 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700731 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700732
Tianyuf669f6a2018-10-10 15:34:32 -0700733 // Destroy the consumer who has acquired but not released the buffer.
734 c1 = nullptr;
735
736 // The buffer is now available for the producer to gain.
737 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
738
739 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700740 std::unique_ptr<ConsumerBuffer> c2 =
741 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700742 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800743 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700744 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyuf669f6a2018-10-10 15:34:32 -0700745 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
746 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700747
Tianyuf669f6a2018-10-10 15:34:32 -0700748 // Producer should be able to gain.
749 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
750}
751
752TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
753 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
754 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
755 ASSERT_TRUE(p.get() != nullptr);
756 std::unique_ptr<ConsumerBuffer> c1 =
757 ConsumerBuffer::Import(p->CreateConsumer());
758 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800759 const uint32_t client_state_mask1 = c1->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700760
761 EXPECT_EQ(0, p->GainAsync());
762 DvrNativeBufferMetadata meta;
763 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
764 EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
765
766 // c2 is created when the buffer is in posted state. buffer state for c1 is
767 // posted. Thus, c2 should be automatically set to posted and able to acquire.
768 std::unique_ptr<ConsumerBuffer> c2 =
769 ConsumerBuffer::Import(p->CreateConsumer());
770 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800771 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700772 EXPECT_NE(client_state_mask1, client_state_mask2);
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800773 EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
Tianyuf669f6a2018-10-10 15:34:32 -0700774 LocalHandle invalid_fence;
775 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700776
Tianyuf669f6a2018-10-10 15:34:32 -0700777 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700778
Tianyuf669f6a2018-10-10 15:34:32 -0700779 // c3 is created when the buffer is in acquired state. buffer state for c1 and
780 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
781 // acquire.
Tianyu1a60bb42018-10-08 14:56:08 -0700782 std::unique_ptr<ConsumerBuffer> c3 =
783 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700784 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800785 const uint32_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700786 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700787 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyuf669f6a2018-10-10 15:34:32 -0700788 EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
789 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700790
Tianyuf669f6a2018-10-10 15:34:32 -0700791 // Releasing c2 and c3 in normal ways.
792 EXPECT_EQ(0, c2->Release(LocalHandle()));
793 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
794
795 // Destroy the c1 who has not released the buffer.
796 c1 = nullptr;
797
798 // The buffer is now available for the producer to gain.
799 EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
800
801 // C4 is created in released state. Thus, it cannot gain the just posted
802 // buffer.
803 std::unique_ptr<ConsumerBuffer> c4 =
804 ConsumerBuffer::Import(p->CreateConsumer());
805 ASSERT_TRUE(c4.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800806 const uint32_t client_state_mask4 = c4->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700807 EXPECT_NE(client_state_mask3, client_state_mask4);
808 EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
809 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
810
811 // Producer should be able to gain.
812 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700813}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700814
815TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700816 // TODO(b/112338294) rewrite test after migration
817 return;
818
Tianyu1a60bb42018-10-08 14:56:08 -0700819 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700820 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700821 std::unique_ptr<ConsumerBuffer> c =
822 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700823 ASSERT_TRUE(p.get() != nullptr);
824 ASSERT_TRUE(c.get() != nullptr);
825
826 DvrNativeBufferMetadata metadata;
827 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700828 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700829
830 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700831 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700832 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
833 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
834 auto s1 = p->Detach();
835 EXPECT_FALSE(s1);
836
837 // Detach in acquired state should fail.
838 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
839 s1 = p->Detach();
840 EXPECT_FALSE(s1);
841
842 // Detach in released state should fail.
843 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
844 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
845 s1 = p->Detach();
846 EXPECT_FALSE(s1);
847
848 // Detach in gained state should succeed.
849 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
850 s1 = p->Detach();
851 EXPECT_TRUE(s1);
852
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700853 LocalChannelHandle handle = s1.take();
854 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700855
856 // Both producer and consumer should have hangup.
857 EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0);
858 auto s2 = p->GetEventMask(POLLHUP);
859 EXPECT_TRUE(s2);
860 EXPECT_EQ(s2.get(), POLLHUP);
861
862 EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0);
863 s2 = p->GetEventMask(POLLHUP);
864 EXPECT_TRUE(s2);
865 EXPECT_EQ(s2.get(), POLLHUP);
866
867 auto s3 = p->CreateConsumer();
868 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700869 // Note that here the expected error code is EOPNOTSUPP as the socket towards
870 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700871 EXPECT_EQ(s3.error(), EOPNOTSUPP);
872
873 s3 = c->CreateConsumer();
874 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700875 // Note that here the expected error code is EPIPE returned from
876 // ConsumerChannel::HandleMessage as the socket is still open but the producer
877 // is gone.
878 EXPECT_EQ(s3.error(), EPIPE);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700879
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700880 // Detached buffer handle can be use to construct a new BufferHubBuffer
881 // object.
882 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700883 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700884 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700885 EXPECT_TRUE(d->IsValid());
886
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700887 EXPECT_EQ(d->id(), p_id);
888}
889
Tianyub61df912018-10-16 14:55:39 -0700890TEST_F(LibBufferHubTest, TestCreateBufferHubBufferFails) {
891 // Buffer Creation will fail: BLOB format requires height to be 1.
892 auto b1 = BufferHubBuffer::Create(kWidth, /*height=2*/ 2, kLayerCount,
893 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage,
894 kUserMetadataSize);
Fan Xuddb90db2018-10-03 10:09:14 -0700895
Tianyub61df912018-10-16 14:55:39 -0700896 EXPECT_FALSE(b1->IsConnected());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700897 EXPECT_FALSE(b1->IsValid());
898
Tianyub61df912018-10-16 14:55:39 -0700899 // Buffer Creation will fail: user metadata size too large.
900 auto b2 = BufferHubBuffer::Create(
901 kWidth, kHeight, kLayerCount, kFormat, kUsage,
902 /*user_metadata_size=*/std::numeric_limits<size_t>::max());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700903
Tianyub61df912018-10-16 14:55:39 -0700904 EXPECT_FALSE(b2->IsConnected());
905 EXPECT_FALSE(b2->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700906
Tianyub61df912018-10-16 14:55:39 -0700907 // Buffer Creation will fail: user metadata size too large.
908 auto b3 = BufferHubBuffer::Create(
909 kWidth, kHeight, kLayerCount, kFormat, kUsage,
910 /*user_metadata_size=*/std::numeric_limits<size_t>::max() -
911 kMetadataHeaderSize);
912
913 EXPECT_FALSE(b3->IsConnected());
914 EXPECT_FALSE(b3->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700915}
916
Tianyub61df912018-10-16 14:55:39 -0700917TEST_F(LibBufferHubTest, TestCreateBufferHubBuffer) {
918 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
919 kUsage, kUserMetadataSize);
920 EXPECT_TRUE(b1->IsConnected());
921 EXPECT_TRUE(b1->IsValid());
922 EXPECT_NE(b1->id(), 0);
923}
924
925TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700926 // TODO(b/112338294) rewrite test after migration
927 return;
928
Tianyu1a60bb42018-10-08 14:56:08 -0700929 std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700930 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
931 ASSERT_TRUE(p1.get() != nullptr);
932 int p1_id = p1->id();
933
Tianyuf669f6a2018-10-10 15:34:32 -0700934 // Detached the producer from gained state.
935 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700936 auto status_or_handle = p1->Detach();
937 EXPECT_TRUE(status_or_handle.ok());
938 LocalChannelHandle h1 = status_or_handle.take();
939 EXPECT_TRUE(h1.valid());
940
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700941 // Detached buffer handle can be use to construct a new BufferHubBuffer
942 // object.
943 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700944 EXPECT_FALSE(h1.valid());
945 EXPECT_TRUE(b1->IsValid());
946 int b1_id = b1->id();
947 EXPECT_EQ(b1_id, p1_id);
Tianyub61df912018-10-16 14:55:39 -0700948}
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700949
Tianyub61df912018-10-16 14:55:39 -0700950TEST_F(LibBufferHubTest, TestDuplicateBufferHubBuffer) {
951 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
952 kUsage, kUserMetadataSize);
953 int b1_id = b1->id();
954 EXPECT_TRUE(b1->IsValid());
955 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800956 EXPECT_NE(b1->client_state_mask(), 0U);
Tianyub61df912018-10-16 14:55:39 -0700957
958 auto status_or_handle = b1->Duplicate();
959 EXPECT_TRUE(status_or_handle);
960
961 // The detached buffer should still be valid.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700962 EXPECT_TRUE(b1->IsConnected());
Tianyub61df912018-10-16 14:55:39 -0700963 EXPECT_TRUE(b1->IsValid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700964
Tianyub61df912018-10-16 14:55:39 -0700965 // Gets the channel handle for the duplicated buffer.
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700966 LocalChannelHandle h2 = status_or_handle.take();
967 EXPECT_TRUE(h2.valid());
968
Tianyub61df912018-10-16 14:55:39 -0700969 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700970 EXPECT_FALSE(h2.valid());
Tianyub61df912018-10-16 14:55:39 -0700971 ASSERT_TRUE(b2 != nullptr);
972 EXPECT_TRUE(b2->IsValid());
973 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800974 EXPECT_NE(b2->client_state_mask(), 0U);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700975
Tianyub61df912018-10-16 14:55:39 -0700976 int b2_id = b2->id();
977
978 // These two buffer instances are based on the same physical buffer under the
979 // hood, so they should share the same id.
980 EXPECT_EQ(b1_id, b2_id);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700981 // We use client_state_mask() to tell those two instances apart.
982 EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
Tianyub61df912018-10-16 14:55:39 -0700983
984 // Both buffer instances should be in gained state.
Tianyuf669f6a2018-10-10 15:34:32 -0700985 EXPECT_TRUE(IsBufferReleased(b1->buffer_state()));
986 EXPECT_TRUE(IsBufferReleased(b2->buffer_state()));
Tianyub61df912018-10-16 14:55:39 -0700987
988 // TODO(b/112338294) rewrite test after migration
989 return;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700990}