1 #include <gtest/gtest.h> 2 #include <poll.h> 3 #include <private/dvr/bufferhub_rpc.h> 4 #include <private/dvr/consumer_buffer.h> 5 #include <private/dvr/producer_buffer.h> 6 #include <sys/epoll.h> 7 #include <sys/eventfd.h> 8 #include <ui/BufferHubDefs.h> 9 10 #include <mutex> 11 #include <thread> 12 13 namespace { 14 #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 23 using android::BufferHubDefs::isAnyClientAcquired; 24 using android::BufferHubDefs::isAnyClientGained; 25 using android::BufferHubDefs::isAnyClientPosted; 26 using android::BufferHubDefs::isClientAcquired; 27 using android::BufferHubDefs::isClientPosted; 28 using android::BufferHubDefs::isClientReleased; 29 using android::BufferHubDefs::kFirstClientBitMask; 30 using android::dvr::ConsumerBuffer; 31 using android::dvr::ProducerBuffer; 32 using android::pdx::LocalHandle; 33 using android::pdx::Status; 34 using LibBufferHubTest = ::testing::Test; 35 36 const int kWidth = 640; 37 const int kHeight = 480; 38 const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888; 39 const int kUsage = 0; 40 // Maximum number of consumers for the buffer that only has one producer in the 41 // test. 42 const size_t kMaxConsumerCount = 43 android::BufferHubDefs::kMaxNumberOfClients - 1; 44 const int kPollTimeoutMs = 100; 45 46 // Helper function to poll the eventfd in BufferHubBase. 47 template <class BufferHubBase> 48 int PollBufferEvent(const std::unique_ptr<BufferHubBase>& buffer, 49 int timeout_ms = kPollTimeoutMs) { 50 pollfd p = {buffer->event_fd(), POLLIN, 0}; 51 return poll(&p, 1, timeout_ms); 52 } 53 54 } // namespace 55 56 TEST_F(LibBufferHubTest, TestBasicUsage) { 57 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 58 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 59 ASSERT_TRUE(p.get() != nullptr); 60 std::unique_ptr<ConsumerBuffer> c1 = 61 ConsumerBuffer::Import(p->CreateConsumer()); 62 ASSERT_TRUE(c1.get() != nullptr); 63 // Check that consumers can spawn other consumers. 64 std::unique_ptr<ConsumerBuffer> c2 = 65 ConsumerBuffer::Import(c1->CreateConsumer()); 66 ASSERT_TRUE(c2.get() != nullptr); 67 68 // Checks the state masks of client p, c1 and c2. 69 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask); 70 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1); 71 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2); 72 73 // Initial state: producer not available, consumers not available. 74 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p))); 75 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1))); 76 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2))); 77 78 EXPECT_EQ(0, p->GainAsync()); 79 EXPECT_EQ(0, p->Post(LocalHandle())); 80 81 // New state: producer not available, consumers available. 82 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p))); 83 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c1))); 84 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2))); 85 86 LocalHandle fence; 87 EXPECT_EQ(0, c1->Acquire(&fence)); 88 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1))); 89 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2))); 90 91 EXPECT_EQ(0, c2->Acquire(&fence)); 92 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2))); 93 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1))); 94 95 EXPECT_EQ(0, c1->Release(LocalHandle())); 96 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p))); 97 EXPECT_EQ(0, c2->Discard()); 98 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(p))); 99 100 EXPECT_EQ(0, p->Gain(&fence)); 101 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p))); 102 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1))); 103 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2))); 104 } 105 106 TEST_F(LibBufferHubTest, TestEpoll) { 107 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 108 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 109 ASSERT_TRUE(p.get() != nullptr); 110 std::unique_ptr<ConsumerBuffer> c = 111 ConsumerBuffer::Import(p->CreateConsumer()); 112 ASSERT_TRUE(c.get() != nullptr); 113 114 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)}; 115 ASSERT_TRUE(epoll_fd.IsValid()); 116 117 epoll_event event; 118 std::array<epoll_event, 64> events; 119 120 auto event_sources = p->GetEventSources(); 121 ASSERT_LT(event_sources.size(), events.size()); 122 123 for (const auto& event_source : event_sources) { 124 event = {.events = event_source.event_mask | EPOLLET, 125 .data = {.fd = p->event_fd()}}; 126 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd, 127 &event)); 128 } 129 130 event_sources = c->GetEventSources(); 131 ASSERT_LT(event_sources.size(), events.size()); 132 133 for (const auto& event_source : event_sources) { 134 event = {.events = event_source.event_mask | EPOLLET, 135 .data = {.fd = c->event_fd()}}; 136 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd, 137 &event)); 138 } 139 140 // No events should be signaled initially. 141 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0)); 142 143 // Gain and post the producer and check for consumer signal. 144 EXPECT_EQ(0, p->GainAsync()); 145 EXPECT_EQ(0, p->Post({})); 146 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 147 kPollTimeoutMs)); 148 ASSERT_TRUE(events[0].events & EPOLLIN); 149 ASSERT_EQ(c->event_fd(), events[0].data.fd); 150 151 // Save the event bits to translate later. 152 event = events[0]; 153 154 // Check for events again. Edge-triggered mode should prevent any. 155 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 156 kPollTimeoutMs)); 157 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 158 kPollTimeoutMs)); 159 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 160 kPollTimeoutMs)); 161 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 162 kPollTimeoutMs)); 163 164 // Translate the events. 165 auto event_status = c->GetEventMask(event.events); 166 ASSERT_TRUE(event_status); 167 ASSERT_TRUE(event_status.get() & EPOLLIN); 168 169 // Check for events again. Edge-triggered mode should prevent any. 170 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 171 kPollTimeoutMs)); 172 } 173 174 TEST_F(LibBufferHubTest, TestStateMask) { 175 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 176 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 177 ASSERT_TRUE(p.get() != nullptr); 178 179 // It's ok to create up to kMaxConsumerCount consumer buffers. 180 uint32_t client_state_masks = p->client_state_mask(); 181 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs; 182 for (size_t i = 0; i < kMaxConsumerCount; i++) { 183 cs[i] = ConsumerBuffer::Import(p->CreateConsumer()); 184 ASSERT_TRUE(cs[i].get() != nullptr); 185 // Expect all buffers have unique state mask. 186 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U); 187 client_state_masks |= cs[i]->client_state_mask(); 188 } 189 EXPECT_EQ(client_state_masks, ~0U); 190 191 // The 64th creation will fail with out-of-memory error. 192 auto state = p->CreateConsumer(); 193 EXPECT_EQ(state.error(), E2BIG); 194 195 // Release any consumer should allow us to re-create. 196 for (size_t i = 0; i < kMaxConsumerCount; i++) { 197 client_state_masks &= ~cs[i]->client_state_mask(); 198 cs[i] = nullptr; 199 cs[i] = ConsumerBuffer::Import(p->CreateConsumer()); 200 ASSERT_TRUE(cs[i].get() != nullptr); 201 // The released state mask will be reused. 202 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U); 203 client_state_masks |= cs[i]->client_state_mask(); 204 } 205 } 206 207 TEST_F(LibBufferHubTest, TestStateTransitions) { 208 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 209 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 210 ASSERT_TRUE(p.get() != nullptr); 211 std::unique_ptr<ConsumerBuffer> c = 212 ConsumerBuffer::Import(p->CreateConsumer()); 213 ASSERT_TRUE(c.get() != nullptr); 214 215 LocalHandle fence; 216 EXPECT_EQ(0, p->GainAsync()); 217 218 // Acquire in gained state should fail. 219 EXPECT_EQ(-EBUSY, c->Acquire(&fence)); 220 221 // Post in gained state should succeed. 222 EXPECT_EQ(0, p->Post(LocalHandle())); 223 224 // Post and gain in posted state should fail. 225 EXPECT_EQ(-EBUSY, p->Post(LocalHandle())); 226 EXPECT_EQ(-EBUSY, p->Gain(&fence)); 227 228 // Acquire in posted state should succeed. 229 EXPECT_EQ(0, c->Acquire(&fence)); 230 231 // Acquire, post, and gain in acquired state should fail. 232 EXPECT_EQ(-EBUSY, c->Acquire(&fence)); 233 EXPECT_EQ(-EBUSY, p->Post(LocalHandle())); 234 EXPECT_EQ(-EBUSY, p->Gain(&fence)); 235 236 // Release in acquired state should succeed. 237 EXPECT_EQ(0, c->Release(LocalHandle())); 238 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 239 240 // Acquire and post in released state should fail. 241 EXPECT_EQ(-EBUSY, c->Acquire(&fence)); 242 EXPECT_EQ(-EBUSY, p->Post(LocalHandle())); 243 244 // Gain in released state should succeed. 245 EXPECT_EQ(0, p->Gain(&fence)); 246 247 // Acquire in gained state should fail. 248 EXPECT_EQ(-EBUSY, c->Acquire(&fence)); 249 } 250 251 TEST_F(LibBufferHubTest, TestAsyncStateTransitions) { 252 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 253 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 254 ASSERT_TRUE(p.get() != nullptr); 255 std::unique_ptr<ConsumerBuffer> c = 256 ConsumerBuffer::Import(p->CreateConsumer()); 257 ASSERT_TRUE(c.get() != nullptr); 258 259 DvrNativeBufferMetadata metadata; 260 LocalHandle invalid_fence; 261 EXPECT_EQ(0, p->GainAsync()); 262 263 // Acquire in gained state should fail. 264 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence)); 265 EXPECT_FALSE(invalid_fence.IsValid()); 266 EXPECT_FALSE(invalid_fence.IsValid()); 267 268 // Post in gained state should succeed. 269 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); 270 EXPECT_EQ(p->buffer_state(), c->buffer_state()); 271 EXPECT_TRUE(isAnyClientPosted(p->buffer_state())); 272 273 // Post and gain in posted state should fail. 274 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence)); 275 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence)); 276 EXPECT_FALSE(invalid_fence.IsValid()); 277 278 // Acquire in posted state should succeed. 279 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c))); 280 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); 281 EXPECT_FALSE(invalid_fence.IsValid()); 282 EXPECT_EQ(p->buffer_state(), c->buffer_state()); 283 EXPECT_TRUE(isAnyClientAcquired(p->buffer_state())); 284 285 // Acquire, post, and gain in acquired state should fail. 286 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence)); 287 EXPECT_FALSE(invalid_fence.IsValid()); 288 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence)); 289 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence)); 290 EXPECT_FALSE(invalid_fence.IsValid()); 291 292 // Release in acquired state should succeed. 293 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence)); 294 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 295 EXPECT_EQ(p->buffer_state(), c->buffer_state()); 296 EXPECT_TRUE(p->is_released()); 297 298 // Acquire and post in released state should fail. 299 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence)); 300 EXPECT_FALSE(invalid_fence.IsValid()); 301 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence)); 302 303 // Gain in released state should succeed. 304 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); 305 EXPECT_FALSE(invalid_fence.IsValid()); 306 EXPECT_EQ(p->buffer_state(), c->buffer_state()); 307 EXPECT_TRUE(isAnyClientGained(p->buffer_state())); 308 309 // Acquire and gain in gained state should fail. 310 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence)); 311 EXPECT_FALSE(invalid_fence.IsValid()); 312 } 313 314 TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) { 315 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 316 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 317 ASSERT_TRUE(p.get() != nullptr); 318 319 ASSERT_EQ(0, p->GainAsync()); 320 ASSERT_EQ(0, p->GainAsync()); 321 } 322 323 TEST_F(LibBufferHubTest, TestGainPostedBuffer) { 324 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 325 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 326 ASSERT_TRUE(p.get() != nullptr); 327 std::unique_ptr<ConsumerBuffer> c = 328 ConsumerBuffer::Import(p->CreateConsumer()); 329 ASSERT_TRUE(c.get() != nullptr); 330 ASSERT_EQ(0, p->GainAsync()); 331 ASSERT_EQ(0, p->Post(LocalHandle())); 332 ASSERT_TRUE(isAnyClientPosted(p->buffer_state())); 333 334 // Gain in posted state should only succeed with gain_posted_buffer = true. 335 LocalHandle invalid_fence; 336 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false)); 337 EXPECT_EQ(0, p->Gain(&invalid_fence, true)); 338 } 339 340 TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) { 341 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 342 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 343 ASSERT_TRUE(p.get() != nullptr); 344 std::unique_ptr<ConsumerBuffer> c = 345 ConsumerBuffer::Import(p->CreateConsumer()); 346 ASSERT_TRUE(c.get() != nullptr); 347 ASSERT_EQ(0, p->GainAsync()); 348 ASSERT_EQ(0, p->Post(LocalHandle())); 349 ASSERT_TRUE(isAnyClientPosted(p->buffer_state())); 350 351 // GainAsync in posted state should only succeed with gain_posted_buffer 352 // equals true. 353 DvrNativeBufferMetadata metadata; 354 LocalHandle invalid_fence; 355 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false)); 356 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true)); 357 } 358 359 TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) { 360 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 361 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 362 ASSERT_TRUE(p.get() != nullptr); 363 ASSERT_EQ(0, p->GainAsync()); 364 ASSERT_EQ(0, p->Post(LocalHandle())); 365 // Producer state bit is in released state after post, other clients shall be 366 // in posted state although there is no consumer of this buffer yet. 367 ASSERT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask())); 368 ASSERT_TRUE(p->is_released()); 369 ASSERT_TRUE(isAnyClientPosted(p->buffer_state())); 370 371 // Gain in released state should succeed. 372 LocalHandle invalid_fence; 373 EXPECT_EQ(0, p->Gain(&invalid_fence, false)); 374 } 375 376 TEST_F(LibBufferHubTest, TestMaxConsumers) { 377 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 378 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 379 ASSERT_TRUE(p.get() != nullptr); 380 uint32_t producer_state_mask = p->client_state_mask(); 381 382 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs; 383 for (size_t i = 0; i < kMaxConsumerCount; ++i) { 384 cs[i] = ConsumerBuffer::Import(p->CreateConsumer()); 385 ASSERT_TRUE(cs[i].get() != nullptr); 386 EXPECT_TRUE(cs[i]->is_released()); 387 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask()); 388 } 389 390 EXPECT_EQ(0, p->GainAsync()); 391 DvrNativeBufferMetadata metadata; 392 LocalHandle invalid_fence; 393 394 // Post the producer should trigger all consumers to be available. 395 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); 396 EXPECT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask())); 397 for (size_t i = 0; i < kMaxConsumerCount; ++i) { 398 EXPECT_TRUE( 399 isClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask())); 400 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(cs[i]))); 401 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence)); 402 EXPECT_TRUE( 403 isClientAcquired(p->buffer_state(), cs[i]->client_state_mask())); 404 } 405 406 // All consumers have to release before the buffer is considered to be 407 // released. 408 for (size_t i = 0; i < kMaxConsumerCount; i++) { 409 EXPECT_FALSE(p->is_released()); 410 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence)); 411 } 412 413 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 414 EXPECT_TRUE(p->is_released()); 415 416 // Buffer state cross all clients must be consistent. 417 for (size_t i = 0; i < kMaxConsumerCount; i++) { 418 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state()); 419 } 420 } 421 422 TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) { 423 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 424 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 425 ASSERT_TRUE(p.get() != nullptr); 426 EXPECT_EQ(0, p->GainAsync()); 427 EXPECT_TRUE(isAnyClientGained(p->buffer_state())); 428 429 std::unique_ptr<ConsumerBuffer> c = 430 ConsumerBuffer::Import(p->CreateConsumer()); 431 ASSERT_TRUE(c.get() != nullptr); 432 EXPECT_TRUE(isAnyClientGained(c->buffer_state())); 433 434 DvrNativeBufferMetadata metadata; 435 LocalHandle invalid_fence; 436 437 // Post the gained buffer should signal already created consumer. 438 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); 439 EXPECT_TRUE(isAnyClientPosted(p->buffer_state())); 440 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c))); 441 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); 442 EXPECT_TRUE(isAnyClientAcquired(c->buffer_state())); 443 } 444 445 TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) { 446 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 447 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 448 ASSERT_TRUE(p.get() != nullptr); 449 EXPECT_EQ(0, p->GainAsync()); 450 EXPECT_TRUE(isAnyClientGained(p->buffer_state())); 451 452 DvrNativeBufferMetadata metadata; 453 LocalHandle invalid_fence; 454 455 // Post the gained buffer before any consumer gets created. 456 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); 457 EXPECT_TRUE(p->is_released()); 458 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p))); 459 460 // Newly created consumer will be signalled for the posted buffer although it 461 // is created after producer posting. 462 std::unique_ptr<ConsumerBuffer> c = 463 ConsumerBuffer::Import(p->CreateConsumer()); 464 ASSERT_TRUE(c.get() != nullptr); 465 EXPECT_TRUE(isClientPosted(c->buffer_state(), c->client_state_mask())); 466 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); 467 } 468 469 TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) { 470 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 471 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 472 ASSERT_TRUE(p.get() != nullptr); 473 474 std::unique_ptr<ConsumerBuffer> c1 = 475 ConsumerBuffer::Import(p->CreateConsumer()); 476 ASSERT_TRUE(c1.get() != nullptr); 477 478 EXPECT_EQ(0, p->GainAsync()); 479 DvrNativeBufferMetadata metadata; 480 LocalHandle invalid_fence; 481 482 // Post, acquire, and release the buffer.. 483 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); 484 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1))); 485 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence)); 486 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence)); 487 488 // Note that the next PDX call is on the producer channel, which may be 489 // executed before Release impulse gets executed by bufferhubd. Thus, here we 490 // need to wait until the releasd is confirmed before creating another 491 // consumer. 492 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 493 EXPECT_TRUE(p->is_released()); 494 495 // Create another consumer immediately after the release, should not make the 496 // buffer un-released. 497 std::unique_ptr<ConsumerBuffer> c2 = 498 ConsumerBuffer::Import(p->CreateConsumer()); 499 ASSERT_TRUE(c2.get() != nullptr); 500 501 EXPECT_TRUE(p->is_released()); 502 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); 503 EXPECT_TRUE(isAnyClientGained(p->buffer_state())); 504 } 505 506 TEST_F(LibBufferHubTest, TestWithCustomMetadata) { 507 struct Metadata { 508 int64_t field1; 509 int64_t field2; 510 }; 511 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 512 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata)); 513 ASSERT_TRUE(p.get() != nullptr); 514 std::unique_ptr<ConsumerBuffer> c = 515 ConsumerBuffer::Import(p->CreateConsumer()); 516 ASSERT_TRUE(c.get() != nullptr); 517 EXPECT_EQ(0, p->GainAsync()); 518 Metadata m = {1, 3}; 519 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata))); 520 EXPECT_LE(0, RETRY_EINTR(PollBufferEvent(c))); 521 LocalHandle fence; 522 Metadata m2 = {}; 523 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2))); 524 EXPECT_EQ(m.field1, m2.field1); 525 EXPECT_EQ(m.field2, m2.field2); 526 EXPECT_EQ(0, c->Release(LocalHandle())); 527 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p, /*timeout_ms=*/0))); 528 } 529 530 TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) { 531 struct Metadata { 532 int64_t field1; 533 int64_t field2; 534 }; 535 struct OverSizedMetadata { 536 int64_t field1; 537 int64_t field2; 538 int64_t field3; 539 }; 540 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 541 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata)); 542 ASSERT_TRUE(p.get() != nullptr); 543 std::unique_ptr<ConsumerBuffer> c = 544 ConsumerBuffer::Import(p->CreateConsumer()); 545 ASSERT_TRUE(c.get() != nullptr); 546 EXPECT_EQ(0, p->GainAsync()); 547 548 // It is illegal to post metadata larger than originally requested during 549 // buffer allocation. 550 OverSizedMetadata evil_meta = {}; 551 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata))); 552 EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c))); 553 554 // It is ok to post metadata smaller than originally requested during 555 // buffer allocation. 556 EXPECT_EQ(0, p->Post(LocalHandle())); 557 } 558 559 TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) { 560 struct Metadata { 561 int64_t field1; 562 int64_t field2; 563 }; 564 struct OverSizedMetadata { 565 int64_t field1; 566 int64_t field2; 567 int64_t field3; 568 }; 569 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 570 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata)); 571 ASSERT_TRUE(p.get() != nullptr); 572 std::unique_ptr<ConsumerBuffer> c = 573 ConsumerBuffer::Import(p->CreateConsumer()); 574 ASSERT_TRUE(c.get() != nullptr); 575 EXPECT_EQ(0, p->GainAsync()); 576 577 Metadata m = {1, 3}; 578 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m))); 579 580 LocalHandle fence; 581 int64_t sequence; 582 OverSizedMetadata e; 583 584 // It is illegal to acquire metadata larger than originally requested during 585 // buffer allocation. 586 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e))); 587 588 // It is ok to acquire metadata smaller than originally requested during 589 // buffer allocation. 590 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence))); 591 EXPECT_EQ(m.field1, sequence); 592 } 593 594 TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) { 595 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 596 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 597 ASSERT_TRUE(p.get() != nullptr); 598 std::unique_ptr<ConsumerBuffer> c = 599 ConsumerBuffer::Import(p->CreateConsumer()); 600 ASSERT_TRUE(c.get() != nullptr); 601 EXPECT_EQ(0, p->GainAsync()); 602 603 int64_t sequence = 3; 604 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence))); 605 606 LocalHandle fence; 607 EXPECT_EQ(0, c->Acquire(&fence)); 608 } 609 610 TEST_F(LibBufferHubTest, TestWithNoMeta) { 611 std::unique_ptr<ProducerBuffer> p = 612 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage); 613 ASSERT_TRUE(p.get() != nullptr); 614 std::unique_ptr<ConsumerBuffer> c = 615 ConsumerBuffer::Import(p->CreateConsumer()); 616 ASSERT_TRUE(c.get() != nullptr); 617 EXPECT_EQ(0, p->GainAsync()); 618 619 LocalHandle fence; 620 621 EXPECT_EQ(0, p->Post(LocalHandle())); 622 EXPECT_EQ(0, c->Acquire(&fence)); 623 } 624 625 TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) { 626 std::unique_ptr<ProducerBuffer> p = 627 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage); 628 ASSERT_TRUE(p.get() != nullptr); 629 std::unique_ptr<ConsumerBuffer> c = 630 ConsumerBuffer::Import(p->CreateConsumer()); 631 ASSERT_TRUE(c.get() != nullptr); 632 EXPECT_EQ(0, p->GainAsync()); 633 634 int64_t sequence = 3; 635 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence))); 636 } 637 638 namespace { 639 640 int PollFd(int fd, int timeout_ms) { 641 pollfd p = {fd, POLLIN, 0}; 642 return poll(&p, 1, timeout_ms); 643 } 644 645 } // namespace 646 647 TEST_F(LibBufferHubTest, TestAcquireFence) { 648 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 649 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0); 650 ASSERT_TRUE(p.get() != nullptr); 651 std::unique_ptr<ConsumerBuffer> c = 652 ConsumerBuffer::Import(p->CreateConsumer()); 653 ASSERT_TRUE(c.get() != nullptr); 654 EXPECT_EQ(0, p->GainAsync()); 655 656 DvrNativeBufferMetadata meta; 657 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 658 659 // Post with unsignaled fence. 660 EXPECT_EQ(0, p->PostAsync(&meta, f1)); 661 662 // Should acquire a valid fence. 663 LocalHandle f2; 664 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c))); 665 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2)); 666 EXPECT_TRUE(f2.IsValid()); 667 // The original fence and acquired fence should have different fd number. 668 EXPECT_NE(f1.Get(), f2.Get()); 669 EXPECT_GE(0, PollFd(f2.Get(), 0)); 670 671 // Signal the original fence will trigger the new fence. 672 eventfd_write(f1.Get(), 1); 673 // Now the original FD has been signaled. 674 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs)); 675 676 // Release the consumer with an invalid fence. 677 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle())); 678 679 // Should gain an invalid fence. 680 LocalHandle f3; 681 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 682 EXPECT_EQ(0, p->GainAsync(&meta, &f3)); 683 EXPECT_FALSE(f3.IsValid()); 684 685 // Post with a signaled fence. 686 EXPECT_EQ(0, p->PostAsync(&meta, f1)); 687 688 // Should acquire a valid fence and it's already signalled. 689 LocalHandle f4; 690 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c))); 691 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4)); 692 EXPECT_TRUE(f4.IsValid()); 693 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs)); 694 695 // Release with an unsignalled fence and signal it immediately after release 696 // without producer gainning. 697 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 698 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5)); 699 eventfd_write(f5.Get(), 1); 700 701 // Should gain a valid fence, which is already signaled. 702 LocalHandle f6; 703 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 704 EXPECT_EQ(0, p->GainAsync(&meta, &f6)); 705 EXPECT_TRUE(f6.IsValid()); 706 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs)); 707 } 708 709 TEST_F(LibBufferHubTest, TestOrphanedAcquire) { 710 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 711 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 712 ASSERT_TRUE(p.get() != nullptr); 713 std::unique_ptr<ConsumerBuffer> c1 = 714 ConsumerBuffer::Import(p->CreateConsumer()); 715 ASSERT_TRUE(c1.get() != nullptr); 716 const uint32_t client_state_mask1 = c1->client_state_mask(); 717 718 EXPECT_EQ(0, p->GainAsync()); 719 DvrNativeBufferMetadata meta; 720 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle())); 721 722 LocalHandle fence; 723 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1))); 724 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence)); 725 726 // Destroy the consumer who has acquired but not released the buffer. 727 c1 = nullptr; 728 729 // The buffer is now available for the producer to gain. 730 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 731 732 // Newly added consumer is not able to acquire the buffer. 733 std::unique_ptr<ConsumerBuffer> c2 = 734 ConsumerBuffer::Import(p->CreateConsumer()); 735 ASSERT_TRUE(c2.get() != nullptr); 736 const uint32_t client_state_mask2 = c2->client_state_mask(); 737 EXPECT_NE(client_state_mask1, client_state_mask2); 738 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2))); 739 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence)); 740 741 // Producer should be able to gain. 742 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false)); 743 } 744 745 TEST_F(LibBufferHubTest, TestAcquireLastPosted) { 746 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 747 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 748 ASSERT_TRUE(p.get() != nullptr); 749 std::unique_ptr<ConsumerBuffer> c1 = 750 ConsumerBuffer::Import(p->CreateConsumer()); 751 ASSERT_TRUE(c1.get() != nullptr); 752 const uint32_t client_state_mask1 = c1->client_state_mask(); 753 754 EXPECT_EQ(0, p->GainAsync()); 755 DvrNativeBufferMetadata meta; 756 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle())); 757 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1))); 758 759 // c2 is created when the buffer is in posted state. buffer state for c1 is 760 // posted. Thus, c2 should be automatically set to posted and able to acquire. 761 std::unique_ptr<ConsumerBuffer> c2 = 762 ConsumerBuffer::Import(p->CreateConsumer()); 763 ASSERT_TRUE(c2.get() != nullptr); 764 const uint32_t client_state_mask2 = c2->client_state_mask(); 765 EXPECT_NE(client_state_mask1, client_state_mask2); 766 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c2))); 767 LocalHandle invalid_fence; 768 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence)); 769 770 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence)); 771 772 // c3 is created when the buffer is in acquired state. buffer state for c1 and 773 // c2 are acquired. Thus, c3 should be automatically set to posted and able to 774 // acquire. 775 std::unique_ptr<ConsumerBuffer> c3 = 776 ConsumerBuffer::Import(p->CreateConsumer()); 777 ASSERT_TRUE(c3.get() != nullptr); 778 const uint32_t client_state_mask3 = c3->client_state_mask(); 779 EXPECT_NE(client_state_mask1, client_state_mask3); 780 EXPECT_NE(client_state_mask2, client_state_mask3); 781 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c3))); 782 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence)); 783 784 // Releasing c2 and c3 in normal ways. 785 EXPECT_EQ(0, c2->Release(LocalHandle())); 786 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle())); 787 788 // Destroy the c1 who has not released the buffer. 789 c1 = nullptr; 790 791 // The buffer is now available for the producer to gain. 792 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p))); 793 794 // C4 is created in released state. Thus, it cannot gain the just posted 795 // buffer. 796 std::unique_ptr<ConsumerBuffer> c4 = 797 ConsumerBuffer::Import(p->CreateConsumer()); 798 ASSERT_TRUE(c4.get() != nullptr); 799 const uint32_t client_state_mask4 = c4->client_state_mask(); 800 EXPECT_NE(client_state_mask3, client_state_mask4); 801 EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c3))); 802 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence)); 803 804 // Producer should be able to gain. 805 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence)); 806 } 807 808 TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) { 809 // TODO(b/112338294) rewrite test after migration 810 return; 811 812 /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create( 813 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 814 std::unique_ptr<ConsumerBuffer> c = 815 ConsumerBuffer::Import(p->CreateConsumer()); 816 ASSERT_TRUE(p.get() != nullptr); 817 ASSERT_TRUE(c.get() != nullptr); 818 819 DvrNativeBufferMetadata metadata; 820 LocalHandle invalid_fence; 821 int p_id = p->id(); 822 823 // Detach in posted state should fail. 824 EXPECT_EQ(0, p->GainAsync()); 825 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); 826 EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0); 827 auto s1 = p->Detach(); 828 EXPECT_FALSE(s1); 829 830 // Detach in acquired state should fail. 831 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); 832 s1 = p->Detach(); 833 EXPECT_FALSE(s1); 834 835 // Detach in released state should fail. 836 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence)); 837 EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0); 838 s1 = p->Detach(); 839 EXPECT_FALSE(s1); 840 841 // Detach in gained state should succeed. 842 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); 843 s1 = p->Detach(); 844 EXPECT_TRUE(s1); 845 846 LocalChannelHandle handle = s1.take(); 847 EXPECT_TRUE(handle.valid()); 848 849 // Both producer and consumer should have hangup. 850 EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0); 851 auto s2 = p->GetEventMask(POLLHUP); 852 EXPECT_TRUE(s2); 853 EXPECT_EQ(s2.get(), POLLHUP); 854 855 EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0); 856 s2 = p->GetEventMask(POLLHUP); 857 EXPECT_TRUE(s2); 858 EXPECT_EQ(s2.get(), POLLHUP); 859 860 auto s3 = p->CreateConsumer(); 861 EXPECT_FALSE(s3); 862 // Note that here the expected error code is EOPNOTSUPP as the socket towards 863 // ProducerChannel has been teared down. 864 EXPECT_EQ(s3.error(), EOPNOTSUPP); 865 866 s3 = c->CreateConsumer(); 867 EXPECT_FALSE(s3); 868 // Note that here the expected error code is EPIPE returned from 869 // ConsumerChannel::HandleMessage as the socket is still open but the producer 870 // is gone. 871 EXPECT_EQ(s3.error(), EPIPE); 872 873 // Detached buffer handle can be use to construct a new BufferHubBuffer 874 // object. 875 auto d = BufferHubBuffer::Import(std::move(handle)); 876 EXPECT_FALSE(handle.valid()); 877 EXPECT_TRUE(d->IsConnected()); 878 EXPECT_TRUE(d->IsValid()); 879 880 EXPECT_EQ(d->id(), p_id); */ 881 } 882 883 TEST_F(LibBufferHubTest, TestDetach) { 884 // TODO(b/112338294) rewrite test after migration 885 return; 886 887 /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create( 888 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); 889 ASSERT_TRUE(p1.get() != nullptr); 890 int p1_id = p1->id(); 891 892 // Detached the producer from gained state. 893 EXPECT_EQ(0, p1->GainAsync()); 894 auto status_or_handle = p1->Detach(); 895 EXPECT_TRUE(status_or_handle.ok()); 896 LocalChannelHandle h1 = status_or_handle.take(); 897 EXPECT_TRUE(h1.valid()); 898 899 // Detached buffer handle can be use to construct a new BufferHubBuffer 900 // object. 901 auto b1 = BufferHubBuffer::Import(std::move(h1)); 902 EXPECT_FALSE(h1.valid()); 903 EXPECT_TRUE(b1->IsValid()); 904 int b1_id = b1->id(); 905 EXPECT_EQ(b1_id, p1_id); */ 906 } 907