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