diff options
-rw-r--r-- | libs/vr/libbufferhub/buffer_hub-test.cpp | 30 | ||||
-rw-r--r-- | libs/vr/libbufferhub/include/private/dvr/producer_buffer.h | 24 | ||||
-rw-r--r-- | libs/vr/libbufferhub/producer_buffer.cpp | 26 |
3 files changed, 61 insertions, 19 deletions
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp index 4d98dfc8da..8351efce40 100644 --- a/libs/vr/libbufferhub/buffer_hub-test.cpp +++ b/libs/vr/libbufferhub/buffer_hub-test.cpp @@ -328,6 +328,36 @@ TEST_F(LibBufferHubTest, TestAsyncStateTransitions) { 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 d2d4d1ebb3..2761416034 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 @@ class ProducerBuffer : public pdx::ClientBase<ProducerBuffer, BufferHubBase> { // 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 @@ class ProducerBuffer : public pdx::ClientBase<ProducerBuffer, BufferHubBase> { // 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 @@ class ProducerBuffer : public pdx::ClientBase<ProducerBuffer, BufferHubBase> { 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 7b6f77abf5..8f0e3e385a 100644 --- a/libs/vr/libbufferhub/producer_buffer.cpp +++ b/libs/vr/libbufferhub/producer_buffer.cpp @@ -134,7 +134,7 @@ int ProducerBuffer::PostAsync(const DvrNativeBufferMetadata* meta, } 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 @@ int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta, 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 @@ int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta, 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::Gain(LocalHandle* release_fence) { } 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)); |