buffer_hub_client.h revision 10e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848
1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_DVR_BUFFER_HUB_CLIENT_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_DVR_BUFFER_HUB_CLIENT_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <hardware/gralloc.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/channel_handle.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/file_handle.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/status.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <vector> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/ion_buffer.h> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferHubBuffer : public pdx::Client { 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using LocalHandle = pdx::LocalHandle; 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using LocalChannelHandle = pdx::LocalChannelHandle; 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename T> 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using Status = pdx::Status<T>; 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a new consumer channel that is attached to the producer. Returns 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // a file descriptor for the new channel or a negative error code. 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> CreateConsumer(); 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Polls the fd for |timeout_ms| milliseconds (-1 for infinity). 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Poll(int timeout_ms); 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Locks the area specified by (x, y, width, height) for a specific usage. If 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the usage is software then |addr| will be updated to point to the address 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // of the buffer in virtual memory. The caller should only access/modify the 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // pixels in the specified area. anything else is undefined behavior. 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Lock(int usage, int x, int y, int width, int height, void** addr, 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t index); 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Must be called after Lock() when the caller has finished changing the 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer. 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Unlock(size_t index); 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Helper for when index is 0. 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Lock(int usage, int x, int y, int width, int height, void** addr) { 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Lock(usage, x, y, width, height, addr, 0); 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Helper for when index is 0. 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Unlock() { return Unlock(0); } 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Gets a blob buffer that was created with BufferProducer::CreateBlob. 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Locking and Unlocking is handled internally. There's no need to Unlock 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // after calling this method. 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetBlobReadWritePointer(size_t size, void** addr); 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Gets a blob buffer that was created with BufferProducer::CreateBlob. 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Locking and Unlocking is handled internally. There's no need to Unlock 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // after calling this method. 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetBlobReadOnlyPointer(size_t size, void** addr); 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns a dup'd file descriptor for accessing the blob shared memory. The 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // caller takes ownership of the file descriptor and must close it or pass on 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // ownership. Some GPU API extensions can take file descriptors to bind shared 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // memory gralloc buffers to GPU buffer objects. 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle GetBlobFd() const { 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Current GPU vendor puts the buffer allocation in one FD. If we change GPU 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // vendors and this is the wrong fd, late-latching and EDS will very clearly 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // stop working and we will need to correct this. The alternative is to use 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // a GL context in the pose service to allocate this buffer or to use the 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // ION API directly instead of gralloc. 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return LocalHandle(dup(native_handle()->data[0])); 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 7310e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar // Get up to |max_fds_count| file descriptors for accessing the blob shared 7410e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar // memory. |fds_count| will contain the actual number of file descriptors. 7510e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar void GetBlobFds(int* fds, size_t* fds_count, size_t max_fds_count) const; 7610e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using Client::event_fd; 783079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka 793079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka Status<int> GetEventMask(int events) { 803079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka if (auto* client_channel = GetChannel()) { 813079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka return client_channel->GetEventMask(events); 823079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka } else { 833079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka return pdx::ErrorStatus(EINVAL); 843079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka } 853079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka } 863079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko native_handle_t* native_handle() const { 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return const_cast<native_handle_t*>(slices_[0].handle()); 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If index is greater than or equal to slice_count(), the result is 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // undefined. 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko native_handle_t* native_handle(size_t index) const { 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return const_cast<native_handle_t*>(slices_[index].handle()); 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IonBuffer* buffer() { return &slices_[0]; } 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If index is greater than or equal to slice_count(), the result is 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // undefined. 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IonBuffer* slice(size_t index) { return &slices_[index]; } 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int slice_count() const { return static_cast<int>(slices_.size()); } 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int id() const { return id_; } 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // The following methods return settings of the first buffer. Currently, 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // it is only possible to create multi-buffer BufferHubBuffers with the same 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // settings. 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int width() const { return slices_[0].width(); } 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int height() const { return slices_[0].height(); } 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int stride() const { return slices_[0].stride(); } 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int format() const { return slices_[0].format(); } 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int usage() const { return slices_[0].usage(); } 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko protected: 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferHubBuffer(LocalChannelHandle channel); 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferHubBuffer(const std::string& endpoint_path); 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual ~BufferHubBuffer(); 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Initialization helper. 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ImportBuffer(); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubBuffer(const BufferHubBuffer&) = delete; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const BufferHubBuffer&) = delete; 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Global id for the buffer that is consistent across processes. It is meant 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // for logging and debugging purposes only and should not be used for lookup 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // or any other functional purpose as a security precaution. 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int id_; 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // A BufferHubBuffer may contain multiple slices of IonBuffers with same 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // configurations. 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<IonBuffer> slices_; 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// This represents a writable buffer. Calling Post notifies all clients and 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// makes the buffer read-only. Call Gain to acquire write access. A buffer 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// may have many consumers. 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// The user of BufferProducer is responsible with making sure that the Post() is 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// done with the correct metadata type and size. The user is also responsible 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// for making sure that remote ends (BufferConsumers) are also using the correct 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// metadata when acquiring the buffer. The API guarantees that a Post() with a 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// metadata of wrong size will fail. However, it currently does not do any 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type checking. 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// The API also assumes that metadata is a serializable type (plain old data). 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferProducer : public pdx::ClientBase<BufferProducer, BufferHubBuffer> { 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a buffer designed to hold arbitrary bytes that can be read and 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // written from CPU, GPU and DSP. The buffer is mapped uncached so that CPU 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // reads and writes are predictable. 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferProducer> CreateUncachedBlob(size_t size); 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Creates a persistent uncached buffer with the given name and access. 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferProducer> CreatePersistentUncachedBlob( 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::string& name, int user_id, int group_id, size_t size); 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Imports a bufferhub producer channel, assuming ownership of its handle. 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferProducer> Import(LocalChannelHandle channel); 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferProducer> Import( 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status); 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Post this buffer, passing |ready_fence| to the consumers. The bytes in 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |meta| are passed unaltered to the consumers. The producer must not modify 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the buffer until it is re-gained. 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(const LocalHandle& ready_fence, const void* meta, 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t meta_size_bytes); 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename Meta, 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename = typename std::enable_if<std::is_void<Meta>::value>::type> 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(const LocalHandle& ready_fence) { 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Post(ready_fence, nullptr, 0); 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 1743079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka template < 1753079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka typename Meta, 1763079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka typename = typename std::enable_if<!std::is_void<Meta>::value>::type> 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(const LocalHandle& ready_fence, const Meta& meta) { 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Post(ready_fence, &meta, sizeof(meta)); 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to re-gain the buffer for writing. If |release_fence| is valid, it 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // must be waited on before using the buffer. If it is not valid then the 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer is free for immediate use. This call will only succeed if the buffer 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // is in the released state. 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Gain(LocalHandle* release_fence); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Asynchronously marks a released buffer as gained. This method is similar to 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the synchronous version above, except that it does not wait for BufferHub 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // to acknowledge success or failure, nor does it transfer a release fence to 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the client. This version may be used in situations where a release fence is 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // not needed. Because of the asynchronous nature of the underlying message, 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // no error is returned if this method is called when the buffer is in an 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // incorrect state. Returns zero if sending the message succeeded, or a 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // negative errno code otherwise. 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GainAsync(); 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attaches the producer to |name| so that it becomes a persistent buffer that 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // may be retrieved by name at a later time. This may be used in cases where a 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // shared memory buffer should persist across the life of the producer process 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // (i.e. the buffer may be held by clients across a service restart). The 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer may be associated with a user and/or group id to restrict access to 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the buffer. If user_id or group_id is -1 then checks for the respective id 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // are disabled. If user_id or group_id is 0 then the respective id of the 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // calling process is used instead. 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int MakePersistent(const std::string& name, int user_id, int group_id); 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Removes the persistence of the producer. 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int RemovePersistence(); 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructors are automatically exposed through BufferProducer::Create(...) 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // static template methods inherited from ClientBase, which take the same 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // arguments as the constructors. 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a buffer with the given geometry and parameters. 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferProducer(int width, int height, int format, int usage, 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t metadata_size = 0, size_t slice_count = 1); 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a persistent buffer with the given geometry and parameters and 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // binds it to |name| in one shot. If a persistent buffer with the same name 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // and settings already exists and matches the given geometry and parameters, 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // that buffer is connected to this client instead of creating a new buffer. 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If the name matches but the geometry or settings do not match then 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // construction fails and BufferProducer::Create() returns nullptr. 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Access to the persistent buffer may be restricted by |user_id| and/or 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |group_id|; these settings are established only when the buffer is first 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // created and cannot be changed. A user or group id of -1 disables checks for 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // that respective id. A user or group id of 0 is substituted with the 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // effective user or group id of the calling process. 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferProducer(const std::string& name, int user_id, int group_id, int width, 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int height, int format, int usage, size_t metadata_size = 0, 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t slice_count = 1); 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a blob (flat) buffer with the given usage flags. 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferProducer(int usage, size_t size); 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a persistent blob (flat) buffer and binds it to |name|. 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferProducer(const std::string& name, int user_id, int group_id, int usage, 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size); 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a channel to persistent buffer by name only. The buffer must 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // have been previously created or made persistent. 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferProducer(const std::string& name); 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Imports the given file handle to a producer channel, taking ownership. 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferProducer(LocalChannelHandle channel); 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// This is a connection to a producer buffer, which can be located in another 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// application. When that buffer is Post()ed, this fd will be signaled and 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Acquire allows read access. The user is responsible for making sure that 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Acquire is called with the correct metadata structure. The only guarantee the 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// API currently provides is that an Acquire() with metadata of the wrong size 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// will fail. 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferConsumer : public pdx::ClientBase<BufferConsumer, BufferHubBuffer> { 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This call assumes ownership of |fd|. 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferConsumer> Import(LocalChannelHandle channel); 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferConsumer> Import( 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status); 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to retrieve a post event from buffer hub. If successful, 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |ready_fence| will be set to a fence to wait on until the buffer is ready. 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This call will only succeed after the fd is signalled. This call may be 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // performed as an alternative to the Acquire() with metadata. In such cases 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the metadata is not read. 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or negative unix error code. 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Acquire(LocalHandle* ready_fence); 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to retrieve a post event from buffer hub. If successful, 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |ready_fence| is set to a fence signaling that the contents of the buffer 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // are available. This call will only succeed if the buffer is in the posted 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // state. 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns zero on success, or a negative errno code otherwise. 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Acquire(LocalHandle* ready_fence, void* meta, size_t meta_size_bytes); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to retrieve a post event from buffer hub. If successful, 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |ready_fence| is set to a fence to wait on until the buffer is ready. This 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // call will only succeed after the fd is signaled. This returns zero or a 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // negative unix error code. 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename Meta> 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Acquire(LocalHandle* ready_fence, Meta* meta) { 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Acquire(ready_fence, meta, sizeof(*meta)); 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This should be called after a successful Acquire call. If the fence is 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // valid the fence determines the buffer usage, otherwise the buffer is 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // released immediately. 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Release(const LocalHandle& release_fence); 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Asynchronously releases a buffer. Similar to the synchronous version above, 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // except that it does not wait for BufferHub to reply with success or error, 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // nor does it transfer a release fence. This version may be used in 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // situations where a release fence is not needed. Because of the asynchronous 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // nature of the underlying message, no error is returned if this method is 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // called when the buffer is in an incorrect state. Returns zero if sending 303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the message succeeded, or a negative errno code otherwise. 304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ReleaseAsync(); 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // May be called after or instead of Acquire to indicate that the consumer 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // does not need to access the buffer this cycle. This returns zero or a 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // negative unix error code. 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Discard(); 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // When set, this consumer is no longer notified when this buffer is 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // available. The system behaves as if Discard() is immediately called 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // whenever the buffer is posted. If ignore is set to true while a buffer is 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // pending, it will act as if Discard() was also called. 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SetIgnore(bool ignore); 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferConsumer(LocalChannelHandle channel); 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_DVR_BUFFER_HUB_CLIENT_H_ 328