1 #ifndef ANDROID_DVR_BUFFER_HUB_BASE_H_
2 #define ANDROID_DVR_BUFFER_HUB_BASE_H_
3 
4 #include <vector>
5 
6 #include <private/dvr/bufferhub_rpc.h>
7 
8 namespace android {
9 namespace dvr {
10 
11 // Base class of two types of BufferHub clients: dvr::ProducerBuffer and
12 // dvr::ConsumerBuffer.
13 class BufferHubBase : public pdx::Client {
14  public:
15   using LocalHandle = pdx::LocalHandle;
16   using LocalChannelHandle = pdx::LocalChannelHandle;
17   template <typename T>
18   using Status = pdx::Status<T>;
19 
20   // Create a new consumer channel that is attached to the producer. Returns
21   // a file descriptor for the new channel or a negative error code.
22   Status<LocalChannelHandle> CreateConsumer();
23 
24   // Gets a blob buffer that was created with ProducerBuffer::CreateBlob.
25   // Locking and Unlocking is handled internally. There's no need to Unlock
26   // after calling this method.
27   int GetBlobReadWritePointer(size_t size, void** addr);
28 
29   // Returns a dup'd file descriptor for accessing the blob shared memory. The
30   // caller takes ownership of the file descriptor and must close it or pass on
31   // ownership. Some GPU API extensions can take file descriptors to bind shared
32   // memory gralloc buffers to GPU buffer objects.
GetBlobFd()33   LocalHandle GetBlobFd() const {
34     // Current GPU vendor puts the buffer allocation in one FD. If we change GPU
35     // vendors and this is the wrong fd, late-latching and EDS will very clearly
36     // stop working and we will need to correct this. The alternative is to use
37     // a GL context in the pose service to allocate this buffer or to use the
38     // ION API directly instead of gralloc.
39     return LocalHandle(dup(native_handle()->data[0]));
40   }
41 
42   using Client::event_fd;
43 
GetEventMask(int events)44   Status<int> GetEventMask(int events) {
45     if (auto* client_channel = GetChannel()) {
46       return client_channel->GetEventMask(events);
47     } else {
48       return pdx::ErrorStatus(EINVAL);
49     }
50   }
51 
GetEventSources()52   std::vector<pdx::ClientChannel::EventSource> GetEventSources() const {
53     if (auto* client_channel = GetChannel()) {
54       return client_channel->GetEventSources();
55     } else {
56       return {};
57     }
58   }
59 
native_handle()60   native_handle_t* native_handle() const {
61     return const_cast<native_handle_t*>(buffer_.handle());
62   }
63 
buffer()64   IonBuffer* buffer() { return &buffer_; }
buffer()65   const IonBuffer* buffer() const { return &buffer_; }
66 
67   // Gets ID of the buffer client. All BufferHub clients derived from the same
68   // buffer in bufferhubd share the same buffer id.
id()69   int id() const { return id_; }
70 
71   // Gets the channel id of the buffer client. Each BufferHub client has its
72   // system unique channel id.
cid()73   int cid() const { return cid_; }
74 
75   // Returns the buffer buffer state.
buffer_state()76   uint32_t buffer_state() {
77     return buffer_state_->load(std::memory_order_acquire);
78   };
79 
80   // Returns whether the buffer is already released by all current clients.
is_released()81   bool is_released() {
82     return (buffer_state() &
83             active_clients_bit_mask_->load(std::memory_order_acquire)) == 0;
84   }
85 
86   // A state mask which is unique to a buffer hub client among all its siblings
87   // sharing the same concrete graphic buffer.
client_state_mask()88   uint32_t client_state_mask() const { return client_state_mask_; }
89 
90   // The following methods return settings of the first buffer. Currently,
91   // it is only possible to create multi-buffer BufferHubBases with the same
92   // settings.
width()93   uint32_t width() const { return buffer_.width(); }
height()94   uint32_t height() const { return buffer_.height(); }
stride()95   uint32_t stride() const { return buffer_.stride(); }
format()96   uint32_t format() const { return buffer_.format(); }
usage()97   uint32_t usage() const { return buffer_.usage(); }
layer_count()98   uint32_t layer_count() const { return buffer_.layer_count(); }
99 
GetQueueIndex()100   uint64_t GetQueueIndex() const { return metadata_header_->queueIndex; }
SetQueueIndex(uint64_t index)101   void SetQueueIndex(uint64_t index) { metadata_header_->queueIndex = index; }
102 
103  protected:
104   explicit BufferHubBase(LocalChannelHandle channel);
105   explicit BufferHubBase(const std::string& endpoint_path);
106   virtual ~BufferHubBase();
107 
108   // Initialization helper.
109   int ImportBuffer();
110 
111   // Check invalid metadata operation. Returns 0 if requested metadata is valid.
112   int CheckMetadata(size_t user_metadata_size) const;
113 
114   // Send out the new fence by updating the shared fence (shared_release_fence
115   // for producer and shared_acquire_fence for consumer). Note that during this
116   // should only be used in LocalPost() or LocalRelease, and the shared fence
117   // shouldn't be poll'ed by the other end.
118   int UpdateSharedFence(const LocalHandle& new_fence,
119                         const LocalHandle& shared_fence);
120 
121   // Locks the area specified by (x, y, width, height) for a specific usage. If
122   // the usage is software then |addr| will be updated to point to the address
123   // of the buffer in virtual memory. The caller should only access/modify the
124   // pixels in the specified area. anything else is undefined behavior.
125   int Lock(int usage, int x, int y, int width, int height, void** addr);
126 
127   // Must be called after Lock() when the caller has finished changing the
128   // buffer.
129   int Unlock();
130 
131   // IonBuffer that is shared between bufferhubd, producer, and consumers.
132   size_t metadata_buf_size_{0};
133   size_t user_metadata_size_{0};
134   BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
135   void* user_metadata_ptr_ = nullptr;
136   std::atomic<uint32_t>* buffer_state_ = nullptr;
137   std::atomic<uint32_t>* fence_state_ = nullptr;
138   std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
139 
140   LocalHandle shared_acquire_fence_;
141   LocalHandle shared_release_fence_;
142 
143   // A local fence fd that holds the ownership of the fence fd on Post (for
144   // producer) and Release (for consumer).
145   LocalHandle pending_fence_fd_;
146 
147  private:
148   BufferHubBase(const BufferHubBase&) = delete;
149   void operator=(const BufferHubBase&) = delete;
150 
151   // Global id for the buffer that is consistent across processes. It is meant
152   // for logging and debugging purposes only and should not be used for lookup
153   // or any other functional purpose as a security precaution.
154   int id_;
155 
156   // Channel id.
157   int cid_;
158 
159   // Client bit mask which indicates the locations of this client object in the
160   // buffer_state_.
161   uint32_t client_state_mask_{0U};
162   IonBuffer buffer_;
163   IonBuffer metadata_buffer_;
164 };
165 
166 }  // namespace dvr
167 }  // namespace android
168 
169 #endif  // ANDROID_DVR_BUFFER_HUB_BASE_H_
170