1#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
2#define ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
3
4#include "buffer_hub.h"
5
6#include <pdx/status.h>
7#include <private/dvr/bufferhub_rpc.h>
8
9namespace android {
10namespace dvr {
11
12class ProducerQueueChannel : public BufferHubChannel {
13 public:
14  static pdx::Status<std::shared_ptr<ProducerQueueChannel>> Create(
15      BufferHubService* service, int channel_id,
16      const ProducerQueueConfig& config, const UsagePolicy& usage_policy);
17  ~ProducerQueueChannel() override;
18
19  bool HandleMessage(pdx::Message& message) override;
20  void HandleImpulse(pdx::Message& message) override;
21
22  BufferInfo GetBufferInfo() const override;
23
24  // Handles client request to create a new consumer queue attached to current
25  // producer queue.
26  // Returns a handle for the service channel, as well as the size of the
27  // metadata associated with the queue.
28  pdx::Status<pdx::RemoteChannelHandle> OnCreateConsumerQueue(
29      pdx::Message& message, bool silent);
30
31  pdx::Status<QueueInfo> OnGetQueueInfo(pdx::Message& message);
32
33  // Allocate a new BufferHubProducer according to the input spec. Client may
34  // handle this as if a new producer is created through kOpCreateBuffer.
35  pdx::Status<std::vector<std::pair<pdx::RemoteChannelHandle, size_t>>>
36  OnProducerQueueAllocateBuffers(pdx::Message& message, uint32_t width,
37                                 uint32_t height, uint32_t layer_count,
38                                 uint32_t format, uint64_t usage,
39                                 size_t buffer_count);
40
41  // Detach a BufferHubProducer indicated by |slot|. Note that the buffer must
42  // be in Gain'ed state for the producer queue to detach.
43  pdx::Status<void> OnProducerQueueRemoveBuffer(pdx::Message& message,
44                                                size_t slot);
45
46  void AddConsumer(ConsumerQueueChannel* channel);
47  void RemoveConsumer(ConsumerQueueChannel* channel);
48
49 private:
50  ProducerQueueChannel(BufferHubService* service, int channel_id,
51                       const ProducerQueueConfig& config,
52                       const UsagePolicy& usage_policy, int* error);
53
54  // Allocate one single producer buffer by |OnProducerQueueAllocateBuffers|.
55  // Note that the newly created buffer's file handle will be pushed to client
56  // and our return type is a RemoteChannelHandle.
57  // Returns the remote channel handle and the slot number for the newly
58  // allocated buffer.
59  pdx::Status<std::pair<pdx::RemoteChannelHandle, size_t>> AllocateBuffer(
60      pdx::Message& message, uint32_t width, uint32_t height,
61      uint32_t layer_count, uint32_t format, uint64_t usage);
62
63  // The producer queue's configuration. Now we assume the configuration is
64  // immutable once the queue is created.
65  ProducerQueueConfig config_;
66
67  // A set of variables to control what |usage| bits can this ProducerQueue
68  // allocate.
69  UsagePolicy usage_policy_;
70
71  // Provides access to the |channel_id| of all consumer channels associated
72  // with this producer.
73  std::vector<ConsumerQueueChannel*> consumer_channels_;
74
75  // Tracks how many buffers have this queue allocated.
76  size_t capacity_;
77
78  // Tracks of all buffer producer allocated through this buffer queue. Once
79  // a buffer get allocated, it will take a logical slot in the |buffers_| array
80  // and the slot number will stay unchanged during the entire life cycle of the
81  // queue.
82  std::weak_ptr<ProducerChannel> buffers_[BufferHubRPC::kMaxQueueCapacity];
83
84  ProducerQueueChannel(const ProducerQueueChannel&) = delete;
85  void operator=(const ProducerQueueChannel&) = delete;
86};
87
88}  // namespace dvr
89}  // namespace android
90
91#endif  // ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
92