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