| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 1 | #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_ |
| 2 | #define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_ |
| 3 | |
| 4 | #include "buffer_hub.h" |
| 5 | |
| 6 | #include <functional> |
| 7 | #include <memory> |
| 8 | #include <vector> |
| 9 | |
| 10 | #include <pdx/channel_handle.h> |
| 11 | #include <pdx/file_handle.h> |
| 12 | #include <pdx/rpc/buffer_wrapper.h> |
| 13 | #include <private/dvr/bufferhub_rpc.h> |
| 14 | #include <private/dvr/ion_buffer.h> |
| 15 | |
| 16 | namespace android { |
| 17 | namespace dvr { |
| 18 | |
| 19 | // The buffer changes ownership according to the following sequence: |
| 20 | // POST -> ACQUIRE/RELEASE (all consumers) -> GAIN (producer acquires) -> POST |
| 21 | |
| 22 | // The producer channel is owned by a single app that writes into buffers and |
| 23 | // calls POST when drawing is complete. This channel has a set of consumer |
| 24 | // channels associated with it that are waiting for notifications. |
| 25 | class ProducerChannel : public BufferHubChannel { |
| 26 | public: |
| 27 | using Message = pdx::Message; |
| 28 | using BorrowedHandle = pdx::BorrowedHandle; |
| 29 | using RemoteChannelHandle = pdx::RemoteChannelHandle; |
| 30 | template <typename T> |
| 31 | using BufferWrapper = pdx::rpc::BufferWrapper<T>; |
| 32 | |
| Jiwen 'Steve' Cai | 0728fa9 | 2018-04-24 19:03:14 -0700 | [diff] [blame] | 33 | static std::unique_ptr<ProducerChannel> Create(BufferHubService* service, |
| 34 | int buffer_id, int channel_id, |
| 35 | IonBuffer buffer, |
| 36 | IonBuffer metadata_buffer, |
| 37 | size_t user_metadata_size); |
| 38 | |
| Corey Tabaka | cd52dd9 | 2017-04-07 18:03:57 -0700 | [diff] [blame] | 39 | static pdx::Status<std::shared_ptr<ProducerChannel>> Create( |
| 40 | BufferHubService* service, int channel_id, uint32_t width, |
| Hendrik Wagenaar | 108e84f | 2017-05-07 22:19:17 -0700 | [diff] [blame] | 41 | uint32_t height, uint32_t layer_count, uint32_t format, uint64_t usage, |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 42 | size_t user_metadata_size); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 43 | |
| 44 | ~ProducerChannel() override; |
| 45 | |
| 46 | bool HandleMessage(Message& message) override; |
| 47 | void HandleImpulse(Message& message) override; |
| 48 | |
| 49 | BufferInfo GetBufferInfo() const override; |
| 50 | |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 51 | BufferDescription<BorrowedHandle> GetBuffer(uint64_t buffer_state_bit); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 52 | |
| Corey Tabaka | cd52dd9 | 2017-04-07 18:03:57 -0700 | [diff] [blame] | 53 | pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message); |
| 54 | pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 55 | |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 56 | pdx::Status<LocalFence> OnConsumerAcquire(Message& message); |
| Corey Tabaka | cd52dd9 | 2017-04-07 18:03:57 -0700 | [diff] [blame] | 57 | pdx::Status<void> OnConsumerRelease(Message& message, |
| 58 | LocalFence release_fence); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 59 | |
| 60 | void OnConsumerIgnored(); |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 61 | void OnConsumerOrphaned(ConsumerChannel* channel); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 62 | |
| 63 | void AddConsumer(ConsumerChannel* channel); |
| 64 | void RemoveConsumer(ConsumerChannel* channel); |
| 65 | |
| Hendrik Wagenaar | 108e84f | 2017-05-07 22:19:17 -0700 | [diff] [blame] | 66 | bool CheckParameters(uint32_t width, uint32_t height, uint32_t layer_count, |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 67 | uint32_t format, uint64_t usage, |
| 68 | size_t user_metadata_size); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 69 | |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 70 | private: |
| 71 | std::vector<ConsumerChannel*> consumer_channels_; |
| 72 | // This counts the number of consumers left to process this buffer. If this is |
| 73 | // zero then the producer can re-acquire ownership. |
| 74 | int pending_consumers_; |
| 75 | |
| Hendrik Wagenaar | 4d3590f | 2017-05-06 22:36:04 -0700 | [diff] [blame] | 76 | IonBuffer buffer_; |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 77 | |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 78 | // IonBuffer that is shared between bufferhubd, producer, and consumers. |
| 79 | IonBuffer metadata_buffer_; |
| 80 | BufferHubDefs::MetadataHeader* metadata_header_ = nullptr; |
| 81 | std::atomic<uint64_t>* buffer_state_ = nullptr; |
| 82 | std::atomic<uint64_t>* fence_state_ = nullptr; |
| 83 | |
| 84 | // All active consumer bits. Valid bits are the lower 63 bits, while the |
| 85 | // highest bit is reserved for the producer and should not be set. |
| 86 | uint64_t active_consumer_bit_mask_{0ULL}; |
| 87 | // All orphaned consumer bits. Valid bits are the lower 63 bits, while the |
| 88 | // highest bit is reserved for the producer and should not be set. |
| 89 | uint64_t orphaned_consumer_bit_mask_{0ULL}; |
| 90 | |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 91 | bool producer_owns_; |
| 92 | LocalFence post_fence_; |
| 93 | LocalFence returned_fence_; |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 94 | size_t user_metadata_size_; // size of user requested buffer buffer size. |
| 95 | size_t metadata_buf_size_; // size of the ion buffer that holds metadata. |
| 96 | |
| 97 | pdx::LocalHandle acquire_fence_fd_; |
| 98 | pdx::LocalHandle release_fence_fd_; |
| 99 | pdx::LocalHandle dummy_fence_fd_; |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 100 | |
| Jiwen 'Steve' Cai | 0728fa9 | 2018-04-24 19:03:14 -0700 | [diff] [blame] | 101 | ProducerChannel(BufferHubService* service, int buffer_id, int channel_id, |
| 102 | IonBuffer buffer, IonBuffer metadata_buffer, |
| 103 | size_t user_metadata_size, int* error); |
| Corey Tabaka | cd52dd9 | 2017-04-07 18:03:57 -0700 | [diff] [blame] | 104 | ProducerChannel(BufferHubService* service, int channel, uint32_t width, |
| Hendrik Wagenaar | 108e84f | 2017-05-07 22:19:17 -0700 | [diff] [blame] | 105 | uint32_t height, uint32_t layer_count, uint32_t format, |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 106 | uint64_t usage, size_t user_metadata_size, int* error); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 107 | |
| Jiwen 'Steve' Cai | 0728fa9 | 2018-04-24 19:03:14 -0700 | [diff] [blame] | 108 | int InitializeBuffer(); |
| Corey Tabaka | 52ea25c | 2017-09-13 18:02:48 -0700 | [diff] [blame] | 109 | pdx::Status<BufferDescription<BorrowedHandle>> OnGetBuffer(Message& message); |
| 110 | pdx::Status<void> OnProducerPost(Message& message, LocalFence acquire_fence); |
| Corey Tabaka | cd52dd9 | 2017-04-07 18:03:57 -0700 | [diff] [blame] | 111 | pdx::Status<LocalFence> OnProducerGain(Message& message); |
| Jiwen 'Steve' Cai | 23c1a73 | 2018-03-12 12:16:47 -0700 | [diff] [blame] | 112 | pdx::Status<RemoteChannelHandle> OnProducerDetach(Message& message); |
| Alex Vakulenko | e4eec20 | 2017-01-27 14:41:04 -0800 | [diff] [blame] | 113 | |
| 114 | ProducerChannel(const ProducerChannel&) = delete; |
| 115 | void operator=(const ProducerChannel&) = delete; |
| 116 | }; |
| 117 | |
| 118 | } // namespace dvr |
| 119 | } // namespace android |
| 120 | |
| 121 | #endif // ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_ |