1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <memory> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <unordered_map> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <hardware/gralloc.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 101db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabaka#include <private/dvr/bufferhub_rpc.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferHubService; 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ConsumerChannel; 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ProducerChannel; 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ConsumerQueueChannel; 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ProducerQueueChannel; 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferHubChannel : public pdx::Channel { 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko enum ChannelType { 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko kProducerType, 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko kConsumerType, 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko kProducerQueueType, 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko kConsumerQueueType, 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko }; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko enum : int { kDetachedId = -1 }; 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id, 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelType channel_type) 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : service_(service), 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_id_(buffer_id), 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_id_(channel_id), 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_type_(channel_type) {} 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual ~BufferHubChannel() {} 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual bool HandleMessage(pdx::Message& message) = 0; 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual void HandleImpulse(pdx::Message& message) = 0; 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Captures buffer info for use by BufferHubService::DumpState(). 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko struct BufferInfo { 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Common data field shared by BufferProducer and ProducerQueue. 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int id = -1; 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int type = -1; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t consumer_count = 0; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Data field for buffer producer. 51cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka uint32_t width = 0; 52cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka uint32_t height = 0; 53108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar uint32_t layer_count = 0; 54cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka uint32_t format = 0; 550057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai uint64_t usage = 0; 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string name; 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Data filed for producer queue. 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t capacity = 0; 600057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai UsagePolicy usage_policy{0, 0, 0, 0}; 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 62cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height, 63108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar uint32_t layer_count, uint32_t format, uint64_t usage, const std::string& name) 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : id(id), 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko type(kProducerType), 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko consumer_count(consumer_count), 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko width(width), 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko height(height), 69108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar layer_count(layer_count), 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko format(format), 710057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai usage(usage), 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko name(name) {} 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 741db8a5d7e3b0565b976e77859e28d77f6a451a2bCorey Tabaka BufferInfo(int id, size_t consumer_count, size_t capacity, 75cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka const UsagePolicy& usage_policy) 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : id(id), 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko type(kProducerQueueType), 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko consumer_count(consumer_count), 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko capacity(capacity), 80cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka usage_policy(usage_policy) {} 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferInfo() {} 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko }; 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns the buffer info for this buffer. 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual BufferInfo GetBufferInfo() const = 0; 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Signal the client fd that an ownership change occurred using POLLIN. 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void SignalAvailable(); 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Clear the ownership change event. 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void ClearAvailable(); 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Signal hangup event. 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Hangup(); 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubService* service() const { return service_; } 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelType channel_type() const { return channel_type_; } 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int buffer_id() const { return buffer_id_; } 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id() const { return channel_id_; } 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool IsDetached() const { return channel_id_ == kDetachedId; } 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Detach() { 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_type_ == kProducerType) 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_id_ = kDetachedId; 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Attach(int channel_id) { 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_type_ == kProducerType && channel_id_ == kDetachedId) 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_id_ = channel_id; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubService* service_; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Static id of the buffer for logging and informational purposes. This id 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // does not change for the life of the buffer. 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(eieio): Consider using an id allocator instead of the originating 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // channel id; channel ids wrap after 2^31 ids, but this is not a problem in 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // general because channel ids are not used for any lookup in this service. 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int buffer_id_; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // The channel id of the buffer. This may change for a persistent producer 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer if it is detached and re-attached to another channel. 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id_; 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelType channel_type_; 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubChannel(const BufferHubChannel&) = delete; 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const BufferHubChannel&) = delete; 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferHubService : public pdx::ServiceBase<BufferHubService> { 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubService(); 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ~BufferHubService() override; 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 138f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko pdx::Status<void> HandleMessage(pdx::Message& message) override; 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void HandleImpulse(pdx::Message& message) override; 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void OnChannelClose(pdx::Message& message, 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<pdx::Channel>& channel) override; 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool IsInitialized() const override; 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string DumpState(size_t max_length) override; 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool AddNamedBuffer(const std::string& name, 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<ProducerChannel>& buffer); 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<ProducerChannel> GetNamedBuffer(const std::string& name); 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool RemoveNamedBuffer(const ProducerChannel& buffer); 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unordered_map<std::string, std::shared_ptr<ProducerChannel>> 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko named_buffers_; 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1580057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width, 1590057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai uint32_t height, uint32_t format, 1604d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint64_t usage, size_t meta_size_bytes); 1614d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar pdx::Status<void> OnCreatePersistentBuffer(pdx::Message& message, 1624d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar const std::string& name, 1634d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar int user_id, int group_id, 1644d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t width, uint32_t height, 1654d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t format, uint64_t usage, 1664d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar size_t meta_size_bytes); 1670057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message, 1680057fddc71d1c3c3de8f9d0bd45a51bb293bfa3cJiwen 'Steve' Cai const std::string& name); 169cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka pdx::Status<QueueInfo> OnCreateProducerQueue(pdx::Message& message, 170cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka size_t meta_size_bytes, 171cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka const UsagePolicy& usage_policy); 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubService(const BufferHubService&) = delete; 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const BufferHubService&) = delete; 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_ 181