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