blob: c1cc7f34f8ddd06a340fdede496fc4c90bfbf53e [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#ifndef ANDROID_DVR_BUFFER_HUB_CLIENT_H_
2#define ANDROID_DVR_BUFFER_HUB_CLIENT_H_
3
4#include <hardware/gralloc.h>
5#include <pdx/channel_handle.h>
6#include <pdx/client.h>
7#include <pdx/file_handle.h>
8#include <pdx/status.h>
9
10#include <vector>
11
12#include <private/dvr/ion_buffer.h>
13
Corey Tabaka52ea25c2017-09-13 18:02:48 -070014#include "bufferhub_rpc.h"
15
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080016namespace android {
17namespace dvr {
18
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070019class BufferHubClient : public pdx::Client {
20 public:
21 using LocalChannelHandle = pdx::LocalChannelHandle;
22
23 BufferHubClient();
24 explicit BufferHubClient(LocalChannelHandle channel_handle);
25
26 bool IsValid() const;
27 LocalChannelHandle TakeChannelHandle();
28
29 using pdx::Client::Close;
30 using pdx::Client::InvokeRemoteMethod;
31 using pdx::Client::IsConnected;
32};
33
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080034class BufferHubBuffer : public pdx::Client {
35 public:
36 using LocalHandle = pdx::LocalHandle;
37 using LocalChannelHandle = pdx::LocalChannelHandle;
38 template <typename T>
39 using Status = pdx::Status<T>;
40
41 // Create a new consumer channel that is attached to the producer. Returns
42 // a file descriptor for the new channel or a negative error code.
43 Status<LocalChannelHandle> CreateConsumer();
44
45 // Polls the fd for |timeout_ms| milliseconds (-1 for infinity).
46 int Poll(int timeout_ms);
47
48 // Locks the area specified by (x, y, width, height) for a specific usage. If
49 // the usage is software then |addr| will be updated to point to the address
50 // of the buffer in virtual memory. The caller should only access/modify the
51 // pixels in the specified area. anything else is undefined behavior.
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -070052 int Lock(int usage, int x, int y, int width, int height, void** addr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080053
54 // Must be called after Lock() when the caller has finished changing the
55 // buffer.
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -070056 int Unlock();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057
58 // Gets a blob buffer that was created with BufferProducer::CreateBlob.
59 // Locking and Unlocking is handled internally. There's no need to Unlock
60 // after calling this method.
61 int GetBlobReadWritePointer(size_t size, void** addr);
62
63 // Gets a blob buffer that was created with BufferProducer::CreateBlob.
64 // Locking and Unlocking is handled internally. There's no need to Unlock
65 // after calling this method.
66 int GetBlobReadOnlyPointer(size_t size, void** addr);
67
68 // Returns a dup'd file descriptor for accessing the blob shared memory. The
69 // caller takes ownership of the file descriptor and must close it or pass on
70 // ownership. Some GPU API extensions can take file descriptors to bind shared
71 // memory gralloc buffers to GPU buffer objects.
72 LocalHandle GetBlobFd() const {
73 // Current GPU vendor puts the buffer allocation in one FD. If we change GPU
74 // vendors and this is the wrong fd, late-latching and EDS will very clearly
75 // stop working and we will need to correct this. The alternative is to use
76 // a GL context in the pose service to allocate this buffer or to use the
77 // ION API directly instead of gralloc.
78 return LocalHandle(dup(native_handle()->data[0]));
79 }
80
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -070081 // Get up to |max_fds_count| file descriptors for accessing the blob shared
82 // memory. |fds_count| will contain the actual number of file descriptors.
83 void GetBlobFds(int* fds, size_t* fds_count, size_t max_fds_count) const;
84
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080085 using Client::event_fd;
Corey Tabaka3079cb72017-01-19 15:07:26 -080086
87 Status<int> GetEventMask(int events) {
88 if (auto* client_channel = GetChannel()) {
89 return client_channel->GetEventMask(events);
90 } else {
91 return pdx::ErrorStatus(EINVAL);
92 }
93 }
94
Corey Tabaka52ea25c2017-09-13 18:02:48 -070095 std::vector<pdx::ClientChannel::EventSource> GetEventSources() const {
96 if (auto* client_channel = GetChannel()) {
97 return client_channel->GetEventSources();
98 } else {
99 return {};
100 }
101 }
102
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800103 native_handle_t* native_handle() const {
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700104 return const_cast<native_handle_t*>(buffer_.handle());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800105 }
106
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700107 IonBuffer* buffer() { return &buffer_; }
108 const IonBuffer* buffer() const { return &buffer_; }
Corey Tabaka2655e1c2017-04-04 11:07:05 -0700109
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800110 int id() const { return id_; }
111
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700112 // Returns the buffer buffer state.
113 uint64_t buffer_state() { return buffer_state_->load(); };
114
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700115 // A state mask which is unique to a buffer hub client among all its siblings
116 // sharing the same concrete graphic buffer.
117 uint64_t buffer_state_bit() const { return buffer_state_bit_; }
118
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800119 // The following methods return settings of the first buffer. Currently,
120 // it is only possible to create multi-buffer BufferHubBuffers with the same
121 // settings.
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700122 uint32_t width() const { return buffer_.width(); }
123 uint32_t height() const { return buffer_.height(); }
124 uint32_t stride() const { return buffer_.stride(); }
125 uint32_t format() const { return buffer_.format(); }
126 uint32_t usage() const { return buffer_.usage(); }
127 uint32_t layer_count() const { return buffer_.layer_count(); }
Jiwen 'Steve' Cai044963e2017-05-01 22:43:21 -0700128
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700129 uint64_t GetQueueIndex() const { return metadata_header_->queue_index; }
130 void SetQueueIndex(uint64_t index) { metadata_header_->queue_index = index; }
131
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800132 protected:
133 explicit BufferHubBuffer(LocalChannelHandle channel);
134 explicit BufferHubBuffer(const std::string& endpoint_path);
135 virtual ~BufferHubBuffer();
136
137 // Initialization helper.
138 int ImportBuffer();
139
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700140 // Check invalid metadata operation. Returns 0 if requested metadata is valid.
141 int CheckMetadata(size_t user_metadata_size) const;
142
143 // Send out the new fence by updating the shared fence (shared_release_fence
144 // for producer and shared_acquire_fence for consumer). Note that during this
145 // should only be used in LocalPost() or LocalRelease, and the shared fence
146 // shouldn't be poll'ed by the other end.
147 int UpdateSharedFence(const LocalHandle& new_fence,
148 const LocalHandle& shared_fence);
149
150 // IonBuffer that is shared between bufferhubd, producer, and consumers.
151 size_t metadata_buf_size_{0};
152 size_t user_metadata_size_{0};
153 BufferHubDefs::MetadataHeader* metadata_header_{nullptr};
154 void* user_metadata_ptr_{nullptr};
155 std::atomic<uint64_t>* buffer_state_{nullptr};
156 std::atomic<uint64_t>* fence_state_{nullptr};
157
158 LocalHandle shared_acquire_fence_;
159 LocalHandle shared_release_fence_;
160
161 // A local fence fd that holds the ownership of the fence fd on Post (for
162 // producer) and Release (for consumer).
163 LocalHandle pending_fence_fd_;
164
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800165 private:
166 BufferHubBuffer(const BufferHubBuffer&) = delete;
167 void operator=(const BufferHubBuffer&) = delete;
168
169 // Global id for the buffer that is consistent across processes. It is meant
170 // for logging and debugging purposes only and should not be used for lookup
171 // or any other functional purpose as a security precaution.
172 int id_;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700173 uint64_t buffer_state_bit_{0ULL};
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700174 IonBuffer buffer_;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700175 IonBuffer metadata_buffer_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800176};
177
178// This represents a writable buffer. Calling Post notifies all clients and
179// makes the buffer read-only. Call Gain to acquire write access. A buffer
180// may have many consumers.
181//
182// The user of BufferProducer is responsible with making sure that the Post() is
183// done with the correct metadata type and size. The user is also responsible
184// for making sure that remote ends (BufferConsumers) are also using the correct
185// metadata when acquiring the buffer. The API guarantees that a Post() with a
186// metadata of wrong size will fail. However, it currently does not do any
187// type checking.
188// The API also assumes that metadata is a serializable type (plain old data).
189class BufferProducer : public pdx::ClientBase<BufferProducer, BufferHubBuffer> {
190 public:
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800191 // Imports a bufferhub producer channel, assuming ownership of its handle.
192 static std::unique_ptr<BufferProducer> Import(LocalChannelHandle channel);
193 static std::unique_ptr<BufferProducer> Import(
194 Status<LocalChannelHandle> status);
195
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700196 // Asynchronously posts a buffer. The fence and metadata are passed to
197 // consumer via shared fd and shared memory.
198 int PostAsync(const DvrNativeBufferMetadata* meta,
199 const LocalHandle& ready_fence);
200
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800201 // Post this buffer, passing |ready_fence| to the consumers. The bytes in
202 // |meta| are passed unaltered to the consumers. The producer must not modify
203 // the buffer until it is re-gained.
204 // This returns zero or a negative unix error code.
205 int Post(const LocalHandle& ready_fence, const void* meta,
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700206 size_t user_metadata_size);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800207
208 template <typename Meta,
209 typename = typename std::enable_if<std::is_void<Meta>::value>::type>
210 int Post(const LocalHandle& ready_fence) {
211 return Post(ready_fence, nullptr, 0);
212 }
Corey Tabaka2655e1c2017-04-04 11:07:05 -0700213 template <typename Meta, typename = typename std::enable_if<
214 !std::is_void<Meta>::value>::type>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800215 int Post(const LocalHandle& ready_fence, const Meta& meta) {
216 return Post(ready_fence, &meta, sizeof(meta));
217 }
218
219 // Attempt to re-gain the buffer for writing. If |release_fence| is valid, it
220 // must be waited on before using the buffer. If it is not valid then the
221 // buffer is free for immediate use. This call will only succeed if the buffer
222 // is in the released state.
223 // This returns zero or a negative unix error code.
224 int Gain(LocalHandle* release_fence);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700225 int GainAsync();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800226
227 // Asynchronously marks a released buffer as gained. This method is similar to
228 // the synchronous version above, except that it does not wait for BufferHub
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700229 // to acknowledge success or failure. Because of the asynchronous nature of
230 // the underlying message, no error is returned if this method is called when
231 // the buffer is in an incorrect state. Returns zero if sending the message
232 // succeeded, or a negative errno code if local error check fails.
233 int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800234
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700235 // Detaches a ProducerBuffer from an existing producer/consumer set. Can only
236 // be called when a producer buffer has exclusive access to the buffer (i.e.
237 // in the gain'ed state). On the successful return of the IPC call, a new
238 // LocalChannelHandle representing a detached buffer will be returned and all
239 // existing producer and consumer channels will be closed. Further IPCs
240 // towards those channels will return error.
241 Status<LocalChannelHandle> Detach();
242
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800243 private:
244 friend BASE;
245
246 // Constructors are automatically exposed through BufferProducer::Create(...)
247 // static template methods inherited from ClientBase, which take the same
248 // arguments as the constructors.
249
250 // Constructs a buffer with the given geometry and parameters.
Corey Tabakacd52dd92017-04-07 18:03:57 -0700251 BufferProducer(uint32_t width, uint32_t height, uint32_t format,
Jiwen 'Steve' Caif0108172018-03-09 13:32:39 -0800252 uint64_t usage, size_t metadata_size = 0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800253
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800254 // Constructs a blob (flat) buffer with the given usage flags.
Jiwen 'Steve' Caif0108172018-03-09 13:32:39 -0800255 BufferProducer(uint64_t usage, size_t size);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800256
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800257 // Imports the given file handle to a producer channel, taking ownership.
258 explicit BufferProducer(LocalChannelHandle channel);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700259
260 // Local state transition helpers.
261 int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
262 int LocalPost(const DvrNativeBufferMetadata* meta,
263 const LocalHandle& ready_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800264};
265
266// This is a connection to a producer buffer, which can be located in another
267// application. When that buffer is Post()ed, this fd will be signaled and
268// Acquire allows read access. The user is responsible for making sure that
269// Acquire is called with the correct metadata structure. The only guarantee the
270// API currently provides is that an Acquire() with metadata of the wrong size
271// will fail.
272class BufferConsumer : public pdx::ClientBase<BufferConsumer, BufferHubBuffer> {
273 public:
274 // This call assumes ownership of |fd|.
275 static std::unique_ptr<BufferConsumer> Import(LocalChannelHandle channel);
276 static std::unique_ptr<BufferConsumer> Import(
277 Status<LocalChannelHandle> status);
278
279 // Attempt to retrieve a post event from buffer hub. If successful,
280 // |ready_fence| will be set to a fence to wait on until the buffer is ready.
281 // This call will only succeed after the fd is signalled. This call may be
282 // performed as an alternative to the Acquire() with metadata. In such cases
283 // the metadata is not read.
284 //
285 // This returns zero or negative unix error code.
286 int Acquire(LocalHandle* ready_fence);
287
288 // Attempt to retrieve a post event from buffer hub. If successful,
289 // |ready_fence| is set to a fence signaling that the contents of the buffer
290 // are available. This call will only succeed if the buffer is in the posted
291 // state.
292 // Returns zero on success, or a negative errno code otherwise.
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700293 int Acquire(LocalHandle* ready_fence, void* meta, size_t user_metadata_size);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800294
295 // Attempt to retrieve a post event from buffer hub. If successful,
296 // |ready_fence| is set to a fence to wait on until the buffer is ready. This
297 // call will only succeed after the fd is signaled. This returns zero or a
298 // negative unix error code.
299 template <typename Meta>
300 int Acquire(LocalHandle* ready_fence, Meta* meta) {
301 return Acquire(ready_fence, meta, sizeof(*meta));
302 }
303
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700304 // Asynchronously acquires a bufer.
305 int AcquireAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
306
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800307 // This should be called after a successful Acquire call. If the fence is
308 // valid the fence determines the buffer usage, otherwise the buffer is
309 // released immediately.
310 // This returns zero or a negative unix error code.
311 int Release(const LocalHandle& release_fence);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700312 int ReleaseAsync();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800313
314 // Asynchronously releases a buffer. Similar to the synchronous version above,
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700315 // except that it does not wait for BufferHub to reply with success or error.
316 // The fence and metadata are passed to consumer via shared fd and shared
317 // memory.
318 int ReleaseAsync(const DvrNativeBufferMetadata* meta,
319 const LocalHandle& release_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800320
321 // May be called after or instead of Acquire to indicate that the consumer
322 // does not need to access the buffer this cycle. This returns zero or a
323 // negative unix error code.
324 int Discard();
325
326 // When set, this consumer is no longer notified when this buffer is
327 // available. The system behaves as if Discard() is immediately called
328 // whenever the buffer is posted. If ignore is set to true while a buffer is
329 // pending, it will act as if Discard() was also called.
330 // This returns zero or a negative unix error code.
331 int SetIgnore(bool ignore);
332
333 private:
334 friend BASE;
335
336 explicit BufferConsumer(LocalChannelHandle channel);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700337
338 // Local state transition helpers.
339 int LocalAcquire(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
340 int LocalRelease(const DvrNativeBufferMetadata* meta,
341 const LocalHandle& release_fence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800342};
343
344} // namespace dvr
345} // namespace android
346
347#endif // ANDROID_DVR_BUFFER_HUB_CLIENT_H_