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