Merge "Allow ProducerBuffer gain posted buffer."
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));
diff --git a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
index d2d4d1e..2761416 100644
--- a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
@@ -52,11 +52,14 @@
// Attempt to re-gain the buffer for writing. If |release_fence| is valid, it
// must be waited on before using the buffer. If it is not valid then the
- // buffer is free for immediate use. This call will only succeed if the buffer
- // is in the released state.
- // This returns zero or a negative unix error code.
- int Gain(LocalHandle* release_fence);
- int GainAsync();
+ // buffer is free for immediate use. This call will succeed if the buffer
+ // is in the released state, or in posted state and gain_posted_buffer is
+ // true.
+ //
+ // @param release_fence output fence.
+ // @param gain_posted_buffer whether to gain posted buffer or not.
+ // @return This returns zero or a negative unix error code.
+ int Gain(LocalHandle* release_fence, bool gain_posted_buffer = false);
// Asynchronously marks a released buffer as gained. This method is similar to
// the synchronous version above, except that it does not wait for BufferHub
@@ -64,7 +67,13 @@
// the underlying message, no error is returned if this method is called when
// the buffer is in an incorrect state. Returns zero if sending the message
// succeeded, or a negative errno code if local error check fails.
- int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
+ // TODO(b/112007999): gain_posted_buffer true is only used to prevent
+ // libdvrtracking from starving when there are non-responding clients. This
+ // gain_posted_buffer param can be removed once libdvrtracking start to use
+ // the new AHardwareBuffer API.
+ int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
+ bool gain_posted_buffer = false);
+ int GainAsync();
// Detaches a ProducerBuffer from an existing producer/consumer set. Can only
// be called when a producer buffer has exclusive access to the buffer (i.e.
@@ -92,7 +101,8 @@
explicit ProducerBuffer(LocalChannelHandle channel);
// Local state transition helpers.
- int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
+ int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
+ bool gain_posted_buffer = false);
int LocalPost(const DvrNativeBufferMetadata* meta,
const LocalHandle& ready_fence);
};
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index 7b6f77a..8f0e3e3 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -134,7 +134,7 @@
}
int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta,
- LocalHandle* out_fence) {
+ LocalHandle* out_fence, bool gain_posted_buffer) {
uint64_t buffer_state = buffer_state_->load();
ALOGD_IF(TRACE, "ProducerBuffer::LocalGain: buffer=%d, state=%" PRIx64 ".",
id(), buffer_state);
@@ -142,13 +142,14 @@
if (!out_meta)
return -EINVAL;
- if (!BufferHubDefs::IsBufferReleased(buffer_state)) {
- if (BufferHubDefs::IsBufferGained(buffer_state)) {
- // We don't want to log error when gaining a newly allocated
- // buffer.
- ALOGI("ProducerBuffer::LocalGain: already gained id=%d.", id());
- return -EALREADY;
- }
+ if (BufferHubDefs::IsBufferGained(buffer_state)) {
+ // We don't want to log error when gaining a newly allocated
+ // buffer.
+ ALOGI("ProducerBuffer::LocalGain: already gained id=%d.", id());
+ return -EALREADY;
+ }
+ if (BufferHubDefs::IsBufferAcquired(buffer_state) ||
+ (BufferHubDefs::IsBufferPosted(buffer_state) && !gain_posted_buffer)) {
ALOGE("ProducerBuffer::LocalGain: not released id=%d state=%" PRIx64 ".",
id(), buffer_state);
return -EBUSY;
@@ -180,11 +181,11 @@
return 0;
}
-int ProducerBuffer::Gain(LocalHandle* release_fence) {
+int ProducerBuffer::Gain(LocalHandle* release_fence, bool gain_posted_buffer) {
ATRACE_NAME("ProducerBuffer::Gain");
DvrNativeBufferMetadata meta;
- if (const int error = LocalGain(&meta, release_fence))
+ if (const int error = LocalGain(&meta, release_fence, gain_posted_buffer))
return error;
auto status = InvokeRemoteMethod<BufferHubRPC::ProducerGain>();
@@ -194,10 +195,11 @@
}
int ProducerBuffer::GainAsync(DvrNativeBufferMetadata* out_meta,
- LocalHandle* release_fence) {
+ LocalHandle* release_fence,
+ bool gain_posted_buffer) {
ATRACE_NAME("ProducerBuffer::GainAsync");
- if (const int error = LocalGain(out_meta, release_fence))
+ if (const int error = LocalGain(out_meta, release_fence, gain_posted_buffer))
return error;
return ReturnStatusOrError(SendImpulse(BufferHubRPC::ProducerGain::Opcode));