OSDN Git Service

Merge "omx: add constrained AVC profile constants" into oc-mr1-dev
[android-x86/frameworks-native.git] / libs / vr / libbufferhubqueue / include / private / dvr / buffer_hub_queue_client.h
1 #ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
2 #define ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
3
4 #include <gui/BufferQueueDefs.h>
5
6 #include <pdx/client.h>
7 #include <pdx/status.h>
8 #include <private/dvr/bufferhub_rpc.h>
9 #include <private/dvr/buffer_hub_client.h>
10 #include <private/dvr/epoll_file_descriptor.h>
11 #include <private/dvr/ring_buffer.h>
12
13 #include <memory>
14 #include <vector>
15
16 namespace android {
17 namespace dvr {
18
19 class ConsumerQueue;
20
21 // |BufferHubQueue| manages a queue of |BufferHubBuffer|s. Buffers are
22 // automatically re-requeued when released by the remote side.
23 class BufferHubQueue : public pdx::Client {
24  public:
25   using BufferAvailableCallback = std::function<void()>;
26   using BufferRemovedCallback =
27       std::function<void(const std::shared_ptr<BufferHubBuffer>&)>;
28
29   virtual ~BufferHubQueue() {}
30
31   // Creates a new consumer queue that is attached to the producer. Returns
32   // a new consumer queue client or nullptr on failure.
33   std::unique_ptr<ConsumerQueue> CreateConsumerQueue();
34
35   // Creates a new consumer queue that is attached to the producer. This queue
36   // sets each of its imported consumer buffers to the ignored state to avoid
37   // participation in lifecycle events.
38   std::unique_ptr<ConsumerQueue> CreateSilentConsumerQueue();
39
40   // Returns whether the buffer queue is in async mode.
41   bool is_async() const { return is_async_; }
42
43   // Returns the default buffer width of this buffer queue.
44   uint32_t default_width() const { return default_width_; }
45
46   // Returns the default buffer height of this buffer queue.
47   uint32_t default_height() const { return default_height_; }
48
49   // Returns the default buffer format of this buffer queue.
50   uint32_t default_format() const { return default_format_; }
51
52   // Creates a new consumer in handle form for immediate transport over RPC.
53   pdx::Status<pdx::LocalChannelHandle> CreateConsumerQueueHandle();
54
55   // Returns the number of buffers avaiable for dequeue.
56   size_t count() const { return available_buffers_.GetSize(); }
57
58   // Returns the total number of buffers that the queue is tracking.
59   size_t capacity() const { return capacity_; }
60
61   // Returns the size of metadata structure associated with this queue.
62   size_t metadata_size() const { return meta_size_; }
63
64   // Returns whether the buffer queue is full.
65   bool is_full() const { return available_buffers_.IsFull(); }
66
67   explicit operator bool() const { return epoll_fd_.IsValid(); }
68
69   std::shared_ptr<BufferHubBuffer> GetBuffer(size_t slot) const {
70     return buffers_[slot];
71   }
72
73   pdx::Status<int> GetEventMask(int events) {
74     if (auto* client_channel = GetChannel()) {
75       return client_channel->GetEventMask(events);
76     } else {
77       return pdx::ErrorStatus(EINVAL);
78     }
79   }
80
81   // Returns an fd that signals pending queue events using
82   // EPOLLIN/POLLIN/readible. Either HandleQueueEvents or WaitForBuffers may be
83   // called to handle pending queue events.
84   int queue_fd() const { return epoll_fd_.Get(); }
85
86   // Handles any pending events, returning available buffers to the queue and
87   // reaping disconnected buffers. Returns true if successful, false if an error
88   // occurred.
89   bool HandleQueueEvents() { return WaitForBuffers(0); }
90
91   // Set buffer event callbacks, which are std::function wrappers. The caller is
92   // responsible for ensuring the validity of these callbacks' callable targets.
93   void SetBufferAvailableCallback(BufferAvailableCallback callback);
94   void SetBufferRemovedCallback(BufferRemovedCallback callback);
95
96   // The queue tracks at most this many buffers.
97   static constexpr size_t kMaxQueueCapacity =
98       android::BufferQueueDefs::NUM_BUFFER_SLOTS;
99
100   static constexpr int kNoTimeOut = -1;
101
102   int id() const { return id_; }
103   bool hung_up() const { return hung_up_; }
104
105  protected:
106   BufferHubQueue(pdx::LocalChannelHandle channel);
107   BufferHubQueue(const std::string& endpoint_path);
108
109   // Imports the queue parameters by querying BufferHub for the parameters for
110   // this channel.
111   pdx::Status<void> ImportQueue();
112
113   // Sets up the queue with the given parameters.
114   void SetupQueue(const QueueInfo& queue_info);
115
116   // Register a buffer for management by the queue. Used by subclasses to add a
117   // buffer to internal bookkeeping.
118   pdx::Status<void> AddBuffer(const std::shared_ptr<BufferHubBuffer>& buffer,
119                               size_t slot);
120
121   // Called by ProducerQueue::RemoveBuffer and ConsumerQueue::RemoveBuffer only
122   // to deregister a buffer for epoll and internal bookkeeping.
123   virtual pdx::Status<void> RemoveBuffer(size_t slot);
124
125   // Free all buffers that belongs to this queue. Can only be called from
126   // producer side.
127   virtual pdx::Status<void> FreeAllBuffers();
128
129   // Dequeue a buffer from the free queue, blocking until one is available. The
130   // timeout argument specifies the number of milliseconds that |Dequeue()| will
131   // block. Specifying a timeout of -1 causes Dequeue() to block indefinitely,
132   // while specifying a timeout equal to zero cause Dequeue() to return
133   // immediately, even if no buffers are available.
134   pdx::Status<std::shared_ptr<BufferHubBuffer>> Dequeue(
135       int timeout, size_t* slot, void* meta, pdx::LocalHandle* fence);
136
137   // Waits for buffers to become available and adds them to the available queue.
138   bool WaitForBuffers(int timeout);
139
140   pdx::Status<void> HandleBufferEvent(size_t slot, int event_fd,
141                                       int poll_events);
142   pdx::Status<void> HandleQueueEvent(int poll_events);
143
144   // Entry in the ring buffer of available buffers that stores related
145   // per-buffer data.
146   struct Entry {
147     Entry() : slot(0) {}
148     Entry(const std::shared_ptr<BufferHubBuffer>& buffer, size_t slot)
149         : buffer(buffer), slot(slot) {}
150     Entry(const std::shared_ptr<BufferHubBuffer>& buffer,
151           std::unique_ptr<uint8_t[]> metadata, pdx::LocalHandle fence,
152           size_t slot)
153         : buffer(buffer),
154           metadata(std::move(metadata)),
155           fence(std::move(fence)),
156           slot(slot) {}
157     Entry(Entry&&) = default;
158     Entry& operator=(Entry&&) = default;
159
160     std::shared_ptr<BufferHubBuffer> buffer;
161     std::unique_ptr<uint8_t[]> metadata;
162     pdx::LocalHandle fence;
163     size_t slot;
164   };
165
166   // Enqueues a buffer to the available list (Gained for producer or Acquireed
167   // for consumer).
168   pdx::Status<void> Enqueue(Entry entry);
169
170   virtual pdx::Status<Entry> OnBufferReady(
171       const std::shared_ptr<BufferHubBuffer>& buf, size_t slot) = 0;
172
173   // Called when a buffer is allocated remotely.
174   virtual pdx::Status<void> OnBufferAllocated() { return {}; }
175
176   // Size of the metadata that buffers in this queue cary.
177   size_t meta_size_{0};
178
179  private:
180   void Initialize();
181
182   // Special epoll data field indicating that the epoll event refers to the
183   // queue.
184   static constexpr int64_t kEpollQueueEventIndex = -1;
185
186   static constexpr size_t kMaxEvents = 128;
187
188   // The u64 data field of an epoll event is interpreted as int64_t:
189   // When |index| >= 0 and |index| < kMaxQueueCapacity it refers to a specific
190   // element of |buffers_| as a direct index;
191   static bool is_buffer_event_index(int64_t index) {
192     return index >= 0 &&
193            index < static_cast<int64_t>(BufferHubQueue::kMaxQueueCapacity);
194   }
195
196   // When |index| == kEpollQueueEventIndex it refers to the queue itself.
197   static bool is_queue_event_index(int64_t index) {
198     return index == BufferHubQueue::kEpollQueueEventIndex;
199   }
200
201   // Whether the buffer queue is operating in Async mode.
202   // From GVR's perspective of view, this means a buffer can be acquired
203   // asynchronously by the compositor.
204   // From Android Surface's perspective of view, this is equivalent to
205   // IGraphicBufferProducer's async mode. When in async mode, a producer
206   // will never block even if consumer is running slow.
207   bool is_async_{false};
208
209   // Default buffer width that is set during ProducerQueue's creation.
210   size_t default_width_{1};
211
212   // Default buffer height that is set during ProducerQueue's creation.
213   size_t default_height_{1};
214
215   // Default buffer format that is set during ProducerQueue's creation.
216   int32_t default_format_{1};  // PIXEL_FORMAT_RGBA_8888
217
218   // Tracks the buffers belonging to this queue. Buffers are stored according to
219   // "slot" in this vector. Each slot is a logical id of the buffer within this
220   // queue regardless of its queue position or presence in the ring buffer.
221   std::vector<std::shared_ptr<BufferHubBuffer>> buffers_{kMaxQueueCapacity};
222
223   // Buffers and related data that are available for dequeue.
224   RingBuffer<Entry> available_buffers_{kMaxQueueCapacity};
225
226   // Keeps track with how many buffers have been added into the queue.
227   size_t capacity_{0};
228
229   // Epoll fd used to manage buffer events.
230   EpollFileDescriptor epoll_fd_;
231
232   // Flag indicating that the other side hung up. For ProducerQueues this
233   // triggers when BufferHub dies or explicitly closes the queue channel. For
234   // ConsumerQueues this can either mean the same or that the ProducerQueue on
235   // the other end hung up.
236   bool hung_up_{false};
237
238   // Global id for the queue that is consistent across processes.
239   int id_{-1};
240
241   // Buffer event callbacks
242   BufferAvailableCallback on_buffer_available_;
243   BufferRemovedCallback on_buffer_removed_;
244
245   BufferHubQueue(const BufferHubQueue&) = delete;
246   void operator=(BufferHubQueue&) = delete;
247 };
248
249 class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> {
250  public:
251   // Usage bits in |usage_set_mask| will be automatically masked on. Usage bits
252   // in |usage_clear_mask| will be automatically masked off. Note that
253   // |usage_set_mask| and |usage_clear_mask| may conflict with each other, but
254   // |usage_set_mask| takes precedence over |usage_clear_mask|. All buffer
255   // allocation through this producer queue shall not have any of the usage bits
256   // in |usage_deny_set_mask| set. Allocation calls violating this will be
257   // rejected. All buffer allocation through this producer queue must have all
258   // the usage bits in |usage_deny_clear_mask| set. Allocation calls violating
259   // this will be rejected. Note that |usage_deny_set_mask| and
260   // |usage_deny_clear_mask| shall not conflict with each other. Such
261   // configuration will be treated as invalid input on creation.
262   static std::unique_ptr<ProducerQueue> Create(
263       const ProducerQueueConfig& config, const UsagePolicy& usage) {
264     return BASE::Create(config, usage);
265   }
266
267   // Import a ProducerQueue from a channel handle.
268   static std::unique_ptr<ProducerQueue> Import(pdx::LocalChannelHandle handle) {
269     return BASE::Create(std::move(handle));
270   }
271
272   // Get a buffer producer. Note that the method doesn't check whether the
273   // buffer slot has a valid buffer that has been allocated already. When no
274   // buffer has been imported before it returns nullptr; otherwise it returns
275   // a shared pointer to a BufferProducer.
276   std::shared_ptr<BufferProducer> GetBuffer(size_t slot) const {
277     return std::static_pointer_cast<BufferProducer>(
278         BufferHubQueue::GetBuffer(slot));
279   }
280
281   // Batch allocate buffers. Once allocated, producer buffers are automatically
282   // enqueue'd into the ProducerQueue and available to use (i.e. in GAINED
283   // state). Upon success, returns a list of slots for each buffer allocated.
284   pdx::Status<std::vector<size_t>> AllocateBuffers(
285       uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
286       uint64_t usage, size_t buffer_count);
287
288   // Allocate producer buffer to populate the queue. Once allocated, a producer
289   // buffer is automatically enqueue'd into the ProducerQueue and available to
290   // use (i.e. in GAINED state). Upon success, returns the slot number for the
291   // buffer allocated.
292   pdx::Status<size_t> AllocateBuffer(uint32_t width, uint32_t height,
293                                      uint32_t layer_count, uint32_t format,
294                                      uint64_t usage);
295
296   // Add a producer buffer to populate the queue. Once added, a producer buffer
297   // is available to use (i.e. in GAINED state).
298   pdx::Status<void> AddBuffer(const std::shared_ptr<BufferProducer>& buffer,
299                               size_t slot);
300
301   // Remove producer buffer from the queue.
302   pdx::Status<void> RemoveBuffer(size_t slot) override;
303
304   // Free all buffers on this producer queue.
305   pdx::Status<void> FreeAllBuffers() override {
306     return BufferHubQueue::FreeAllBuffers();
307   }
308
309   // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode,
310   // and caller should call Post() once it's done writing to release the buffer
311   // to the consumer side.
312   pdx::Status<std::shared_ptr<BufferProducer>> Dequeue(
313       int timeout, size_t* slot, pdx::LocalHandle* release_fence);
314
315   // Enqueues a producer buffer in the queue.
316   pdx::Status<void> Enqueue(const std::shared_ptr<BufferProducer>& buffer,
317                             size_t slot) {
318     return BufferHubQueue::Enqueue({buffer, slot});
319   }
320
321  private:
322   friend BASE;
323
324   // Constructors are automatically exposed through ProducerQueue::Create(...)
325   // static template methods inherited from ClientBase, which take the same
326   // arguments as the constructors.
327   explicit ProducerQueue(pdx::LocalChannelHandle handle);
328   ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage);
329
330   pdx::Status<Entry> OnBufferReady(
331       const std::shared_ptr<BufferHubBuffer>& buffer, size_t slot) override;
332 };
333
334 class ConsumerQueue : public BufferHubQueue {
335  public:
336   // Get a buffer consumer. Note that the method doesn't check whether the
337   // buffer slot has a valid buffer that has been imported already. When no
338   // buffer has been imported before it returns nullptr; otherwise returns a
339   // shared pointer to a BufferConsumer.
340   std::shared_ptr<BufferConsumer> GetBuffer(size_t slot) const {
341     return std::static_pointer_cast<BufferConsumer>(
342         BufferHubQueue::GetBuffer(slot));
343   }
344
345   // Import a ConsumerQueue from a channel handle. |ignore_on_import| controls
346   // whether or not buffers are set to be ignored when imported. This may be
347   // used to avoid participation in the buffer lifecycle by a consumer queue
348   // that is only used to spawn other consumer queues, such as in an
349   // intermediate service.
350   static std::unique_ptr<ConsumerQueue> Import(pdx::LocalChannelHandle handle,
351                                                bool ignore_on_import = false) {
352     return std::unique_ptr<ConsumerQueue>(
353         new ConsumerQueue(std::move(handle), ignore_on_import));
354   }
355
356   // Import newly created buffers from the service side.
357   // Returns number of buffers successfully imported or an error.
358   pdx::Status<size_t> ImportBuffers();
359
360   // Dequeue a consumer buffer to read. The returned buffer in |Acquired|'ed
361   // mode, and caller should call Releasse() once it's done writing to release
362   // the buffer to the producer side. |meta| is passed along from BufferHub,
363   // The user of BufferProducer is responsible with making sure that the
364   // Dequeue() is done with the corect metadata type and size with those used
365   // when the buffer is orignally created.
366   template <typename Meta>
367   pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
368       int timeout, size_t* slot, Meta* meta, pdx::LocalHandle* acquire_fence) {
369     return Dequeue(timeout, slot, meta, sizeof(*meta), acquire_fence);
370   }
371   pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
372       int timeout, size_t* slot, pdx::LocalHandle* acquire_fence) {
373     return Dequeue(timeout, slot, nullptr, 0, acquire_fence);
374   }
375
376   pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
377       int timeout, size_t* slot, void* meta, size_t meta_size,
378       pdx::LocalHandle* acquire_fence);
379
380  private:
381   friend BufferHubQueue;
382
383   ConsumerQueue(pdx::LocalChannelHandle handle, bool ignore_on_import = false);
384
385   // Add a consumer buffer to populate the queue. Once added, a consumer buffer
386   // is NOT available to use until the producer side |Post| it. |WaitForBuffers|
387   // will catch the |Post| and |Acquire| the buffer to make it available for
388   // consumer.
389   pdx::Status<void> AddBuffer(const std::shared_ptr<BufferConsumer>& buffer,
390                               size_t slot);
391
392   pdx::Status<Entry> OnBufferReady(
393       const std::shared_ptr<BufferHubBuffer>& buffer, size_t slot) override;
394
395   pdx::Status<void> OnBufferAllocated() override;
396
397   // Flag indicating that imported (consumer) buffers should be ignored when
398   // imported to avoid participating in the buffer ownership flow.
399   bool ignore_on_import_;
400 };
401
402 }  // namespace dvr
403 }  // namespace android
404
405 #endif  // ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_