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