bufferhub_tests.cpp revision 4fe60582f314e381098f8f3bc2e39c5880e9243a
1#include <android/native_window.h>
2#include <gtest/gtest.h>
3#include <private/dvr/buffer_hub_client.h>
4
5#include <mutex>
6#include <thread>
7
8#define RETRY_EINTR(fnc_call)                 \
9  ([&]() -> decltype(fnc_call) {              \
10    decltype(fnc_call) result;                \
11    do {                                      \
12      result = (fnc_call);                    \
13    } while (result == -1 && errno == EINTR); \
14    return result;                            \
15  })()
16
17using android::dvr::BufferProducer;
18using android::dvr::BufferConsumer;
19using android::pdx::LocalHandle;
20
21const int kWidth = 640;
22const int kHeight = 480;
23const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
24const int kUsage = 0;
25const uint64_t kContext = 42;
26
27using LibBufferHubTest = ::testing::Test;
28
29TEST_F(LibBufferHubTest, TestBasicUsage) {
30  std::unique_ptr<BufferProducer> p = BufferProducer::Create(
31      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
32  ASSERT_TRUE(p.get() != nullptr);
33  std::unique_ptr<BufferConsumer> c =
34      BufferConsumer::Import(p->CreateConsumer());
35  ASSERT_TRUE(c.get() != nullptr);
36  // Check that consumers can spawn other consumers.
37  std::unique_ptr<BufferConsumer> c2 =
38      BufferConsumer::Import(c->CreateConsumer());
39  ASSERT_TRUE(c2.get() != nullptr);
40
41  EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
42  // Both consumers should be triggered.
43  EXPECT_GE(0, RETRY_EINTR(p->Poll(0)));
44  EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
45  EXPECT_LT(0, RETRY_EINTR(c2->Poll(10)));
46
47  uint64_t context;
48  LocalHandle fence;
49  EXPECT_LE(0, c->Acquire(&fence, &context));
50  EXPECT_EQ(kContext, context);
51  EXPECT_GE(0, RETRY_EINTR(c->Poll(0)));
52
53  EXPECT_LE(0, c2->Acquire(&fence, &context));
54  EXPECT_EQ(kContext, context);
55  EXPECT_GE(0, RETRY_EINTR(c2->Poll(0)));
56
57  EXPECT_EQ(0, c->Release(LocalHandle()));
58  EXPECT_GE(0, RETRY_EINTR(p->Poll(0)));
59  EXPECT_EQ(0, c2->Discard());
60
61  EXPECT_LE(0, RETRY_EINTR(p->Poll(0)));
62  EXPECT_EQ(0, p->Gain(&fence));
63  EXPECT_GE(0, RETRY_EINTR(p->Poll(0)));
64}
65
66TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
67  struct Metadata {
68    int64_t field1;
69    int64_t field2;
70  };
71  std::unique_ptr<BufferProducer> p = BufferProducer::Create(
72      kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
73  ASSERT_TRUE(p.get() != nullptr);
74  std::unique_ptr<BufferConsumer> c =
75      BufferConsumer::Import(p->CreateConsumer());
76  ASSERT_TRUE(c.get() != nullptr);
77
78  Metadata m = {1, 3};
79  EXPECT_EQ(0, p->Post(LocalHandle(), m));
80  EXPECT_LE(0, RETRY_EINTR(c->Poll(10)));
81
82  LocalHandle fence;
83  Metadata m2 = {};
84  EXPECT_EQ(0, c->Acquire(&fence, &m2));
85  EXPECT_EQ(m.field1, m2.field1);
86  EXPECT_EQ(m.field2, m2.field2);
87
88  EXPECT_EQ(0, c->Release(LocalHandle()));
89  EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
90}
91
92TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
93  struct Metadata {
94    int64_t field1;
95    int64_t field2;
96  };
97  std::unique_ptr<BufferProducer> p = BufferProducer::Create(
98      kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
99  ASSERT_TRUE(p.get() != nullptr);
100  std::unique_ptr<BufferConsumer> c =
101      BufferConsumer::Import(p->CreateConsumer());
102  ASSERT_TRUE(c.get() != nullptr);
103
104  int64_t sequence = 3;
105  EXPECT_NE(0, p->Post(LocalHandle(), sequence));
106  EXPECT_GE(0, RETRY_EINTR(c->Poll(10)));
107}
108
109TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
110  struct Metadata {
111    int64_t field1;
112    int64_t field2;
113  };
114  std::unique_ptr<BufferProducer> p = BufferProducer::Create(
115      kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
116  ASSERT_TRUE(p.get() != nullptr);
117  std::unique_ptr<BufferConsumer> c =
118      BufferConsumer::Import(p->CreateConsumer());
119  ASSERT_TRUE(c.get() != nullptr);
120
121  Metadata m = {1, 3};
122  EXPECT_EQ(0, p->Post(LocalHandle(), m));
123
124  LocalHandle fence;
125  int64_t sequence;
126  EXPECT_NE(0, c->Acquire(&fence, &sequence));
127}
128
129TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
130  std::unique_ptr<BufferProducer> p = BufferProducer::Create(
131      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
132  ASSERT_TRUE(p.get() != nullptr);
133  std::unique_ptr<BufferConsumer> c =
134      BufferConsumer::Import(p->CreateConsumer());
135  ASSERT_TRUE(c.get() != nullptr);
136
137  int64_t sequence = 3;
138  EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
139
140  LocalHandle fence;
141  EXPECT_EQ(0, c->Acquire(&fence));
142}
143
144TEST_F(LibBufferHubTest, TestWithNoMeta) {
145  std::unique_ptr<BufferProducer> p =
146      BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
147  ASSERT_TRUE(p.get() != nullptr);
148  std::unique_ptr<BufferConsumer> c =
149      BufferConsumer::Import(p->CreateConsumer());
150  ASSERT_TRUE(c.get() != nullptr);
151
152  LocalHandle fence;
153
154  EXPECT_EQ(0, p->Post<void>(LocalHandle()));
155  EXPECT_EQ(0, c->Acquire(&fence));
156}
157
158TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
159  std::unique_ptr<BufferProducer> p =
160      BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
161  ASSERT_TRUE(p.get() != nullptr);
162  std::unique_ptr<BufferConsumer> c =
163      BufferConsumer::Import(p->CreateConsumer());
164  ASSERT_TRUE(c.get() != nullptr);
165
166  int64_t sequence = 3;
167  EXPECT_NE(0, p->Post(LocalHandle(), sequence));
168}
169
170TEST_F(LibBufferHubTest, TestPersistentBufferPersistence) {
171  auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
172                                  kHeight, kFormat, kUsage);
173  ASSERT_NE(nullptr, p);
174
175  // Record the original buffer id for later comparison.
176  const int buffer_id = p->id();
177
178  auto c = BufferConsumer::Import(p->CreateConsumer());
179  ASSERT_NE(nullptr, c);
180
181  EXPECT_EQ(0, p->Post<void>(LocalHandle()));
182
183  // Close the connection to the producer. This should not affect the consumer.
184  p = nullptr;
185
186  LocalHandle fence;
187  EXPECT_EQ(0, c->Acquire(&fence));
188  EXPECT_EQ(0, c->Release(LocalHandle()));
189
190  // Attempt to reconnect to the persistent buffer.
191  p = BufferProducer::Create("TestPersistentBuffer");
192  ASSERT_NE(nullptr, p);
193  EXPECT_EQ(buffer_id, p->id());
194  EXPECT_EQ(0, p->Gain(&fence));
195}
196
197TEST_F(LibBufferHubTest, TestPersistentBufferMismatchParams) {
198  auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
199                                  kHeight, kFormat, kUsage);
200  ASSERT_NE(nullptr, p);
201
202  // Close the connection to the producer.
203  p = nullptr;
204
205  // Mismatch the params.
206  p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth * 2,
207                             kHeight, kFormat, kUsage);
208  ASSERT_EQ(nullptr, p);
209}
210
211TEST_F(LibBufferHubTest, TestRemovePersistentBuffer) {
212  auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
213                                  kHeight, kFormat, kUsage);
214  ASSERT_NE(nullptr, p);
215
216  LocalHandle fence;
217  auto c = BufferConsumer::Import(p->CreateConsumer());
218  ASSERT_NE(nullptr, c);
219  EXPECT_NE(-EPIPE, c->Acquire(&fence));
220
221  // Test that removing persistence and closing the producer orphans the
222  // consumer.
223  EXPECT_EQ(0, p->RemovePersistence());
224  p = nullptr;
225
226  EXPECT_EQ(-EPIPE, c->Release(LocalHandle()));
227}
228