1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <base/logging.h> 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/buffer_hub_client.h> 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/buffer_hub_queue_client.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <gtest/gtest.h> 652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka#include <poll.h> 752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka#include <sys/eventfd.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <vector> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka// Enable/disable debug logging. 12b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka#define TRACE 0 13b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing pdx::LocalHandle; 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 216bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Caiconstexpr uint32_t kBufferWidth = 100; 226bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Caiconstexpr uint32_t kBufferHeight = 1; 236bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Caiconstexpr uint32_t kBufferLayerCount = 1; 246bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Caiconstexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB; 256bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Caiconstexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferHubQueueTest : public ::testing::Test { 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 296bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai bool CreateProducerQueue(const ProducerQueueConfig& config, 306bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai const UsagePolicy& usage) { 316bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai producer_queue_ = ProducerQueue::Create(config, usage); 322b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka return producer_queue_ != nullptr; 332b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka } 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 352b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka bool CreateConsumerQueue() { 362b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka if (producer_queue_) { 372b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka consumer_queue_ = producer_queue_->CreateConsumerQueue(); 382b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka return consumer_queue_ != nullptr; 392b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka } else { 401db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabaka return false; 412b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka } 422b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka } 431db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabaka 446bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai bool CreateQueues(const ProducerQueueConfig& config, 456bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai const UsagePolicy& usage) { 466bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai return CreateProducerQueue(config, usage) && CreateConsumerQueue(); 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 49b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka void AllocateBuffer(size_t* slot_out = nullptr) { 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create producer buffer. 5152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, 5252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka kBufferLayerCount, 5352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka kBufferFormat, kBufferUsage); 54b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 558fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai ASSERT_TRUE(status.ok()); 568fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai size_t slot = status.take(); 57b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka if (slot_out) 58b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka *slot_out = slot; 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 6152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka bool WaitAndHandleOnce(BufferHubQueue* queue, int timeout_ms) { 6252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka pollfd pfd{queue->queue_fd(), POLLIN, 0}; 6352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int ret; 6452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka do { 6552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ret = poll(&pfd, 1, timeout_ms); 6652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } while (ret == -1 && errno == EINTR); 6752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 6852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka if (ret < 0) { 6952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ALOGW("Failed to poll queue %d's event fd, error: %s.", queue->id(), 7052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka strerror(errno)); 7152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return false; 7252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } else if (ret == 0) { 7352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return false; 7452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } 7552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return queue->HandleQueueEvents(); 7652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } 7752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko protected: 796bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ProducerQueueConfigBuilder config_builder_; 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<ProducerQueue> producer_queue_; 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<ConsumerQueue> consumer_queue_; 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestDequeue) { 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const size_t nb_dequeue_times = 16; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 876bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<size_t>().Build(), 886bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Allocate only one buffer. 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // But dequeue multiple times. 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < nb_dequeue_times; i++) { 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t slot; 96ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 9752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &slot, &fence); 989d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 999d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, p1); 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t mi = i; 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(p1->Post(LocalHandle(), &mi, sizeof(mi)), 0); 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t mo; 1049d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto c1_status = consumer_queue_->Dequeue(100, &slot, &mo, &fence); 1059d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(c1_status.ok()); 1069d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto c1 = c1_status.take(); 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, c1); 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(mi, mo); 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko c1->Release(LocalHandle()); 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestProducerConsumer) { 114b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka const size_t kBufferCount = 16; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t slot; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint64_t seq; 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1186bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(), 1196bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 121b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka for (size_t i = 0; i < kBufferCount; i++) { 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Producer queue has all the available buffers on initialize. 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(producer_queue_->count(), i + 1); 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(producer_queue_->capacity(), i + 1); 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Consumer queue has no avaiable buffer on initialize. 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(consumer_queue_->count(), 0U); 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Consumer queue does not import buffers until a dequeue is issued. 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(consumer_queue_->capacity(), i); 1329d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka // Dequeue returns timeout since no buffer is ready to consumer, but 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // this implicitly triggers buffer import and bump up |capacity|. 134ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 13552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto status = consumer_queue_->Dequeue(100, &slot, &seq, &fence); 1369d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_FALSE(status.ok()); 1379d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_EQ(ETIMEDOUT, status.error()); 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(consumer_queue_->capacity(), i + 1); 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 14152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Use eventfd as a stand-in for a fence. 14252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka LocalHandle post_fence(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 143b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 144b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka for (size_t i = 0; i < kBufferCount; i++) { 145ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 146b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 147b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // First time there is no buffer available to dequeue. 14852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto consumer_status = consumer_queue_->Dequeue(100, &slot, &seq, &fence); 1499d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_FALSE(consumer_status.ok()); 1509d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_EQ(ETIMEDOUT, consumer_status.error()); 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 152b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Make sure Producer buffer is POSTED so that it's ready to Accquire 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // in the consumer's Dequeue() function. 15452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto producer_status = producer_queue_->Dequeue(100, &slot, &fence); 1559d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(producer_status.ok()); 1569d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto producer = producer_status.take(); 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, producer); 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint64_t seq_in = static_cast<uint64_t>(i); 160b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_EQ(producer->Post(post_fence, &seq_in, sizeof(seq_in)), 0); 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 162b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Second time the just the POSTED buffer should be dequeued. 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint64_t seq_out = 0; 16452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka consumer_status = consumer_queue_->Dequeue(100, &slot, &seq_out, &fence); 1659d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(consumer_status.ok()); 166b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_TRUE(fence.IsValid()); 167b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 1689d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto consumer = consumer_status.take(); 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, consumer); 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(seq_in, seq_out); 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 174bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' CaiTEST_F(BufferHubQueueTest, TestRemoveBuffer) { 1756bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); 176b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 177b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Allocate buffers. 178b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka const size_t kBufferCount = 4u; 179b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka for (size_t i = 0; i < kBufferCount; i++) { 180b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka AllocateBuffer(); 181b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka } 182b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_EQ(kBufferCount, producer_queue_->count()); 183b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_EQ(kBufferCount, producer_queue_->capacity()); 184b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 185b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka consumer_queue_ = producer_queue_->CreateConsumerQueue(); 186b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_NE(nullptr, consumer_queue_); 187b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 188b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Check that buffers are correctly imported on construction. 189b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 190b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(0u, consumer_queue_->count()); 191b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 192b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Dequeue all the buffers and keep track of them in an array. This prevents 193b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // the producer queue ring buffer ref counts from interfering with the tests. 194b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka struct Entry { 195b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka std::shared_ptr<BufferProducer> buffer; 196b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka LocalHandle fence; 197b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka size_t slot; 198b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka }; 199b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka std::array<Entry, kBufferCount> buffers; 200b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 201b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka for (size_t i = 0; i < kBufferCount; i++) { 202b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka Entry* entry = &buffers[i]; 20352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto producer_status = producer_queue_->Dequeue( 20452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka /*timeout_ms=*/100, &entry->slot, &entry->fence); 205b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_TRUE(producer_status.ok()); 206b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka entry->buffer = producer_status.take(); 207b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_NE(nullptr, entry->buffer); 208b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka } 209b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 210bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai // Remove a buffer and make sure both queues reflect the change. 211bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[0].slot)); 212b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity()); 213b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 214bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai // As long as the removed buffer is still alive the consumer queue won't know 215b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // its gone. 216b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 217b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); 218b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 219b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 220bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai // Release the removed buffer. 221b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka buffers[0].buffer = nullptr; 222b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 223b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Now the consumer queue should know it's gone. 22452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_FALSE(WaitAndHandleOnce(consumer_queue_.get(), /*timeout_ms=*/100)); 22552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_EQ(kBufferCount - 1, consumer_queue_->capacity()); 226b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 227b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Allocate a new buffer. This should take the first empty slot. 228b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka size_t slot; 229b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka AllocateBuffer(&slot); 230b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ALOGE_IF(TRACE, "ALLOCATE %zu", slot); 231b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(buffers[0].slot, slot); 232b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, producer_queue_->capacity()); 233b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 234b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // The consumer queue should pick up the new buffer. 235b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount - 1, consumer_queue_->capacity()); 236b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); 237b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 238b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 239bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai // Remove and allocate a buffer. 240bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[1].slot)); 241b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity()); 242b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka buffers[1].buffer = nullptr; 243b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 244b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka AllocateBuffer(&slot); 245b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ALOGE_IF(TRACE, "ALLOCATE %zu", slot); 246b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(buffers[1].slot, slot); 247b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, producer_queue_->capacity()); 248b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 249b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // The consumer queue should pick up the new buffer but the count shouldn't 250b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // change. 251b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 252b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); 253b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 254b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 255bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai // Remove and allocate a buffer, but don't free the buffer right away. 256bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[2].slot)); 257b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity()); 258b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 259b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka AllocateBuffer(&slot); 260b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ALOGE_IF(TRACE, "ALLOCATE %zu", slot); 261b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(buffers[2].slot, slot); 262b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, producer_queue_->capacity()); 263b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 264b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 265b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); 266b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 267b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 268b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka // Release the producer buffer to trigger a POLLHUP event for an already 269bb701dbac7c9c9eb2a7d0ec48c5e020f1272de13Jiwen 'Steve' Cai // removed buffer. 270b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka buffers[2].buffer = nullptr; 271b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 272b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); 273b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 274b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka} 275b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka 2762b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey TabakaTEST_F(BufferHubQueueTest, TestMultipleConsumers) { 2776bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai // ProducerConfigureBuilder doesn't set Metadata{size}, which means there 2786bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai // is no metadata associated with this BufferQueue's buffer. 2796bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); 2802b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 2812b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Allocate buffers. 2822b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka const size_t kBufferCount = 4u; 2832b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka for (size_t i = 0; i < kBufferCount; i++) { 2842b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka AllocateBuffer(); 2852b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka } 2862b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_EQ(kBufferCount, producer_queue_->count()); 2872b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 2882b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Build a silent consumer queue to test multi-consumer queue features. 2892b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka auto silent_queue = producer_queue_->CreateSilentConsumerQueue(); 2902b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_NE(nullptr, silent_queue); 2912b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 29252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Check that silent queue doesn't import buffers on creation. 29352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_EQ(0, silent_queue->capacity()); 2942b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 2952b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Dequeue and post a buffer. 2962b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka size_t slot; 2972b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka LocalHandle fence; 29852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto producer_status = 29952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_queue_->Dequeue(/*timeout_ms=*/100, &slot, &fence); 3002b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_TRUE(producer_status.ok()); 3012b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka auto producer_buffer = producer_status.take(); 3022b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_NE(nullptr, producer_buffer); 3032b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_EQ(0, producer_buffer->Post<void>({})); 30452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // After post, check the number of remaining available buffers. 30552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_EQ(kBufferCount - 1, producer_queue_->count()); 3062b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3072b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Currently we expect no buffer to be available prior to calling 3082b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // WaitForBuffers/HandleQueueEvents. 3092b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // TODO(eieio): Note this behavior may change in the future. 3102b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_EQ(0u, silent_queue->count()); 3112b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_FALSE(silent_queue->HandleQueueEvents()); 3122b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_EQ(0u, silent_queue->count()); 3132b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3142b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Build a new consumer queue to test multi-consumer queue features. 3152b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka consumer_queue_ = silent_queue->CreateConsumerQueue(); 3162b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_NE(nullptr, consumer_queue_); 3172b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3182b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Check that buffers are correctly imported on construction. 3192b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); 3202b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_EQ(1u, consumer_queue_->count()); 3212b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3222b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Reclaim released/ignored buffers. 32352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_EQ(kBufferCount - 1, producer_queue_->count()); 32452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 32552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka usleep(10000); 32652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka WaitAndHandleOnce(producer_queue_.get(), /*timeout_ms=*/100); 3272b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_EQ(kBufferCount - 1, producer_queue_->count()); 3282b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3292b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Post another buffer. 33052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_status = producer_queue_->Dequeue(/*timeout_ms=*/100, &slot, &fence); 3312b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_TRUE(producer_status.ok()); 3322b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka producer_buffer = producer_status.take(); 3332b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_NE(nullptr, producer_buffer); 3342b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_EQ(0, producer_buffer->Post<void>({})); 3352b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3362b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Verify that the consumer queue receives it. 33752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka size_t consumer_queue_count = consumer_queue_->count(); 33852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka WaitAndHandleOnce(consumer_queue_.get(), /*timeout_ms=*/100); 33952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_LT(consumer_queue_count, consumer_queue_->count()); 34052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 34152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Save the current consumer queue buffer count to compare after the dequeue. 34252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka consumer_queue_count = consumer_queue_->count(); 3432b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3442b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Dequeue and acquire/release (discard) buffers on the consumer end. 34552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto consumer_status = 34652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka consumer_queue_->Dequeue(/*timeout_ms=*/100, &slot, &fence); 3472b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_TRUE(consumer_status.ok()); 3482b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka auto consumer_buffer = consumer_status.take(); 3492b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka ASSERT_NE(nullptr, consumer_buffer); 3502b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka consumer_buffer->Discard(); 3512b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 3522b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // Buffer should be returned to the producer queue without being handled by 3532b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka // the silent consumer queue. 35452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_GT(consumer_queue_count, consumer_queue_->count()); 3552b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_EQ(kBufferCount - 2, producer_queue_->count()); 3562b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_TRUE(producer_queue_->HandleQueueEvents()); 3572b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka EXPECT_EQ(kBufferCount - 1, producer_queue_->count()); 3582b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka} 3592b99ee560ba14b617ebb4c1997e8b8004f2de22fCorey Tabaka 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TestMetadata { 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char a; 362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int32_t b; 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t c; 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestMetadata) { 3676bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<TestMetadata>().Build(), 3686bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 3696bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai 370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<TestMetadata> ms = { 373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {'0', 0, 0}, {'1', 10, 3333}, {'@', 123, 1000000000}}; 374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (auto mi : ms) { 376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t slot; 377ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 37852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &slot, &fence); 3799d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 3809d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, p1); 382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(p1->Post(LocalHandle(-1), &mi, sizeof(mi)), 0); 383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestMetadata mo; 38452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto c1_status = consumer_queue_->Dequeue(100, &slot, &mo, &fence); 3859d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(c1_status.ok()); 3869d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto c1 = c1_status.take(); 387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(mi.a, mo.a); 388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(mi.b, mo.b); 389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(mi.c, mo.c); 390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko c1->Release(LocalHandle(-1)); 391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestMetadataMismatch) { 3956bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 3966bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 3976bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai 398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t mi = 3; 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t slot; 402ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 40352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &slot, &fence); 4049d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 4059d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, p1); 407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(p1->Post(LocalHandle(-1), &mi, sizeof(mi)), 0); 408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int32_t mo; 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Acquire a buffer with mismatched metadata is not OK. 41152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto c1_status = consumer_queue_->Dequeue(100, &slot, &mo, &fence); 4129d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_FALSE(c1_status.ok()); 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestEnqueue) { 4166bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 4176bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t slot; 421ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 42252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &slot, &fence); 4239d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 4249d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, p1); 426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t mo; 42852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_queue_->Enqueue(p1, slot, 0ULL); 42952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto c1_status = consumer_queue_->Dequeue(100, &slot, &mo, &fence); 4309d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_FALSE(c1_status.ok()); 431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestAllocateBuffer) { 4346bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 4356bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 437e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t s1; 438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 439ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 44052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &s1, &fence); 4419d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 4429d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, p1); 444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // producer queue is exhausted 446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t s2; 44752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p2_status = producer_queue_->Dequeue(100, &s2, &fence); 4489d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_FALSE(p2_status.ok()); 4499d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_EQ(ETIMEDOUT, p2_status.error()); 450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // dynamically add buffer. 452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko AllocateBuffer(); 453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(producer_queue_->count(), 1U); 454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(producer_queue_->capacity(), 2U); 455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // now we can dequeue again 45752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka p2_status = producer_queue_->Dequeue(100, &s2, &fence); 4589d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p2_status.ok()); 4599d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p2 = p2_status.take(); 460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, p2); 461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(producer_queue_->count(), 0U); 462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // p1 and p2 should have different slot number 463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(s1, s2); 464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Consumer queue does not import buffers until |Dequeue| or |ImportBuffers| 466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // are called. So far consumer_queue_ should be empty. 467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(consumer_queue_->count(), 0U); 468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t seq = 1; 470e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(p1->Post(LocalHandle(), seq), 0); 471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t cs1, cs2; 47252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto c1_status = consumer_queue_->Dequeue(100, &cs1, &seq, &fence); 4739d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(c1_status.ok()); 4749d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto c1 = c1_status.take(); 475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, c1); 476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(consumer_queue_->count(), 0U); 477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(consumer_queue_->capacity(), 2U); 478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(cs1, s1); 479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(p2->Post(LocalHandle(), seq), 0); 48152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto c2_status = consumer_queue_->Dequeue(100, &cs2, &seq, &fence); 4829d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(c2_status.ok()); 4839d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto c2 = c2_status.take(); 484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, c2); 485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(cs2, s2); 486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestUsageSetMask) { 4899d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; 4906bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 4916bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{set_mask, 0, 0, 0})); 492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // When allocation, leave out |set_mask| from usage bits on purpose. 494b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka auto status = producer_queue_->AllocateBuffer( 495b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, 4968fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai kBufferUsage & ~set_mask); 497b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_TRUE(status.ok()); 498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 499ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 5008fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai size_t slot; 50152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &slot, &fence); 5029d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 5039d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(p1->usage() & set_mask, set_mask); 505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestUsageClearMask) { 5089d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka const uint32_t clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; 5096bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 5106bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{0, clear_mask, 0, 0})); 511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // When allocation, add |clear_mask| into usage bits on purpose. 513b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka auto status = producer_queue_->AllocateBuffer( 514b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, 5158fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai kBufferUsage | clear_mask); 516b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_TRUE(status.ok()); 517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 518ed6543224138fd753eeea909918bb8d1d2efb1e6Jiwen 'Steve' Cai LocalHandle fence; 5198fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai size_t slot; 52052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto p1_status = producer_queue_->Dequeue(100, &slot, &fence); 5219d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_TRUE(p1_status.ok()); 5229d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka auto p1 = p1_status.take(); 5239d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka ASSERT_EQ(0u, p1->usage() & clear_mask); 524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestUsageDenySetMask) { 5279d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka const uint32_t deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; 5286bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 5296bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{0, 0, deny_set_mask, 0})); 530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Now that |deny_set_mask| is illegal, allocation without those bits should 532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // be able to succeed. 533b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka auto status = producer_queue_->AllocateBuffer( 534108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, 5358fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai kBufferUsage & ~deny_set_mask); 536b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_TRUE(status.ok()); 537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // While allocation with those bits should fail. 539b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, 540b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka kBufferLayerCount, kBufferFormat, 5418fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai kBufferUsage | deny_set_mask); 542b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_FALSE(status.ok()); 543b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_EQ(EINVAL, status.error()); 544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(BufferHubQueueTest, TestUsageDenyClearMask) { 5479d8bd09569322f452fddf91e581904f1e8f6849cCorey Tabaka const uint32_t deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; 5486bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), 5496bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{0, 0, 0, deny_clear_mask})); 550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Now that clearing |deny_clear_mask| is illegal (i.e. setting these bits are 552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // mandatory), allocation with those bits should be able to succeed. 553b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka auto status = producer_queue_->AllocateBuffer( 554108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, 5558fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai kBufferUsage | deny_clear_mask); 556b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_TRUE(status.ok()); 557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // While allocation without those bits should fail. 55952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, 56052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka kBufferLayerCount, kBufferFormat, 56152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka kBufferUsage & ~deny_clear_mask); 562b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_FALSE(status.ok()); 563b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka ASSERT_EQ(EINVAL, status.error()); 564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5666bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' CaiTEST_F(BufferHubQueueTest, TestQueueInfo) { 5676bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai static const bool kIsAsync = true; 5686bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetIsAsync(kIsAsync) 5696bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai .SetDefaultWidth(kBufferWidth) 5706bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai .SetDefaultHeight(kBufferHeight) 5716bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai .SetDefaultFormat(kBufferFormat) 5726bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai .Build(), 5736bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai UsagePolicy{})); 5746bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai 5756bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->default_width(), kBufferWidth); 5766bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->default_height(), kBufferHeight); 5776bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->default_format(), kBufferFormat); 5786bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->is_async(), kIsAsync); 5796bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai 5806bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(consumer_queue_->default_width(), kBufferWidth); 5816bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(consumer_queue_->default_height(), kBufferHeight); 5826bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(consumer_queue_->default_format(), kBufferFormat); 5836bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai EXPECT_EQ(consumer_queue_->is_async(), kIsAsync); 5846bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai} 5856bffc67cec8bd8ad086d5a6265dedb737073bdeaJiwen 'Steve' Cai 586005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' CaiTEST_F(BufferHubQueueTest, TestFreeAllBuffers) { 587005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai constexpr size_t kBufferCount = 2; 588005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 589005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai#define CHECK_NO_BUFFER_THEN_ALLOCATE(num_buffers) \ 590005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_EQ(consumer_queue_->count(), 0U); \ 591005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_EQ(consumer_queue_->capacity(), 0U); \ 592005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->count(), 0U); \ 593005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->capacity(), 0U); \ 594005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai for (size_t i = 0; i < num_buffers; i++) { \ 595005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai AllocateBuffer(); \ 596005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai } \ 597005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->count(), num_buffers); \ 598005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_EQ(producer_queue_->capacity(), num_buffers); 599005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 600005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai size_t slot; 601005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai uint64_t seq; 602005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai LocalHandle fence; 603005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai pdx::Status<void> status; 604005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai pdx::Status<std::shared_ptr<BufferConsumer>> consumer_status; 605005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai pdx::Status<std::shared_ptr<BufferProducer>> producer_status; 606005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai std::shared_ptr<BufferConsumer> consumer_buffer; 607005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai std::shared_ptr<BufferProducer> producer_buffer; 608005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 609005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(), 610005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai UsagePolicy{})); 611005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 612005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Free all buffers when buffers are avaible for dequeue. 613005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 614005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai status = producer_queue_->FreeAllBuffers(); 615005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_TRUE(status.ok()); 616005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 617005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Free all buffers when one buffer is dequeued. 618005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 61952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_status = producer_queue_->Dequeue(100, &slot, &fence); 620005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(producer_status.ok()); 621005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai status = producer_queue_->FreeAllBuffers(); 622005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_TRUE(status.ok()); 623005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 624005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Free all buffers when all buffers are dequeued. 625005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 626005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai for (size_t i = 0; i < kBufferCount; i++) { 62752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_status = producer_queue_->Dequeue(100, &slot, &fence); 628005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(producer_status.ok()); 629005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai } 630005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai status = producer_queue_->FreeAllBuffers(); 631005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_TRUE(status.ok()); 632005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 633005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Free all buffers when one buffer is posted. 634005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 63552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_status = producer_queue_->Dequeue(100, &slot, &fence); 636005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(producer_status.ok()); 637005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai producer_buffer = producer_status.take(); 638005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_NE(nullptr, producer_buffer); 639005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_EQ(0, producer_buffer->Post(fence, &seq, sizeof(seq))); 640005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai status = producer_queue_->FreeAllBuffers(); 641005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_TRUE(status.ok()); 642005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 643005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Free all buffers when all buffers are posted. 644005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 645005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai for (size_t i = 0; i < kBufferCount; i++) { 64652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_status = producer_queue_->Dequeue(100, &slot, &fence); 647005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(producer_status.ok()); 648005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai producer_buffer = producer_status.take(); 649005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_NE(nullptr, producer_buffer); 650005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_EQ(0, producer_buffer->Post(fence, &seq, sizeof(seq))); 651005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai } 652005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai status = producer_queue_->FreeAllBuffers(); 653005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_TRUE(status.ok()); 654005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 655005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Free all buffers when all buffers are acquired. 656005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 657005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai for (size_t i = 0; i < kBufferCount; i++) { 65852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka producer_status = producer_queue_->Dequeue(100, &slot, &fence); 659005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(producer_status.ok()); 660005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai producer_buffer = producer_status.take(); 661005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_NE(nullptr, producer_buffer); 662005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_EQ(0, producer_buffer->Post(fence, &seq, sizeof(seq))); 66352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka consumer_status = consumer_queue_->Dequeue(100, &slot, &seq, &fence); 664005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai ASSERT_TRUE(consumer_status.ok()); 665005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai } 666005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 667005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai status = producer_queue_->FreeAllBuffers(); 668005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai EXPECT_TRUE(status.ok()); 669005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 670005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // In addition to FreeAllBuffers() from the queue, it is also required to 671005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // delete all references to the ProducerBuffer (i.e. the PDX client). 672005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai producer_buffer = nullptr; 673005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 674005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // Crank consumer queue events to pickup EPOLLHUP events on the queue. 675005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai consumer_queue_->HandleQueueEvents(); 676005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 677005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai // One last check. 678005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); 679005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 680005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai#undef CHECK_NO_BUFFER_THEN_ALLOCATE 681005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai} 682005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai 683e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace 684e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 685e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 686e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 687