Loading libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h +78 −2 Original line number Diff line number Diff line Loading @@ -130,12 +130,88 @@ using LocalFence = FenceHandle<pdx::LocalHandle>; using BorrowedFence = FenceHandle<pdx::BorrowedHandle>; struct ProducerQueueConfig { // Whether the buffer queue is operating in Async mode. // From GVR's perspective of view, this means a buffer can be acquired // asynchronously by the compositor. // From Android Surface's perspective of view, this is equivalent to // IGraphicBufferProducer's async mode. When in async mode, a producer // will never block even if consumer is running slow. bool is_async; // Default buffer width that is set during ProducerQueue's creation. uint32_t default_width; // Default buffer height that is set during ProducerQueue's creation. uint32_t default_height; // Default buffer format that is set during ProducerQueue's creation. uint32_t default_format; // Size of the meta data associated with all the buffers allocated from the // queue. size_t meta_size_bytes; private: PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, meta_size_bytes); PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width, default_height, default_format, meta_size_bytes); }; class ProducerQueueConfigBuilder { public: // Build a ProducerQueueConfig object. ProducerQueueConfig Build() { return {is_async_, default_width_, default_height_, default_format_, meta_size_bytes_}; } ProducerQueueConfigBuilder& SetIsAsync(bool is_async) { is_async_ = is_async; return *this; } ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) { default_width_ = width; return *this; } ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) { default_height_ = height; return *this; } ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) { default_format_ = format; return *this; } template <typename Meta> ProducerQueueConfigBuilder& SetMetadata() { meta_size_bytes_ = sizeof(Meta); return *this; } ProducerQueueConfigBuilder& SetMetadataSize(size_t meta_size_bytes) { meta_size_bytes_ = meta_size_bytes; return *this; } private: bool is_async_{false}; uint32_t default_width_{1}; uint32_t default_height_{1}; uint32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888 size_t meta_size_bytes_{0}; }; // Explicit specializations of ProducerQueueConfigBuilder::Build for void // metadata type. template <> inline ProducerQueueConfigBuilder& ProducerQueueConfigBuilder::SetMetadata<void>() { meta_size_bytes_ = 0; return *this; } struct QueueInfo { ProducerQueueConfig producer_config; int id; Loading Loading @@ -226,7 +302,7 @@ struct BufferHubRPC { // Buffer Queue Methods. PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue, QueueInfo(size_t meta_size_bytes, QueueInfo(const ProducerQueueConfig& producer_config, const UsagePolicy& usage_policy)); PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue, LocalChannelHandle(Void)); Loading libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp +12 −7 Original line number Diff line number Diff line Loading @@ -105,14 +105,18 @@ Status<void> BufferHubQueue::ImportQueue() { status.GetErrorMessage().c_str()); return ErrorStatus(status.error()); } else { SetupQueue(status.get().producer_config.meta_size_bytes, status.get().id); SetupQueue(status.get()); return {}; } } void BufferHubQueue::SetupQueue(size_t meta_size_bytes, int id) { meta_size_ = meta_size_bytes; id_ = id; void BufferHubQueue::SetupQueue(const QueueInfo& queue_info) { is_async_ = queue_info.producer_config.is_async; default_width_ = queue_info.producer_config.default_width; default_height_ = queue_info.producer_config.default_height; default_format_ = queue_info.producer_config.default_format; meta_size_ = queue_info.producer_config.meta_size_bytes; id_ = queue_info.id; } std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() { Loading Loading @@ -405,10 +409,11 @@ ProducerQueue::ProducerQueue(LocalChannelHandle handle) } } ProducerQueue::ProducerQueue(size_t meta_size, const UsagePolicy& usage) ProducerQueue::ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage) : BASE(BufferHubRPC::kClientPath) { auto status = InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(meta_size, usage); InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(config, usage); if (!status) { ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s", status.GetErrorMessage().c_str()); Loading @@ -416,7 +421,7 @@ ProducerQueue::ProducerQueue(size_t meta_size, const UsagePolicy& usage) return; } SetupQueue(status.get().producer_config.meta_size_bytes, status.get().id); SetupQueue(status.get()); } Status<void> ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height, Loading libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -11,8 +11,10 @@ namespace dvr { /* static */ sp<BufferHubQueueProducer> BufferHubQueueProducer::Create() { sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer; producer->queue_ = ProducerQueue::Create<DvrNativeBufferMetadata>(UsagePolicy{}); auto config = ProducerQueueConfigBuilder() .SetMetadata<DvrNativeBufferMetadata>() .Build(); producer->queue_ = ProducerQueue::Create(config, UsagePolicy{}); return producer; } Loading libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h +23 −26 Original line number Diff line number Diff line Loading @@ -33,14 +33,17 @@ class BufferHubQueue : public pdx::Client { // participation in lifecycle events. std::unique_ptr<ConsumerQueue> CreateSilentConsumerQueue(); // Returns whether the buffer queue is in async mode. bool is_async() const { return is_async_; } // Returns the default buffer width of this buffer queue. size_t default_width() const { return default_width_; } uint32_t default_width() const { return default_width_; } // Returns the default buffer height of this buffer queue. size_t default_height() const { return default_height_; } uint32_t default_height() const { return default_height_; } // Returns the default buffer format of this buffer queue. int32_t default_format() const { return default_format_; } uint32_t default_format() const { return default_format_; } // Creates a new consumer in handle form for immediate transport over RPC. pdx::Status<pdx::LocalChannelHandle> CreateConsumerQueueHandle(); Loading Loading @@ -99,7 +102,7 @@ class BufferHubQueue : public pdx::Client { pdx::Status<void> ImportQueue(); // Sets up the queue with the given parameters. void SetupQueue(size_t meta_size_bytes_, int id); void SetupQueue(const QueueInfo& queue_info); // Register a buffer for management by the queue. Used by subclasses to add a // buffer to internal bookkeeping. Loading Loading @@ -182,17 +185,22 @@ class BufferHubQueue : public pdx::Client { return index == BufferHubQueue::kEpollQueueEventIndex; } // Default buffer width that can be set to override the buffer width when a // width and height of 0 are specified in AllocateBuffer. // Whether the buffer queue is operating in Async mode. // From GVR's perspective of view, this means a buffer can be acquired // asynchronously by the compositor. // From Android Surface's perspective of view, this is equivalent to // IGraphicBufferProducer's async mode. When in async mode, a producer // will never block even if consumer is running slow. bool is_async_{false}; // Default buffer width that is set during ProducerQueue's creation. size_t default_width_{1}; // Default buffer height that can be set to override the buffer height when a // width and height of 0 are specified in AllocateBuffer. // Default buffer height that is set during ProducerQueue's creation. size_t default_height_{1}; // Default buffer format that can be set to override the buffer format when it // isn't specified in AllocateBuffer. int32_t default_format_{PIXEL_FORMAT_RGBA_8888}; // Default buffer format that is set during ProducerQueue's creation. int32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888 // Tracks the buffers belonging to this queue. Buffers are stored according to // "slot" in this vector. Each slot is a logical id of the buffer within this Loading Loading @@ -234,13 +242,9 @@ class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> { // this will be rejected. Note that |usage_deny_set_mask| and // |usage_deny_clear_mask| shall not conflict with each other. Such // configuration will be treated as invalid input on creation. template <typename Meta> static std::unique_ptr<ProducerQueue> Create(const UsagePolicy& usage) { return BASE::Create(sizeof(Meta), usage); } static std::unique_ptr<ProducerQueue> Create(size_t meta_size_bytes, const UsagePolicy& usage) { return BASE::Create(meta_size_bytes, usage); static std::unique_ptr<ProducerQueue> Create( const ProducerQueueConfig& config, const UsagePolicy& usage) { return BASE::Create(config, usage); } // Import a ProducerQueue from a channel handle. Loading Loading @@ -291,19 +295,12 @@ class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> { // static template methods inherited from ClientBase, which take the same // arguments as the constructors. explicit ProducerQueue(pdx::LocalChannelHandle handle); ProducerQueue(size_t meta_size, const UsagePolicy& usage); ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage); pdx::Status<Entry> OnBufferReady( const std::shared_ptr<BufferHubBuffer>& buffer, size_t slot) override; }; // Explicit specializations of ProducerQueue::Create for void metadata type. template <> inline std::unique_ptr<ProducerQueue> ProducerQueue::Create<void>( const UsagePolicy& usage) { return ProducerQueue::Create(0, usage); } class ConsumerQueue : public BufferHubQueue { public: // Get a buffer consumer. Note that the method doesn't check whether the Loading libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp +58 −23 Original line number Diff line number Diff line Loading @@ -16,17 +16,17 @@ using pdx::LocalHandle; namespace { constexpr int kBufferWidth = 100; constexpr int kBufferHeight = 1; constexpr int kBufferLayerCount = 1; constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB; constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; constexpr uint32_t kBufferWidth = 100; constexpr uint32_t kBufferHeight = 1; constexpr uint32_t kBufferLayerCount = 1; constexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB; constexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; class BufferHubQueueTest : public ::testing::Test { public: template <typename Meta> bool CreateProducerQueue(const UsagePolicy& usage) { producer_queue_ = ProducerQueue::Create<Meta>(usage); bool CreateProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage) { producer_queue_ = ProducerQueue::Create(config, usage); return producer_queue_ != nullptr; } Loading @@ -39,9 +39,9 @@ class BufferHubQueueTest : public ::testing::Test { } } template <typename Meta> bool CreateQueues(const UsagePolicy& usage) { return CreateProducerQueue<Meta>(usage) && CreateConsumerQueue(); bool CreateQueues(const ProducerQueueConfig& config, const UsagePolicy& usage) { return CreateProducerQueue(config, usage) && CreateConsumerQueue(); } void AllocateBuffer(size_t* slot_out = nullptr) { Loading @@ -57,6 +57,7 @@ class BufferHubQueueTest : public ::testing::Test { } protected: ProducerQueueConfigBuilder config_builder_; std::unique_ptr<ProducerQueue> producer_queue_; std::unique_ptr<ConsumerQueue> consumer_queue_; }; Loading @@ -64,7 +65,8 @@ class BufferHubQueueTest : public ::testing::Test { TEST_F(BufferHubQueueTest, TestDequeue) { const size_t nb_dequeue_times = 16; ASSERT_TRUE(CreateQueues<size_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<size_t>().Build(), UsagePolicy{})); // Allocate only one buffer. AllocateBuffer(); Loading Loading @@ -94,7 +96,8 @@ TEST_F(BufferHubQueueTest, TestProducerConsumer) { size_t slot; uint64_t seq; ASSERT_TRUE(CreateQueues<uint64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(), UsagePolicy{})); for (size_t i = 0; i < kBufferCount; i++) { AllocateBuffer(); Loading Loading @@ -165,7 +168,7 @@ TEST_F(BufferHubQueueTest, TestProducerConsumer) { } TEST_F(BufferHubQueueTest, TestDetach) { ASSERT_TRUE(CreateProducerQueue<void>(UsagePolicy{})); ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); // Allocate buffers. const size_t kBufferCount = 4u; Loading Loading @@ -268,7 +271,9 @@ TEST_F(BufferHubQueueTest, TestDetach) { } TEST_F(BufferHubQueueTest, TestMultipleConsumers) { ASSERT_TRUE(CreateProducerQueue<void>(UsagePolicy{})); // ProducerConfigureBuilder doesn't set Metadata{size}, which means there // is no metadata associated with this BufferQueue's buffer. ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); // Allocate buffers. const size_t kBufferCount = 4u; Loading Loading @@ -346,7 +351,9 @@ struct TestMetadata { }; TEST_F(BufferHubQueueTest, TestMetadata) { ASSERT_TRUE(CreateQueues<TestMetadata>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<TestMetadata>().Build(), UsagePolicy{})); AllocateBuffer(); std::vector<TestMetadata> ms = { Loading @@ -372,7 +379,9 @@ TEST_F(BufferHubQueueTest, TestMetadata) { } TEST_F(BufferHubQueueTest, TestMetadataMismatch) { ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{})); AllocateBuffer(); int64_t mi = 3; Loading @@ -391,7 +400,8 @@ TEST_F(BufferHubQueueTest, TestMetadataMismatch) { } TEST_F(BufferHubQueueTest, TestEnqueue) { ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{})); AllocateBuffer(); size_t slot; Loading @@ -408,7 +418,8 @@ TEST_F(BufferHubQueueTest, TestEnqueue) { } TEST_F(BufferHubQueueTest, TestAllocateBuffer) { ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{})); size_t s1; AllocateBuffer(); Loading Loading @@ -463,7 +474,8 @@ TEST_F(BufferHubQueueTest, TestAllocateBuffer) { TEST_F(BufferHubQueueTest, TestUsageSetMask) { const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{set_mask, 0, 0, 0})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{set_mask, 0, 0, 0})); // When allocation, leave out |set_mask| from usage bits on purpose. size_t slot; Loading @@ -481,7 +493,8 @@ TEST_F(BufferHubQueueTest, TestUsageSetMask) { TEST_F(BufferHubQueueTest, TestUsageClearMask) { const uint32_t clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{0, clear_mask, 0, 0})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{0, clear_mask, 0, 0})); // When allocation, add |clear_mask| into usage bits on purpose. size_t slot; Loading @@ -499,7 +512,8 @@ TEST_F(BufferHubQueueTest, TestUsageClearMask) { TEST_F(BufferHubQueueTest, TestUsageDenySetMask) { const uint32_t deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{0, 0, deny_set_mask, 0})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{0, 0, deny_set_mask, 0})); // Now that |deny_set_mask| is illegal, allocation without those bits should // be able to succeed. Loading @@ -519,7 +533,8 @@ TEST_F(BufferHubQueueTest, TestUsageDenySetMask) { TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) { const uint32_t deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{0, 0, 0, deny_clear_mask})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{0, 0, 0, deny_clear_mask})); // Now that clearing |deny_clear_mask| is illegal (i.e. setting these bits are // mandatory), allocation with those bits should be able to succeed. Loading @@ -537,6 +552,26 @@ TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) { ASSERT_EQ(EINVAL, status.error()); } TEST_F(BufferHubQueueTest, TestQueueInfo) { static const bool kIsAsync = true; ASSERT_TRUE(CreateQueues(config_builder_.SetIsAsync(kIsAsync) .SetDefaultWidth(kBufferWidth) .SetDefaultHeight(kBufferHeight) .SetDefaultFormat(kBufferFormat) .Build(), UsagePolicy{})); EXPECT_EQ(producer_queue_->default_width(), kBufferWidth); EXPECT_EQ(producer_queue_->default_height(), kBufferHeight); EXPECT_EQ(producer_queue_->default_format(), kBufferFormat); EXPECT_EQ(producer_queue_->is_async(), kIsAsync); EXPECT_EQ(consumer_queue_->default_width(), kBufferWidth); EXPECT_EQ(consumer_queue_->default_height(), kBufferHeight); EXPECT_EQ(consumer_queue_->default_format(), kBufferFormat); EXPECT_EQ(consumer_queue_->is_async(), kIsAsync); } } // namespace } // namespace dvr Loading Loading
libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h +78 −2 Original line number Diff line number Diff line Loading @@ -130,12 +130,88 @@ using LocalFence = FenceHandle<pdx::LocalHandle>; using BorrowedFence = FenceHandle<pdx::BorrowedHandle>; struct ProducerQueueConfig { // Whether the buffer queue is operating in Async mode. // From GVR's perspective of view, this means a buffer can be acquired // asynchronously by the compositor. // From Android Surface's perspective of view, this is equivalent to // IGraphicBufferProducer's async mode. When in async mode, a producer // will never block even if consumer is running slow. bool is_async; // Default buffer width that is set during ProducerQueue's creation. uint32_t default_width; // Default buffer height that is set during ProducerQueue's creation. uint32_t default_height; // Default buffer format that is set during ProducerQueue's creation. uint32_t default_format; // Size of the meta data associated with all the buffers allocated from the // queue. size_t meta_size_bytes; private: PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, meta_size_bytes); PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width, default_height, default_format, meta_size_bytes); }; class ProducerQueueConfigBuilder { public: // Build a ProducerQueueConfig object. ProducerQueueConfig Build() { return {is_async_, default_width_, default_height_, default_format_, meta_size_bytes_}; } ProducerQueueConfigBuilder& SetIsAsync(bool is_async) { is_async_ = is_async; return *this; } ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) { default_width_ = width; return *this; } ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) { default_height_ = height; return *this; } ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) { default_format_ = format; return *this; } template <typename Meta> ProducerQueueConfigBuilder& SetMetadata() { meta_size_bytes_ = sizeof(Meta); return *this; } ProducerQueueConfigBuilder& SetMetadataSize(size_t meta_size_bytes) { meta_size_bytes_ = meta_size_bytes; return *this; } private: bool is_async_{false}; uint32_t default_width_{1}; uint32_t default_height_{1}; uint32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888 size_t meta_size_bytes_{0}; }; // Explicit specializations of ProducerQueueConfigBuilder::Build for void // metadata type. template <> inline ProducerQueueConfigBuilder& ProducerQueueConfigBuilder::SetMetadata<void>() { meta_size_bytes_ = 0; return *this; } struct QueueInfo { ProducerQueueConfig producer_config; int id; Loading Loading @@ -226,7 +302,7 @@ struct BufferHubRPC { // Buffer Queue Methods. PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue, QueueInfo(size_t meta_size_bytes, QueueInfo(const ProducerQueueConfig& producer_config, const UsagePolicy& usage_policy)); PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue, LocalChannelHandle(Void)); Loading
libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp +12 −7 Original line number Diff line number Diff line Loading @@ -105,14 +105,18 @@ Status<void> BufferHubQueue::ImportQueue() { status.GetErrorMessage().c_str()); return ErrorStatus(status.error()); } else { SetupQueue(status.get().producer_config.meta_size_bytes, status.get().id); SetupQueue(status.get()); return {}; } } void BufferHubQueue::SetupQueue(size_t meta_size_bytes, int id) { meta_size_ = meta_size_bytes; id_ = id; void BufferHubQueue::SetupQueue(const QueueInfo& queue_info) { is_async_ = queue_info.producer_config.is_async; default_width_ = queue_info.producer_config.default_width; default_height_ = queue_info.producer_config.default_height; default_format_ = queue_info.producer_config.default_format; meta_size_ = queue_info.producer_config.meta_size_bytes; id_ = queue_info.id; } std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() { Loading Loading @@ -405,10 +409,11 @@ ProducerQueue::ProducerQueue(LocalChannelHandle handle) } } ProducerQueue::ProducerQueue(size_t meta_size, const UsagePolicy& usage) ProducerQueue::ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage) : BASE(BufferHubRPC::kClientPath) { auto status = InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(meta_size, usage); InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(config, usage); if (!status) { ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s", status.GetErrorMessage().c_str()); Loading @@ -416,7 +421,7 @@ ProducerQueue::ProducerQueue(size_t meta_size, const UsagePolicy& usage) return; } SetupQueue(status.get().producer_config.meta_size_bytes, status.get().id); SetupQueue(status.get()); } Status<void> ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height, Loading
libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -11,8 +11,10 @@ namespace dvr { /* static */ sp<BufferHubQueueProducer> BufferHubQueueProducer::Create() { sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer; producer->queue_ = ProducerQueue::Create<DvrNativeBufferMetadata>(UsagePolicy{}); auto config = ProducerQueueConfigBuilder() .SetMetadata<DvrNativeBufferMetadata>() .Build(); producer->queue_ = ProducerQueue::Create(config, UsagePolicy{}); return producer; } Loading
libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h +23 −26 Original line number Diff line number Diff line Loading @@ -33,14 +33,17 @@ class BufferHubQueue : public pdx::Client { // participation in lifecycle events. std::unique_ptr<ConsumerQueue> CreateSilentConsumerQueue(); // Returns whether the buffer queue is in async mode. bool is_async() const { return is_async_; } // Returns the default buffer width of this buffer queue. size_t default_width() const { return default_width_; } uint32_t default_width() const { return default_width_; } // Returns the default buffer height of this buffer queue. size_t default_height() const { return default_height_; } uint32_t default_height() const { return default_height_; } // Returns the default buffer format of this buffer queue. int32_t default_format() const { return default_format_; } uint32_t default_format() const { return default_format_; } // Creates a new consumer in handle form for immediate transport over RPC. pdx::Status<pdx::LocalChannelHandle> CreateConsumerQueueHandle(); Loading Loading @@ -99,7 +102,7 @@ class BufferHubQueue : public pdx::Client { pdx::Status<void> ImportQueue(); // Sets up the queue with the given parameters. void SetupQueue(size_t meta_size_bytes_, int id); void SetupQueue(const QueueInfo& queue_info); // Register a buffer for management by the queue. Used by subclasses to add a // buffer to internal bookkeeping. Loading Loading @@ -182,17 +185,22 @@ class BufferHubQueue : public pdx::Client { return index == BufferHubQueue::kEpollQueueEventIndex; } // Default buffer width that can be set to override the buffer width when a // width and height of 0 are specified in AllocateBuffer. // Whether the buffer queue is operating in Async mode. // From GVR's perspective of view, this means a buffer can be acquired // asynchronously by the compositor. // From Android Surface's perspective of view, this is equivalent to // IGraphicBufferProducer's async mode. When in async mode, a producer // will never block even if consumer is running slow. bool is_async_{false}; // Default buffer width that is set during ProducerQueue's creation. size_t default_width_{1}; // Default buffer height that can be set to override the buffer height when a // width and height of 0 are specified in AllocateBuffer. // Default buffer height that is set during ProducerQueue's creation. size_t default_height_{1}; // Default buffer format that can be set to override the buffer format when it // isn't specified in AllocateBuffer. int32_t default_format_{PIXEL_FORMAT_RGBA_8888}; // Default buffer format that is set during ProducerQueue's creation. int32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888 // Tracks the buffers belonging to this queue. Buffers are stored according to // "slot" in this vector. Each slot is a logical id of the buffer within this Loading Loading @@ -234,13 +242,9 @@ class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> { // this will be rejected. Note that |usage_deny_set_mask| and // |usage_deny_clear_mask| shall not conflict with each other. Such // configuration will be treated as invalid input on creation. template <typename Meta> static std::unique_ptr<ProducerQueue> Create(const UsagePolicy& usage) { return BASE::Create(sizeof(Meta), usage); } static std::unique_ptr<ProducerQueue> Create(size_t meta_size_bytes, const UsagePolicy& usage) { return BASE::Create(meta_size_bytes, usage); static std::unique_ptr<ProducerQueue> Create( const ProducerQueueConfig& config, const UsagePolicy& usage) { return BASE::Create(config, usage); } // Import a ProducerQueue from a channel handle. Loading Loading @@ -291,19 +295,12 @@ class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> { // static template methods inherited from ClientBase, which take the same // arguments as the constructors. explicit ProducerQueue(pdx::LocalChannelHandle handle); ProducerQueue(size_t meta_size, const UsagePolicy& usage); ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage); pdx::Status<Entry> OnBufferReady( const std::shared_ptr<BufferHubBuffer>& buffer, size_t slot) override; }; // Explicit specializations of ProducerQueue::Create for void metadata type. template <> inline std::unique_ptr<ProducerQueue> ProducerQueue::Create<void>( const UsagePolicy& usage) { return ProducerQueue::Create(0, usage); } class ConsumerQueue : public BufferHubQueue { public: // Get a buffer consumer. Note that the method doesn't check whether the Loading
libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp +58 −23 Original line number Diff line number Diff line Loading @@ -16,17 +16,17 @@ using pdx::LocalHandle; namespace { constexpr int kBufferWidth = 100; constexpr int kBufferHeight = 1; constexpr int kBufferLayerCount = 1; constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB; constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; constexpr uint32_t kBufferWidth = 100; constexpr uint32_t kBufferHeight = 1; constexpr uint32_t kBufferLayerCount = 1; constexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB; constexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; class BufferHubQueueTest : public ::testing::Test { public: template <typename Meta> bool CreateProducerQueue(const UsagePolicy& usage) { producer_queue_ = ProducerQueue::Create<Meta>(usage); bool CreateProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage) { producer_queue_ = ProducerQueue::Create(config, usage); return producer_queue_ != nullptr; } Loading @@ -39,9 +39,9 @@ class BufferHubQueueTest : public ::testing::Test { } } template <typename Meta> bool CreateQueues(const UsagePolicy& usage) { return CreateProducerQueue<Meta>(usage) && CreateConsumerQueue(); bool CreateQueues(const ProducerQueueConfig& config, const UsagePolicy& usage) { return CreateProducerQueue(config, usage) && CreateConsumerQueue(); } void AllocateBuffer(size_t* slot_out = nullptr) { Loading @@ -57,6 +57,7 @@ class BufferHubQueueTest : public ::testing::Test { } protected: ProducerQueueConfigBuilder config_builder_; std::unique_ptr<ProducerQueue> producer_queue_; std::unique_ptr<ConsumerQueue> consumer_queue_; }; Loading @@ -64,7 +65,8 @@ class BufferHubQueueTest : public ::testing::Test { TEST_F(BufferHubQueueTest, TestDequeue) { const size_t nb_dequeue_times = 16; ASSERT_TRUE(CreateQueues<size_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<size_t>().Build(), UsagePolicy{})); // Allocate only one buffer. AllocateBuffer(); Loading Loading @@ -94,7 +96,8 @@ TEST_F(BufferHubQueueTest, TestProducerConsumer) { size_t slot; uint64_t seq; ASSERT_TRUE(CreateQueues<uint64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(), UsagePolicy{})); for (size_t i = 0; i < kBufferCount; i++) { AllocateBuffer(); Loading Loading @@ -165,7 +168,7 @@ TEST_F(BufferHubQueueTest, TestProducerConsumer) { } TEST_F(BufferHubQueueTest, TestDetach) { ASSERT_TRUE(CreateProducerQueue<void>(UsagePolicy{})); ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); // Allocate buffers. const size_t kBufferCount = 4u; Loading Loading @@ -268,7 +271,9 @@ TEST_F(BufferHubQueueTest, TestDetach) { } TEST_F(BufferHubQueueTest, TestMultipleConsumers) { ASSERT_TRUE(CreateProducerQueue<void>(UsagePolicy{})); // ProducerConfigureBuilder doesn't set Metadata{size}, which means there // is no metadata associated with this BufferQueue's buffer. ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); // Allocate buffers. const size_t kBufferCount = 4u; Loading Loading @@ -346,7 +351,9 @@ struct TestMetadata { }; TEST_F(BufferHubQueueTest, TestMetadata) { ASSERT_TRUE(CreateQueues<TestMetadata>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<TestMetadata>().Build(), UsagePolicy{})); AllocateBuffer(); std::vector<TestMetadata> ms = { Loading @@ -372,7 +379,9 @@ TEST_F(BufferHubQueueTest, TestMetadata) { } TEST_F(BufferHubQueueTest, TestMetadataMismatch) { ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{})); AllocateBuffer(); int64_t mi = 3; Loading @@ -391,7 +400,8 @@ TEST_F(BufferHubQueueTest, TestMetadataMismatch) { } TEST_F(BufferHubQueueTest, TestEnqueue) { ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{})); AllocateBuffer(); size_t slot; Loading @@ -408,7 +418,8 @@ TEST_F(BufferHubQueueTest, TestEnqueue) { } TEST_F(BufferHubQueueTest, TestAllocateBuffer) { ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{})); size_t s1; AllocateBuffer(); Loading Loading @@ -463,7 +474,8 @@ TEST_F(BufferHubQueueTest, TestAllocateBuffer) { TEST_F(BufferHubQueueTest, TestUsageSetMask) { const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{set_mask, 0, 0, 0})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{set_mask, 0, 0, 0})); // When allocation, leave out |set_mask| from usage bits on purpose. size_t slot; Loading @@ -481,7 +493,8 @@ TEST_F(BufferHubQueueTest, TestUsageSetMask) { TEST_F(BufferHubQueueTest, TestUsageClearMask) { const uint32_t clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{0, clear_mask, 0, 0})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{0, clear_mask, 0, 0})); // When allocation, add |clear_mask| into usage bits on purpose. size_t slot; Loading @@ -499,7 +512,8 @@ TEST_F(BufferHubQueueTest, TestUsageClearMask) { TEST_F(BufferHubQueueTest, TestUsageDenySetMask) { const uint32_t deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{0, 0, deny_set_mask, 0})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{0, 0, deny_set_mask, 0})); // Now that |deny_set_mask| is illegal, allocation without those bits should // be able to succeed. Loading @@ -519,7 +533,8 @@ TEST_F(BufferHubQueueTest, TestUsageDenySetMask) { TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) { const uint32_t deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; ASSERT_TRUE(CreateQueues<int64_t>(UsagePolicy{0, 0, 0, deny_clear_mask})); ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), UsagePolicy{0, 0, 0, deny_clear_mask})); // Now that clearing |deny_clear_mask| is illegal (i.e. setting these bits are // mandatory), allocation with those bits should be able to succeed. Loading @@ -537,6 +552,26 @@ TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) { ASSERT_EQ(EINVAL, status.error()); } TEST_F(BufferHubQueueTest, TestQueueInfo) { static const bool kIsAsync = true; ASSERT_TRUE(CreateQueues(config_builder_.SetIsAsync(kIsAsync) .SetDefaultWidth(kBufferWidth) .SetDefaultHeight(kBufferHeight) .SetDefaultFormat(kBufferFormat) .Build(), UsagePolicy{})); EXPECT_EQ(producer_queue_->default_width(), kBufferWidth); EXPECT_EQ(producer_queue_->default_height(), kBufferHeight); EXPECT_EQ(producer_queue_->default_format(), kBufferFormat); EXPECT_EQ(producer_queue_->is_async(), kIsAsync); EXPECT_EQ(consumer_queue_->default_width(), kBufferWidth); EXPECT_EQ(consumer_queue_->default_height(), kBufferHeight); EXPECT_EQ(consumer_queue_->default_format(), kBufferFormat); EXPECT_EQ(consumer_queue_->is_async(), kIsAsync); } } // namespace } // namespace dvr Loading