1#include <dvr/dvr_api.h> 2#include <dvr/dvr_buffer_queue.h> 3#include <gui/Surface.h> 4#include <private/dvr/buffer_hub_queue_client.h> 5 6#include <base/logging.h> 7#include <gtest/gtest.h> 8 9#include "../dvr_internal.h" 10 11namespace android { 12namespace dvr { 13 14namespace { 15 16static constexpr int kBufferWidth = 100; 17static constexpr int kBufferHeight = 1; 18static constexpr int kLayerCount = 1; 19static constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB; 20static constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; 21static constexpr size_t kQueueCapacity = 3; 22 23typedef uint64_t TestMeta; 24 25class DvrBufferQueueTest : public ::testing::Test { 26 protected: 27 void SetUp() override { 28 write_queue_ = CreateDvrWriteBufferQueueFromProducerQueue( 29 ProducerQueue::Create<TestMeta>(0, 0, 0, 0)); 30 ASSERT_NE(nullptr, write_queue_); 31 } 32 33 void TearDown() override { 34 if (write_queue_ != nullptr) { 35 dvrWriteBufferQueueDestroy(write_queue_); 36 write_queue_ = nullptr; 37 } 38 } 39 40 void AllocateBuffers(size_t buffer_count) { 41 size_t out_slot; 42 for (size_t i = 0; i < buffer_count; i++) { 43 int ret = GetProducerQueueFromDvrWriteBufferQueue(write_queue_) 44 ->AllocateBuffer(kBufferWidth, kBufferHeight, kLayerCount, 45 kBufferFormat, kBufferUsage, &out_slot); 46 ASSERT_EQ(0, ret); 47 } 48 } 49 50 DvrWriteBufferQueue* write_queue_{nullptr}; 51}; 52 53TEST_F(DvrBufferQueueTest, TestWrite_QueueDestroy) { 54 dvrWriteBufferQueueDestroy(write_queue_); 55 write_queue_ = nullptr; 56} 57 58TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) { 59 AllocateBuffers(kQueueCapacity); 60 size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_); 61 62 ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity); 63 ASSERT_EQ(kQueueCapacity, capacity); 64} 65 66TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) { 67 DvrReadBufferQueue* read_queue = nullptr; 68 int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); 69 70 ASSERT_EQ(0, ret); 71 ASSERT_NE(nullptr, read_queue); 72 73 dvrReadBufferQueueDestroy(read_queue); 74} 75 76TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) { 77 DvrReadBufferQueue* read_queue1 = nullptr; 78 DvrReadBufferQueue* read_queue2 = nullptr; 79 int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1); 80 81 ASSERT_EQ(0, ret); 82 ASSERT_NE(nullptr, read_queue1); 83 84 ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2); 85 ASSERT_EQ(0, ret); 86 ASSERT_NE(nullptr, read_queue2); 87 ASSERT_NE(read_queue1, read_queue2); 88 89 dvrReadBufferQueueDestroy(read_queue1); 90 dvrReadBufferQueueDestroy(read_queue2); 91} 92 93TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) { 94 AllocateBuffers(3); 95 96 DvrReadBuffer* read_buffer = nullptr; 97 DvrWriteBuffer* write_buffer = nullptr; 98 99 EXPECT_FALSE(dvrReadBufferIsValid(read_buffer)); 100 EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer)); 101 102 dvrReadBufferCreateEmpty(&read_buffer); 103 ASSERT_NE(nullptr, read_buffer); 104 105 dvrWriteBufferCreateEmpty(&write_buffer); 106 ASSERT_NE(nullptr, write_buffer); 107 108 EXPECT_FALSE(dvrReadBufferIsValid(read_buffer)); 109 EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer)); 110 111 DvrReadBufferQueue* read_queue = nullptr; 112 113 ASSERT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue)); 114 115 const int kTimeoutMs = 0; 116 int fence_fd = -1; 117 ASSERT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, kTimeoutMs, 118 write_buffer, &fence_fd)); 119 EXPECT_EQ(-1, fence_fd); 120 EXPECT_TRUE(dvrWriteBufferIsValid(write_buffer)); 121 122 ASSERT_EQ(0, dvrWriteBufferClear(write_buffer)); 123 EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer)); 124} 125 126TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { 127 static constexpr int kTimeout = 0; 128 DvrReadBufferQueue* read_queue = nullptr; 129 DvrReadBuffer* rb = nullptr; 130 DvrWriteBuffer* wb = nullptr; 131 int fence_fd = -1; 132 133 int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); 134 135 ASSERT_EQ(0, ret); 136 ASSERT_NE(nullptr, read_queue); 137 138 dvrWriteBufferCreateEmpty(&wb); 139 ASSERT_NE(nullptr, wb); 140 141 dvrReadBufferCreateEmpty(&rb); 142 ASSERT_NE(nullptr, rb); 143 144 AllocateBuffers(kQueueCapacity); 145 146 // Gain buffer for writing. 147 ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb, &fence_fd); 148 ASSERT_EQ(0, ret); 149 ASSERT_TRUE(dvrWriteBufferIsValid(wb)); 150 ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d", 151 wb, fence_fd); 152 pdx::LocalHandle release_fence(fence_fd); 153 154 // Post buffer to the read_queue. 155 TestMeta seq = 42U; 156 ret = dvrWriteBufferPost(wb, /* fence */ -1, &seq, sizeof(seq)); 157 ASSERT_EQ(0, ret); 158 dvrWriteBufferDestroy(wb); 159 wb = nullptr; 160 161 // Acquire buffer for reading. 162 TestMeta acquired_seq = 0U; 163 ret = dvrReadBufferQueueDequeue(read_queue, kTimeout, rb, &fence_fd, 164 &acquired_seq, sizeof(acquired_seq)); 165 ASSERT_EQ(0, ret); 166 ASSERT_TRUE(dvrReadBufferIsValid(rb)); 167 ASSERT_EQ(seq, acquired_seq); 168 ALOGD_IF(TRACE, 169 "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb, 170 fence_fd); 171 pdx::LocalHandle acquire_fence(fence_fd); 172 173 // Release buffer to the write_queue. 174 ret = dvrReadBufferRelease(rb, -1); 175 ASSERT_EQ(0, ret); 176 dvrReadBufferDestroy(rb); 177 rb = nullptr; 178 179 // TODO(b/34387835) Currently buffer allocation has to happen after all queues 180 // are initialized. 181 size_t capacity = dvrReadBufferQueueGetCapacity(read_queue); 182 183 ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity); 184 ASSERT_EQ(kQueueCapacity, capacity); 185 186 dvrReadBufferQueueDestroy(read_queue); 187} 188 189TEST_F(DvrBufferQueueTest, TestGetExternalSurface) { 190 ANativeWindow* window = nullptr; 191 192 // The |write_queue_| doesn't have proper metadata (must be 193 // DvrNativeBufferMetadata) configured during creation. 194 int ret = dvrWriteBufferQueueGetExternalSurface(write_queue_, &window); 195 ASSERT_EQ(-EINVAL, ret); 196 ASSERT_EQ(nullptr, window); 197 198 // A write queue with DvrNativeBufferMetadata should work fine. 199 std::unique_ptr<DvrWriteBufferQueue, decltype(&dvrWriteBufferQueueDestroy)> 200 write_queue( 201 CreateDvrWriteBufferQueueFromProducerQueue( 202 ProducerQueue::Create<DvrNativeBufferMetadata>(0, 0, 0, 0)), 203 dvrWriteBufferQueueDestroy); 204 ASSERT_NE(nullptr, write_queue.get()); 205 206 ret = dvrWriteBufferQueueGetExternalSurface(write_queue.get(), &window); 207 ASSERT_EQ(0, ret); 208 ASSERT_NE(nullptr, window); 209 210 sp<Surface> surface = static_cast<Surface*>(window); 211 ASSERT_TRUE(Surface::isValid(surface)); 212} 213 214} // namespace 215 216} // namespace dvr 217} // namespace android 218