blob: 0b9e0cc5b89d7f9bce4ef792ff7ad736c765bfda [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <android/native_window.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08002#include <gtest/gtest.h>
3#include <private/dvr/buffer_hub_client.h>
4
5#include <mutex>
6#include <thread>
7
Alex Vakulenko4fe60582017-02-02 11:35:59 -08008#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
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080017using 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.
Alex Vakulenko4fe60582017-02-02 11:35:59 -080043 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)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080046
47 uint64_t context;
48 LocalHandle fence;
49 EXPECT_LE(0, c->Acquire(&fence, &context));
50 EXPECT_EQ(kContext, context);
Alex Vakulenko4fe60582017-02-02 11:35:59 -080051 EXPECT_GE(0, RETRY_EINTR(c->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080052
53 EXPECT_LE(0, c2->Acquire(&fence, &context));
54 EXPECT_EQ(kContext, context);
Alex Vakulenko4fe60582017-02-02 11:35:59 -080055 EXPECT_GE(0, RETRY_EINTR(c2->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080056
57 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -080058 EXPECT_GE(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080059 EXPECT_EQ(0, c2->Discard());
60
Alex Vakulenko4fe60582017-02-02 11:35:59 -080061 EXPECT_LE(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 EXPECT_EQ(0, p->Gain(&fence));
Alex Vakulenko4fe60582017-02-02 11:35:59 -080063 EXPECT_GE(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080064}
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));
Alex Vakulenko4fe60582017-02-02 11:35:59 -080080 EXPECT_LE(0, RETRY_EINTR(c->Poll(10)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081
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()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -080089 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090}
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));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800106 EXPECT_GE(0, RETRY_EINTR(c->Poll(10)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800107}
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}