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