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
11 namespace android {
12 namespace dvr {
13
14 namespace {
15
16 static constexpr int kBufferWidth = 100;
17 static constexpr int kBufferHeight = 1;
18 static constexpr int kLayerCount = 1;
19 static constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
20 static constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
21 static constexpr size_t kQueueCapacity = 3;
22
23 typedef uint64_t TestMeta;
24
25 class DvrBufferQueueTest : public ::testing::Test {
26 protected:
SetUp()27 void SetUp() override {
28 write_queue_ = CreateDvrWriteBufferQueueFromProducerQueue(
29 ProducerQueue::Create<TestMeta>(0, 0, 0, 0));
30 ASSERT_NE(nullptr, write_queue_);
31 }
32
TearDown()33 void TearDown() override {
34 if (write_queue_ != nullptr) {
35 dvrWriteBufferQueueDestroy(write_queue_);
36 write_queue_ = nullptr;
37 }
38 }
39
AllocateBuffers(size_t buffer_count)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
TEST_F(DvrBufferQueueTest,TestWrite_QueueDestroy)53 TEST_F(DvrBufferQueueTest, TestWrite_QueueDestroy) {
54 dvrWriteBufferQueueDestroy(write_queue_);
55 write_queue_ = nullptr;
56 }
57
TEST_F(DvrBufferQueueTest,TestWrite_QueueGetCapacity)58 TEST_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
TEST_F(DvrBufferQueueTest,TestCreateReadQueueFromWriteQueue)66 TEST_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
TEST_F(DvrBufferQueueTest,TestCreateReadQueueFromReadQueue)76 TEST_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
TEST_F(DvrBufferQueueTest,CreateEmptyBuffer)93 TEST_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
TEST_F(DvrBufferQueueTest,TestDequeuePostDequeueRelease)126 TEST_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
TEST_F(DvrBufferQueueTest,TestGetExternalSurface)189 TEST_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