• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
2 #define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
3 
4 #include <memory>
5 #include <string>
6 #include <unordered_map>
7 
8 #include <hardware/gralloc.h>
9 #include <pdx/service.h>
10 #include <private/dvr/bufferhub_rpc.h>
11 
12 namespace android {
13 namespace dvr {
14 
15 class BufferHubService;
16 class ConsumerChannel;
17 class ProducerChannel;
18 class ConsumerQueueChannel;
19 class ProducerQueueChannel;
20 
21 class BufferHubChannel : public pdx::Channel {
22  public:
23   enum ChannelType {
24     kProducerType,
25     kConsumerType,
26     kProducerQueueType,
27     kConsumerQueueType,
28   };
29 
30   enum : int { kDetachedId = -1 };
31 
BufferHubChannel(BufferHubService * service,int buffer_id,int channel_id,ChannelType channel_type)32   BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id,
33                    ChannelType channel_type)
34       : service_(service),
35         buffer_id_(buffer_id),
36         channel_id_(channel_id),
37         channel_type_(channel_type) {}
~BufferHubChannel()38   virtual ~BufferHubChannel() {}
39 
40   virtual bool HandleMessage(pdx::Message& message) = 0;
41   virtual void HandleImpulse(pdx::Message& message) = 0;
42 
43   // Captures buffer info for use by BufferHubService::DumpState().
44   struct BufferInfo {
45     // Common data field shared by BufferProducer and ProducerQueue.
46     int id = -1;
47     int type = -1;
48     size_t consumer_count = 0;
49 
50     // Data field for buffer producer.
51     uint32_t width = 0;
52     uint32_t height = 0;
53     uint32_t layer_count = 0;
54     uint32_t format = 0;
55     uint64_t usage = 0;
56     size_t pending_count = 0;
57     uint64_t state = 0;
58     uint64_t signaled_mask = 0;
59     uint64_t index = 0;
60     std::string name;
61 
62     // Data filed for producer queue.
63     size_t capacity = 0;
64     UsagePolicy usage_policy{0, 0, 0, 0};
65 
BufferInfoBufferInfo66     BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height,
67                uint32_t layer_count, uint32_t format, uint64_t usage,
68                size_t pending_count, uint64_t state, uint64_t signaled_mask,
69                uint64_t index, const std::string& name)
70         : id(id),
71           type(kProducerType),
72           consumer_count(consumer_count),
73           width(width),
74           height(height),
75           layer_count(layer_count),
76           format(format),
77           usage(usage),
78           pending_count(pending_count),
79           state(state),
80           signaled_mask(signaled_mask),
81           index(index),
82           name(name) {}
83 
BufferInfoBufferInfo84     BufferInfo(int id, size_t consumer_count, size_t capacity,
85                const UsagePolicy& usage_policy)
86         : id(id),
87           type(kProducerQueueType),
88           consumer_count(consumer_count),
89           capacity(capacity),
90           usage_policy(usage_policy) {}
91 
BufferInfoBufferInfo92     BufferInfo() {}
93   };
94 
95   // Returns the buffer info for this buffer.
96   virtual BufferInfo GetBufferInfo() const = 0;
97 
98   // Signal the client fd that an ownership change occurred using POLLIN.
99   void SignalAvailable();
100 
101   // Clear the ownership change event.
102   void ClearAvailable();
103 
104   // Signal hangup event.
105   void Hangup();
106 
service()107   BufferHubService* service() const { return service_; }
channel_type()108   ChannelType channel_type() const { return channel_type_; }
buffer_id()109   int buffer_id() const { return buffer_id_; }
110 
channel_id()111   int channel_id() const { return channel_id_; }
IsDetached()112   bool IsDetached() const { return channel_id_ == kDetachedId; }
113 
signaled()114   bool signaled() const { return signaled_; }
115 
Detach()116   void Detach() {
117     if (channel_type_ == kProducerType)
118       channel_id_ = kDetachedId;
119   }
Attach(int channel_id)120   void Attach(int channel_id) {
121     if (channel_type_ == kProducerType && channel_id_ == kDetachedId)
122       channel_id_ = channel_id;
123   }
124 
125  private:
126   BufferHubService* service_;
127 
128   // Static id of the buffer for logging and informational purposes. This id
129   // does not change for the life of the buffer.
130   // TODO(eieio): Consider using an id allocator instead of the originating
131   // channel id; channel ids wrap after 2^31 ids, but this is not a problem in
132   // general because channel ids are not used for any lookup in this service.
133   int buffer_id_;
134 
135   // The channel id of the buffer. This may change for a persistent producer
136   // buffer if it is detached and re-attached to another channel.
137   int channel_id_;
138 
139   bool signaled_;
140 
141   ChannelType channel_type_;
142 
143   BufferHubChannel(const BufferHubChannel&) = delete;
144   void operator=(const BufferHubChannel&) = delete;
145 };
146 
147 class BufferHubService : public pdx::ServiceBase<BufferHubService> {
148  public:
149   BufferHubService();
150   ~BufferHubService() override;
151 
152   pdx::Status<void> HandleMessage(pdx::Message& message) override;
153   void HandleImpulse(pdx::Message& message) override;
154 
155   void OnChannelClose(pdx::Message& message,
156                       const std::shared_ptr<pdx::Channel>& channel) override;
157 
158   bool IsInitialized() const override;
159   std::string DumpState(size_t max_length) override;
160 
161   bool AddNamedBuffer(const std::string& name,
162                       const std::shared_ptr<ProducerChannel>& buffer);
163   std::shared_ptr<ProducerChannel> GetNamedBuffer(const std::string& name);
164   bool RemoveNamedBuffer(const ProducerChannel& buffer);
165 
166  private:
167   friend BASE;
168 
169   std::unordered_map<std::string, std::shared_ptr<ProducerChannel>>
170       named_buffers_;
171 
172   pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width,
173                                    uint32_t height, uint32_t format,
174                                    uint64_t usage, size_t meta_size_bytes);
175   pdx::Status<void> OnCreatePersistentBuffer(pdx::Message& message,
176                                              const std::string& name,
177                                              int user_id, int group_id,
178                                              uint32_t width, uint32_t height,
179                                              uint32_t format, uint64_t usage,
180                                              size_t meta_size_bytes);
181   pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message,
182                                           const std::string& name);
183   pdx::Status<QueueInfo> OnCreateProducerQueue(
184       pdx::Message& message, const ProducerQueueConfig& producer_config,
185       const UsagePolicy& usage_policy);
186 
187   BufferHubService(const BufferHubService&) = delete;
188   void operator=(const BufferHubService&) = delete;
189 };
190 
191 }  // namespace dvr
192 }  // namespace android
193 
194 #endif  // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
195