Loading libs/vr/libbufferhub/buffer_hub-test.cpp +9 −17 Original line number Diff line number Diff line Loading @@ -361,9 +361,11 @@ TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) { ASSERT_TRUE(p.get() != nullptr); ASSERT_EQ(0, p->GainAsync()); ASSERT_EQ(0, p->Post(LocalHandle())); // Producer state bit is in released state after post. The overall state of // the buffer is also released because there is no consumer of this buffer. ASSERT_TRUE(IsBufferReleased(p->buffer_state())); // Producer state bit is in released state after post, other clients shall be // in posted state although there is no consumer of this buffer yet. ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask())); ASSERT_FALSE(IsBufferReleased(p->buffer_state())); ASSERT_TRUE(AnyClientPosted(p->buffer_state())); // Gain in released state should succeed. LocalHandle invalid_fence; Loading Loading @@ -450,27 +452,17 @@ TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) { LocalHandle invalid_fence; // Post the gained buffer before any consumer gets created. // The buffer should be in released state because it is not expected to be // read by any clients. EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); EXPECT_TRUE(IsBufferReleased(p->buffer_state())); EXPECT_FALSE(IsBufferReleased(p->buffer_state())); EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs))); // Newly created consumer will not be signalled for the posted buffer before // its creation. It cannot acquire the buffer immediately. // Newly created consumer will be signalled for the posted buffer although it // is created after producer posting. std::unique_ptr<ConsumerBuffer> c = ConsumerBuffer::Import(p->CreateConsumer()); ASSERT_TRUE(c.get() != nullptr); EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask())); EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence)); // Producer should be able to gain back and post the buffer EXPECT_EQ(0, p->GainAsync()); EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); // Consumer should be able to pick up the buffer this time. EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask())); EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask())); } TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) { Loading libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h +6 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,12 @@ class BufferHubBase : public pdx::Client { return buffer_state_->load(std::memory_order_acquire); }; // Returns whether the buffer is already released by all current clients. bool is_released() { return (buffer_state() & active_clients_bit_mask_->load(std::memory_order_acquire)) == 0; } // A state mask which is unique to a buffer hub client among all its siblings // sharing the same concrete graphic buffer. uint32_t client_state_mask() const { return client_state_mask_; } Loading libs/vr/libbufferhub/producer_buffer.cpp +10 −9 Original line number Diff line number Diff line Loading @@ -89,13 +89,10 @@ int ProducerBuffer::LocalPost(const DvrNativeBufferMetadata* meta, return -EBUSY; } // Set the producer client buffer state to released, other clients' buffer // state to posted. uint32_t current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire); uint32_t updated_buffer_state = current_active_clients_bit_mask & (~client_state_mask()) & BufferHubDefs::kHighBitsMask; // Set the producer client buffer state to released, that of all other clients // (both existing and non-existing clients) to posted. uint32_t updated_buffer_state = (~client_state_mask()) & BufferHubDefs::kHighBitsMask; while (!buffer_state_->compare_exchange_weak( current_buffer_state, updated_buffer_state, std::memory_order_acq_rel, std::memory_order_acquire)) { Loading Loading @@ -176,7 +173,9 @@ int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta, } if (BufferHubDefs::AnyClientAcquired(current_buffer_state) || BufferHubDefs::AnyClientGained(current_buffer_state) || (BufferHubDefs::AnyClientPosted(current_buffer_state) && (BufferHubDefs::AnyClientPosted( current_buffer_state & active_clients_bit_mask_->load(std::memory_order_acquire)) && !gain_posted_buffer)) { ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(), current_buffer_state); Loading @@ -198,7 +197,9 @@ int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta, if (BufferHubDefs::AnyClientAcquired(current_buffer_state) || BufferHubDefs::AnyClientGained(current_buffer_state) || (BufferHubDefs::AnyClientPosted(current_buffer_state) && (BufferHubDefs::AnyClientPosted( current_buffer_state & active_clients_bit_mask_->load(std::memory_order_acquire)) && !gain_posted_buffer)) { ALOGE( "%s: Failed to gain the buffer. The buffer is no longer released. " Loading services/vr/bufferhubd/producer_channel.cpp +15 −3 Original line number Diff line number Diff line Loading @@ -369,7 +369,9 @@ Status<RemoteChannelHandle> ProducerChannel::CreateConsumer( (consumer_state_mask & BufferHubDefs::kHighBitsMask); } } if (update_buffer_state) { if (update_buffer_state || BufferHubDefs::IsClientPosted( buffer_state_->load(std::memory_order_acquire), consumer_state_mask)) { consumer->OnProducerPosted(); } Loading Loading @@ -537,8 +539,13 @@ Status<void> ProducerChannel::OnConsumerRelease(Message&, uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire); uint32_t current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire); // Signal producer if all current active consumers have released the buffer. if (BufferHubDefs::IsBufferReleased(current_buffer_state & ~orphaned_consumer_bit_mask_)) { ~orphaned_consumer_bit_mask_ & current_active_clients_bit_mask)) { buffer_state_->store(0U); SignalAvailable(); if (orphaned_consumer_bit_mask_) { ALOGW( Loading @@ -564,8 +571,13 @@ void ProducerChannel::OnConsumerOrphaned(const uint32_t& consumer_state_mask) { uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire); uint32_t current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire); // Signal producer if all current active consumers have released the buffer. if (BufferHubDefs::IsBufferReleased(current_buffer_state & ~orphaned_consumer_bit_mask_)) { ~orphaned_consumer_bit_mask_ & current_active_clients_bit_mask)) { buffer_state_->store(0U); SignalAvailable(); } Loading Loading
libs/vr/libbufferhub/buffer_hub-test.cpp +9 −17 Original line number Diff line number Diff line Loading @@ -361,9 +361,11 @@ TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) { ASSERT_TRUE(p.get() != nullptr); ASSERT_EQ(0, p->GainAsync()); ASSERT_EQ(0, p->Post(LocalHandle())); // Producer state bit is in released state after post. The overall state of // the buffer is also released because there is no consumer of this buffer. ASSERT_TRUE(IsBufferReleased(p->buffer_state())); // Producer state bit is in released state after post, other clients shall be // in posted state although there is no consumer of this buffer yet. ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask())); ASSERT_FALSE(IsBufferReleased(p->buffer_state())); ASSERT_TRUE(AnyClientPosted(p->buffer_state())); // Gain in released state should succeed. LocalHandle invalid_fence; Loading Loading @@ -450,27 +452,17 @@ TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) { LocalHandle invalid_fence; // Post the gained buffer before any consumer gets created. // The buffer should be in released state because it is not expected to be // read by any clients. EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); EXPECT_TRUE(IsBufferReleased(p->buffer_state())); EXPECT_FALSE(IsBufferReleased(p->buffer_state())); EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs))); // Newly created consumer will not be signalled for the posted buffer before // its creation. It cannot acquire the buffer immediately. // Newly created consumer will be signalled for the posted buffer although it // is created after producer posting. std::unique_ptr<ConsumerBuffer> c = ConsumerBuffer::Import(p->CreateConsumer()); ASSERT_TRUE(c.get() != nullptr); EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask())); EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence)); // Producer should be able to gain back and post the buffer EXPECT_EQ(0, p->GainAsync()); EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); // Consumer should be able to pick up the buffer this time. EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask())); EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask())); } TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) { Loading
libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h +6 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,12 @@ class BufferHubBase : public pdx::Client { return buffer_state_->load(std::memory_order_acquire); }; // Returns whether the buffer is already released by all current clients. bool is_released() { return (buffer_state() & active_clients_bit_mask_->load(std::memory_order_acquire)) == 0; } // A state mask which is unique to a buffer hub client among all its siblings // sharing the same concrete graphic buffer. uint32_t client_state_mask() const { return client_state_mask_; } Loading
libs/vr/libbufferhub/producer_buffer.cpp +10 −9 Original line number Diff line number Diff line Loading @@ -89,13 +89,10 @@ int ProducerBuffer::LocalPost(const DvrNativeBufferMetadata* meta, return -EBUSY; } // Set the producer client buffer state to released, other clients' buffer // state to posted. uint32_t current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire); uint32_t updated_buffer_state = current_active_clients_bit_mask & (~client_state_mask()) & BufferHubDefs::kHighBitsMask; // Set the producer client buffer state to released, that of all other clients // (both existing and non-existing clients) to posted. uint32_t updated_buffer_state = (~client_state_mask()) & BufferHubDefs::kHighBitsMask; while (!buffer_state_->compare_exchange_weak( current_buffer_state, updated_buffer_state, std::memory_order_acq_rel, std::memory_order_acquire)) { Loading Loading @@ -176,7 +173,9 @@ int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta, } if (BufferHubDefs::AnyClientAcquired(current_buffer_state) || BufferHubDefs::AnyClientGained(current_buffer_state) || (BufferHubDefs::AnyClientPosted(current_buffer_state) && (BufferHubDefs::AnyClientPosted( current_buffer_state & active_clients_bit_mask_->load(std::memory_order_acquire)) && !gain_posted_buffer)) { ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(), current_buffer_state); Loading @@ -198,7 +197,9 @@ int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta, if (BufferHubDefs::AnyClientAcquired(current_buffer_state) || BufferHubDefs::AnyClientGained(current_buffer_state) || (BufferHubDefs::AnyClientPosted(current_buffer_state) && (BufferHubDefs::AnyClientPosted( current_buffer_state & active_clients_bit_mask_->load(std::memory_order_acquire)) && !gain_posted_buffer)) { ALOGE( "%s: Failed to gain the buffer. The buffer is no longer released. " Loading
services/vr/bufferhubd/producer_channel.cpp +15 −3 Original line number Diff line number Diff line Loading @@ -369,7 +369,9 @@ Status<RemoteChannelHandle> ProducerChannel::CreateConsumer( (consumer_state_mask & BufferHubDefs::kHighBitsMask); } } if (update_buffer_state) { if (update_buffer_state || BufferHubDefs::IsClientPosted( buffer_state_->load(std::memory_order_acquire), consumer_state_mask)) { consumer->OnProducerPosted(); } Loading Loading @@ -537,8 +539,13 @@ Status<void> ProducerChannel::OnConsumerRelease(Message&, uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire); uint32_t current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire); // Signal producer if all current active consumers have released the buffer. if (BufferHubDefs::IsBufferReleased(current_buffer_state & ~orphaned_consumer_bit_mask_)) { ~orphaned_consumer_bit_mask_ & current_active_clients_bit_mask)) { buffer_state_->store(0U); SignalAvailable(); if (orphaned_consumer_bit_mask_) { ALOGW( Loading @@ -564,8 +571,13 @@ void ProducerChannel::OnConsumerOrphaned(const uint32_t& consumer_state_mask) { uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire); uint32_t current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire); // Signal producer if all current active consumers have released the buffer. if (BufferHubDefs::IsBufferReleased(current_buffer_state & ~orphaned_consumer_bit_mask_)) { ~orphaned_consumer_bit_mask_ & current_active_clients_bit_mask)) { buffer_state_->store(0U); SignalAvailable(); } Loading