Allow ProducerBuffer gain posted buffer.

Say there are 3 buffers allocated in buffer queue or some sort of
containers of the buffers, and all of the three buffers are in
posted state. Consumers are taking their time to do other things.
In this case, the producer who is using the buffers from this buffer
container would not be able to produce image because there is no buffer
available (unless the container of the buffer decide to allocate new
buffers). This change allows the container of the buffer decide whether
to reuse an old posted buffer, or to allocate new buffer, for the
producer side of the buffer container to produce image into.

Bug: 80164475
Test: buffer_hub-test on Taimen and Vega
Change-Id: I8c3d10a3b32ffa4bbf24da176a694b12c4dc3a5d
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 4d98dfc..8351efc 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -328,6 +328,36 @@
   EXPECT_FALSE(invalid_fence.IsValid());
 }
 
+TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
+  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
+      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
+  ASSERT_TRUE(p.get() != nullptr);
+
+  // The producer buffer starts in gained state. Post the buffer.
+  ASSERT_EQ(0, p->Post(LocalHandle()));
+
+  // Gain in posted state should only succeed with gain_posted_buffer = true.
+  LocalHandle invalid_fence;
+  EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
+  EXPECT_EQ(0, p->Gain(&invalid_fence, true));
+}
+
+TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
+  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
+      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
+  ASSERT_TRUE(p.get() != nullptr);
+
+  // The producer buffer starts in gained state. Post the buffer.
+  ASSERT_EQ(0, p->Post(LocalHandle()));
+
+  // GainAsync in posted state should only succeed with gain_posted_buffer
+  // equals true.
+  DvrNativeBufferMetadata metadata;
+  LocalHandle invalid_fence;
+  EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
+  EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
+}
+
 TEST_F(LibBufferHubTest, TestZeroConsumer) {
   std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
       kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));