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 1452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka#include "bufferhub_rpc.h" 1552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferHubBuffer : public pdx::Client { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using LocalHandle = pdx::LocalHandle; 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using LocalChannelHandle = pdx::LocalChannelHandle; 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename T> 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using Status = pdx::Status<T>; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a new consumer channel that is attached to the producer. Returns 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // a file descriptor for the new channel or a negative error code. 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> CreateConsumer(); 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Polls the fd for |timeout_ms| milliseconds (-1 for infinity). 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Poll(int timeout_ms); 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Locks the area specified by (x, y, width, height) for a specific usage. If 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the usage is software then |addr| will be updated to point to the address 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // of the buffer in virtual memory. The caller should only access/modify the 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // pixels in the specified area. anything else is undefined behavior. 374d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar int Lock(int usage, int x, int y, int width, int height, void** addr); 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Must be called after Lock() when the caller has finished changing the 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer. 414d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar int Unlock(); 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Gets a blob buffer that was created with BufferProducer::CreateBlob. 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Locking and Unlocking is handled internally. There's no need to Unlock 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // after calling this method. 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetBlobReadWritePointer(size_t size, void** addr); 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Gets a blob buffer that was created with BufferProducer::CreateBlob. 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Locking and Unlocking is handled internally. There's no need to Unlock 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // after calling this method. 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetBlobReadOnlyPointer(size_t size, void** addr); 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns a dup'd file descriptor for accessing the blob shared memory. The 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // caller takes ownership of the file descriptor and must close it or pass on 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // ownership. Some GPU API extensions can take file descriptors to bind shared 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // memory gralloc buffers to GPU buffer objects. 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle GetBlobFd() const { 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Current GPU vendor puts the buffer allocation in one FD. If we change GPU 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // vendors and this is the wrong fd, late-latching and EDS will very clearly 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // stop working and we will need to correct this. The alternative is to use 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // a GL context in the pose service to allocate this buffer or to use the 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // ION API directly instead of gralloc. 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return LocalHandle(dup(native_handle()->data[0])); 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 6610e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar // Get up to |max_fds_count| file descriptors for accessing the blob shared 6710e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar // memory. |fds_count| will contain the actual number of file descriptors. 6810e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar void GetBlobFds(int* fds, size_t* fds_count, size_t max_fds_count) const; 6910e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using Client::event_fd; 713079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka 723079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka Status<int> GetEventMask(int events) { 733079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka if (auto* client_channel = GetChannel()) { 743079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka return client_channel->GetEventMask(events); 753079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka } else { 763079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka return pdx::ErrorStatus(EINVAL); 773079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka } 783079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka } 793079cb7c32421099a73e1a774b228635eeb3f189Corey Tabaka 8052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::vector<pdx::ClientChannel::EventSource> GetEventSources() const { 8152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka if (auto* client_channel = GetChannel()) { 8252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return client_channel->GetEventSources(); 8352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } else { 8452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka return {}; 8552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } 8652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } 8752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko native_handle_t* native_handle() const { 894d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar return const_cast<native_handle_t*>(buffer_.handle()); 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 912655e1cd5498749381701aa1fa7f29c66364a7efCorey Tabaka 924d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar IonBuffer* buffer() { return &buffer_; } 934d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar const IonBuffer* buffer() const { return &buffer_; } 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int id() const { return id_; } 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 9752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // A state mask which is unique to a buffer hub client among all its siblings 9852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // sharing the same concrete graphic buffer. 9952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka uint64_t buffer_state_bit() const { return buffer_state_bit_; } 10052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // The following methods return settings of the first buffer. Currently, 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // it is only possible to create multi-buffer BufferHubBuffers with the same 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // settings. 1044d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t width() const { return buffer_.width(); } 1054d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t height() const { return buffer_.height(); } 1064d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t stride() const { return buffer_.stride(); } 1074d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t format() const { return buffer_.format(); } 1084d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t usage() const { return buffer_.usage(); } 1094d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t layer_count() const { return buffer_.layer_count(); } 110044963e1dd0479035b6e5f2c6bd618bde7143710Jiwen 'Steve' Cai 111ec971362bc651d8c98febb8399981877da859c14Corey Tabaka // TODO(b/37881101) Clean up producer/consumer usage. 1124d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint64_t producer_usage() const { return buffer_.usage(); } 1134d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint64_t consumer_usage() const { return buffer_.usage(); } 114ec971362bc651d8c98febb8399981877da859c14Corey Tabaka 11552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka uint64_t GetQueueIndex() const { return metadata_header_->queue_index; } 11652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka void SetQueueIndex(uint64_t index) { metadata_header_->queue_index = index; } 11752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko protected: 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferHubBuffer(LocalChannelHandle channel); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferHubBuffer(const std::string& endpoint_path); 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual ~BufferHubBuffer(); 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Initialization helper. 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ImportBuffer(); 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Check invalid metadata operation. Returns 0 if requested metadata is valid. 12752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int CheckMetadata(size_t user_metadata_size) const; 12852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 12952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Send out the new fence by updating the shared fence (shared_release_fence 13052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // for producer and shared_acquire_fence for consumer). Note that during this 13152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // should only be used in LocalPost() or LocalRelease, and the shared fence 13252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // shouldn't be poll'ed by the other end. 13352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int UpdateSharedFence(const LocalHandle& new_fence, 13452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const LocalHandle& shared_fence); 13552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 13652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // IonBuffer that is shared between bufferhubd, producer, and consumers. 13752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka size_t metadata_buf_size_{0}; 13852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka size_t user_metadata_size_{0}; 13952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka BufferHubDefs::MetadataHeader* metadata_header_{nullptr}; 14052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka void* user_metadata_ptr_{nullptr}; 14152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::atomic<uint64_t>* buffer_state_{nullptr}; 14252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::atomic<uint64_t>* fence_state_{nullptr}; 14352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 14452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka LocalHandle shared_acquire_fence_; 14552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka LocalHandle shared_release_fence_; 14652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 14752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // A local fence fd that holds the ownership of the fence fd on Post (for 14852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // producer) and Release (for consumer). 14952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka LocalHandle pending_fence_fd_; 15052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferHubBuffer(const BufferHubBuffer&) = delete; 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const BufferHubBuffer&) = delete; 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Global id for the buffer that is consistent across processes. It is meant 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // for logging and debugging purposes only and should not be used for lookup 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // or any other functional purpose as a security precaution. 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int id_; 15952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka uint64_t buffer_state_bit_{0ULL}; 1604d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar IonBuffer buffer_; 16152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka IonBuffer metadata_buffer_; 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// This represents a writable buffer. Calling Post notifies all clients and 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// makes the buffer read-only. Call Gain to acquire write access. A buffer 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// may have many consumers. 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// The user of BufferProducer is responsible with making sure that the Post() is 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// done with the correct metadata type and size. The user is also responsible 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// for making sure that remote ends (BufferConsumers) are also using the correct 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// metadata when acquiring the buffer. The API guarantees that a Post() with a 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// metadata of wrong size will fail. However, it currently does not do any 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type checking. 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// The API also assumes that metadata is a serializable type (plain old data). 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferProducer : public pdx::ClientBase<BufferProducer, BufferHubBuffer> { 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Imports a bufferhub producer channel, assuming ownership of its handle. 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferProducer> Import(LocalChannelHandle channel); 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferProducer> Import( 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status); 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Asynchronously posts a buffer. The fence and metadata are passed to 18352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // consumer via shared fd and shared memory. 18452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int PostAsync(const DvrNativeBufferMetadata* meta, 18552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const LocalHandle& ready_fence); 18652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Post this buffer, passing |ready_fence| to the consumers. The bytes in 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |meta| are passed unaltered to the consumers. The producer must not modify 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the buffer until it is re-gained. 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(const LocalHandle& ready_fence, const void* meta, 19252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka size_t user_metadata_size); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename Meta, 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename = typename std::enable_if<std::is_void<Meta>::value>::type> 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(const LocalHandle& ready_fence) { 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Post(ready_fence, nullptr, 0); 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 1992655e1cd5498749381701aa1fa7f29c66364a7efCorey Tabaka template <typename Meta, typename = typename std::enable_if< 2002655e1cd5498749381701aa1fa7f29c66364a7efCorey Tabaka !std::is_void<Meta>::value>::type> 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(const LocalHandle& ready_fence, const Meta& meta) { 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Post(ready_fence, &meta, sizeof(meta)); 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to re-gain the buffer for writing. If |release_fence| is valid, it 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // must be waited on before using the buffer. If it is not valid then the 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer is free for immediate use. This call will only succeed if the buffer 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // is in the released state. 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Gain(LocalHandle* release_fence); 21152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int GainAsync(); 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Asynchronously marks a released buffer as gained. This method is similar to 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the synchronous version above, except that it does not wait for BufferHub 21552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // to acknowledge success or failure. Because of the asynchronous nature of 21652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // the underlying message, no error is returned if this method is called when 21752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // the buffer is in an incorrect state. Returns zero if sending the message 21852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // succeeded, or a negative errno code if local error check fails. 21952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence); 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attaches the producer to |name| so that it becomes a persistent buffer that 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // may be retrieved by name at a later time. This may be used in cases where a 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // shared memory buffer should persist across the life of the producer process 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // (i.e. the buffer may be held by clients across a service restart). The 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // buffer may be associated with a user and/or group id to restrict access to 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the buffer. If user_id or group_id is -1 then checks for the respective id 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // are disabled. If user_id or group_id is 0 then the respective id of the 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // calling process is used instead. 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int MakePersistent(const std::string& name, int user_id, int group_id); 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Removes the persistence of the producer. 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int RemovePersistence(); 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructors are automatically exposed through BufferProducer::Create(...) 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // static template methods inherited from ClientBase, which take the same 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // arguments as the constructors. 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a buffer with the given geometry and parameters. 242cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka BufferProducer(uint32_t width, uint32_t height, uint32_t format, 2434d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t usage, size_t metadata_size = 0); 244ec971362bc651d8c98febb8399981877da859c14Corey Tabaka BufferProducer(uint32_t width, uint32_t height, uint32_t format, 245ec971362bc651d8c98febb8399981877da859c14Corey Tabaka uint64_t producer_usage, uint64_t consumer_usage, 2464d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar size_t metadata_size); 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a persistent buffer with the given geometry and parameters and 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // binds it to |name| in one shot. If a persistent buffer with the same name 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // and settings already exists and matches the given geometry and parameters, 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // that buffer is connected to this client instead of creating a new buffer. 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // If the name matches but the geometry or settings do not match then 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // construction fails and BufferProducer::Create() returns nullptr. 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Access to the persistent buffer may be restricted by |user_id| and/or 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |group_id|; these settings are established only when the buffer is first 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // created and cannot be changed. A user or group id of -1 disables checks for 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // that respective id. A user or group id of 0 is substituted with the 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // effective user or group id of the calling process. 260cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka BufferProducer(const std::string& name, int user_id, int group_id, 261cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka uint32_t width, uint32_t height, uint32_t format, 2624d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar uint32_t usage, size_t metadata_size = 0); 263ec971362bc651d8c98febb8399981877da859c14Corey Tabaka BufferProducer(const std::string& name, int user_id, int group_id, 264ec971362bc651d8c98febb8399981877da859c14Corey Tabaka uint32_t width, uint32_t height, uint32_t format, 265ec971362bc651d8c98febb8399981877da859c14Corey Tabaka uint64_t producer_usage, uint64_t consumer_usage, 26652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka size_t user_metadata_size); 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a blob (flat) buffer with the given usage flags. 269ec971362bc651d8c98febb8399981877da859c14Corey Tabaka BufferProducer(uint32_t usage, size_t size); 270ec971362bc651d8c98febb8399981877da859c14Corey Tabaka BufferProducer(uint64_t producer_usage, uint64_t consumer_usage, size_t size); 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a persistent blob (flat) buffer and binds it to |name|. 273cd52dd9f1b301854b4e1734e3741d9cef8f784b1Corey Tabaka BufferProducer(const std::string& name, int user_id, int group_id, 274ec971362bc651d8c98febb8399981877da859c14Corey Tabaka uint32_t usage, size_t size); 275ec971362bc651d8c98febb8399981877da859c14Corey Tabaka BufferProducer(const std::string& name, int user_id, int group_id, 276ec971362bc651d8c98febb8399981877da859c14Corey Tabaka uint64_t producer_usage, uint64_t consumer_usage, size_t size); 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Constructs a channel to persistent buffer by name only. The buffer must 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // have been previously created or made persistent. 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferProducer(const std::string& name); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Imports the given file handle to a producer channel, taking ownership. 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferProducer(LocalChannelHandle channel); 28452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 28552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Local state transition helpers. 28652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence); 28752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int LocalPost(const DvrNativeBufferMetadata* meta, 28852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const LocalHandle& ready_fence); 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// This is a connection to a producer buffer, which can be located in another 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// application. When that buffer is Post()ed, this fd will be signaled and 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Acquire allows read access. The user is responsible for making sure that 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Acquire is called with the correct metadata structure. The only guarantee the 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// API currently provides is that an Acquire() with metadata of the wrong size 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// will fail. 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass BufferConsumer : public pdx::ClientBase<BufferConsumer, BufferHubBuffer> { 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This call assumes ownership of |fd|. 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferConsumer> Import(LocalChannelHandle channel); 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::unique_ptr<BufferConsumer> Import( 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status); 303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to retrieve a post event from buffer hub. If successful, 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |ready_fence| will be set to a fence to wait on until the buffer is ready. 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This call will only succeed after the fd is signalled. This call may be 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // performed as an alternative to the Acquire() with metadata. In such cases 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // the metadata is not read. 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or negative unix error code. 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Acquire(LocalHandle* ready_fence); 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to retrieve a post event from buffer hub. If successful, 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |ready_fence| is set to a fence signaling that the contents of the buffer 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // are available. This call will only succeed if the buffer is in the posted 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // state. 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns zero on success, or a negative errno code otherwise. 31852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int Acquire(LocalHandle* ready_fence, void* meta, size_t user_metadata_size); 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Attempt to retrieve a post event from buffer hub. If successful, 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // |ready_fence| is set to a fence to wait on until the buffer is ready. This 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // call will only succeed after the fd is signaled. This returns zero or a 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // negative unix error code. 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename Meta> 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Acquire(LocalHandle* ready_fence, Meta* meta) { 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Acquire(ready_fence, meta, sizeof(*meta)); 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 32952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Asynchronously acquires a bufer. 33052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int AcquireAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence); 33152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This should be called after a successful Acquire call. If the fence is 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // valid the fence determines the buffer usage, otherwise the buffer is 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // released immediately. 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Release(const LocalHandle& release_fence); 33752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int ReleaseAsync(); 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Asynchronously releases a buffer. Similar to the synchronous version above, 34052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // except that it does not wait for BufferHub to reply with success or error. 34152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // The fence and metadata are passed to consumer via shared fd and shared 34252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // memory. 34352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int ReleaseAsync(const DvrNativeBufferMetadata* meta, 34452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const LocalHandle& release_fence); 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // May be called after or instead of Acquire to indicate that the consumer 347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // does not need to access the buffer this cycle. This returns zero or a 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // negative unix error code. 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Discard(); 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // When set, this consumer is no longer notified when this buffer is 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // available. The system behaves as if Discard() is immediately called 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // whenever the buffer is posted. If ignore is set to true while a buffer is 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // pending, it will act as if Discard() was also called. 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This returns zero or a negative unix error code. 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SetIgnore(bool ignore); 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit BufferConsumer(LocalChannelHandle channel); 36252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 36352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Local state transition helpers. 36452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int LocalAcquire(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence); 36552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int LocalRelease(const DvrNativeBufferMetadata* meta, 36652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const LocalHandle& release_fence); 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_DVR_BUFFER_HUB_CLIENT_H_ 373