#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_ #define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_ #include "buffer_hub.h" #include #include #include #include #include #include #include #include namespace android { namespace dvr { // The buffer changes ownership according to the following sequence: // POST -> ACQUIRE/RELEASE (all consumers) -> GAIN (producer acquires) -> POST // The producer channel is owned by a single app that writes into buffers and // calls POST when drawing is complete. This channel has a set of consumer // channels associated with it that are waiting for notifications. class ProducerChannel : public BufferHubChannel { public: using Message = pdx::Message; using BorrowedHandle = pdx::BorrowedHandle; using RemoteChannelHandle = pdx::RemoteChannelHandle; template using BufferWrapper = pdx::rpc::BufferWrapper; static std::unique_ptr Create(BufferHubService* service, int buffer_id, int channel_id, IonBuffer buffer, IonBuffer metadata_buffer, size_t user_metadata_size); static pdx::Status> Create( BufferHubService* service, int channel_id, uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, uint64_t usage, size_t user_metadata_size); ~ProducerChannel() override; bool HandleMessage(Message& message) override; void HandleImpulse(Message& message) override; BufferInfo GetBufferInfo() const override; BufferDescription GetBuffer(uint64_t buffer_state_bit); pdx::Status CreateConsumer(Message& message); pdx::Status OnNewConsumer(Message& message); pdx::Status OnConsumerAcquire(Message& message); pdx::Status OnConsumerRelease(Message& message, LocalFence release_fence); void OnConsumerIgnored(); void OnConsumerOrphaned(ConsumerChannel* channel); void AddConsumer(ConsumerChannel* channel); void RemoveConsumer(ConsumerChannel* channel); bool CheckParameters(uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, uint64_t usage, size_t user_metadata_size); private: std::vector consumer_channels_; // This counts the number of consumers left to process this buffer. If this is // zero then the producer can re-acquire ownership. int pending_consumers_; IonBuffer buffer_; // IonBuffer that is shared between bufferhubd, producer, and consumers. IonBuffer metadata_buffer_; BufferHubDefs::MetadataHeader* metadata_header_ = nullptr; std::atomic* buffer_state_ = nullptr; std::atomic* fence_state_ = nullptr; // All active consumer bits. Valid bits are the lower 63 bits, while the // highest bit is reserved for the producer and should not be set. uint64_t active_consumer_bit_mask_{0ULL}; // All orphaned consumer bits. Valid bits are the lower 63 bits, while the // highest bit is reserved for the producer and should not be set. uint64_t orphaned_consumer_bit_mask_{0ULL}; bool producer_owns_; LocalFence post_fence_; LocalFence returned_fence_; size_t user_metadata_size_; // size of user requested buffer buffer size. size_t metadata_buf_size_; // size of the ion buffer that holds metadata. pdx::LocalHandle acquire_fence_fd_; pdx::LocalHandle release_fence_fd_; pdx::LocalHandle dummy_fence_fd_; ProducerChannel(BufferHubService* service, int buffer_id, int channel_id, IonBuffer buffer, IonBuffer metadata_buffer, size_t user_metadata_size, int* error); ProducerChannel(BufferHubService* service, int channel, uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, uint64_t usage, size_t user_metadata_size, int* error); int InitializeBuffer(); pdx::Status> OnGetBuffer(Message& message); pdx::Status OnProducerPost(Message& message, LocalFence acquire_fence); pdx::Status OnProducerGain(Message& message); pdx::Status OnProducerDetach(Message& message); ProducerChannel(const ProducerChannel&) = delete; void operator=(const ProducerChannel&) = delete; }; } // namespace dvr } // namespace android #endif // ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_