diff options
author | Jason Macnak <natsu@google.com> | 2022-03-02 00:17:14 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-03-02 00:17:14 +0000 |
commit | ee8cf75deb53583e269f1a9b4588793708a9c15d (patch) | |
tree | 5dfda0d170f7dd6c5085f475dcd5f3319258cd3b | |
parent | 391024e0da35e62dafc748e3018536990f826ae7 (diff) | |
parent | 72c3089009061eda00519a76107b2d0ec612d6ea (diff) | |
download | minigbm-ee8cf75deb53583e269f1a9b4588793708a9c15d.tar.gz |
Merge "Merge remote-tracking branch 'aosp/upstream-main' into 'aosp/master'"
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_buffer.cc | 118 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_buffer.h | 34 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_driver.cc | 247 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_driver.h | 39 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_handle.h | 4 | ||||
-rw-r--r-- | cros_gralloc/gralloc0/gralloc0.cc | 23 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Allocator.cc | 46 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Allocator.h | 6 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Mapper.cc | 298 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Mapper.h | 27 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Metadata.h | 37 | ||||
-rw-r--r-- | dri.c | 2 | ||||
-rw-r--r-- | i915.c | 7 | ||||
-rw-r--r-- | mediatek.c | 30 | ||||
-rw-r--r-- | msm.c | 16 |
16 files changed, 698 insertions, 237 deletions
@@ -113,6 +113,7 @@ cc_defaults { shared_libs: [ "libcutils", + "libdmabufheap", "libdrm", "libnativewindow", "libsync", diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 2f4ceb0..e1af7a4 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -9,34 +9,110 @@ #include <assert.h> #include <sys/mman.h> -cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo, - struct cros_gralloc_handle *acquire_handle, - int32_t reserved_region_fd, uint64_t reserved_region_size) - : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0), - reserved_region_fd_(reserved_region_fd), reserved_region_size_(reserved_region_size), - reserved_region_addr_(nullptr) +#include <cutils/native_handle.h> + +/*static*/ +std::unique_ptr<cros_gralloc_buffer> +cros_gralloc_buffer::create(struct bo *acquire_bo, + const struct cros_gralloc_handle *borrowed_handle) +{ + auto acquire_hnd = + reinterpret_cast<struct cros_gralloc_handle *>(native_handle_clone(borrowed_handle)); + if (!acquire_hnd) { + drv_log("Failed to create cros_gralloc_buffer: failed to clone handle.\n"); + return {}; + } + + std::unique_ptr<cros_gralloc_buffer> buffer( + new cros_gralloc_buffer(acquire_bo, acquire_hnd)); + if (!buffer) { + drv_log("Failed to create cros_gralloc_buffer: failed to allocate.\n"); + native_handle_close(acquire_hnd); + native_handle_delete(acquire_hnd); + return {}; + } + + return buffer; +} + +cros_gralloc_buffer::cros_gralloc_buffer(struct bo *acquire_bo, + struct cros_gralloc_handle *acquire_handle) + : bo_(acquire_bo), hnd_(acquire_handle) { assert(bo_); - num_planes_ = drv_bo_get_num_planes(bo_); - for (uint32_t plane = 0; plane < num_planes_; plane++) + assert(hnd_); + for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) lock_data_[plane] = nullptr; } cros_gralloc_buffer::~cros_gralloc_buffer() { drv_bo_destroy(bo_); - if (hnd_) { - native_handle_close(hnd_); - native_handle_delete(hnd_); - } if (reserved_region_addr_) { - munmap(reserved_region_addr_, reserved_region_size_); + munmap(reserved_region_addr_, hnd_->reserved_region_size); } + native_handle_close(hnd_); + native_handle_delete(hnd_); } uint32_t cros_gralloc_buffer::get_id() const { - return id_; + return hnd_->id; +} + +uint32_t cros_gralloc_buffer::get_width() const +{ + return hnd_->width; +} + +uint32_t cros_gralloc_buffer::get_height() const +{ + return hnd_->height; +} + +uint32_t cros_gralloc_buffer::get_format() const +{ + return hnd_->format; +} + +uint64_t cros_gralloc_buffer::get_format_modifier() const +{ + return hnd_->format_modifier; +} + +uint64_t cros_gralloc_buffer::get_total_size() const +{ + return hnd_->total_size; +} + +uint32_t cros_gralloc_buffer::get_num_planes() const +{ + return hnd_->num_planes; +} + +uint32_t cros_gralloc_buffer::get_plane_offset(uint32_t plane) const +{ + return hnd_->offsets[plane]; +} + +uint32_t cros_gralloc_buffer::get_plane_stride(uint32_t plane) const +{ + return hnd_->strides[plane]; +} + +uint32_t cros_gralloc_buffer::get_plane_size(uint32_t plane) const +{ + return hnd_->sizes[plane]; +} + +int32_t cros_gralloc_buffer::get_android_format() const +{ + return hnd_->droid_format; +} + +uint64_t cros_gralloc_buffer::get_android_usage() const +{ + return static_cast<uint64_t>(hnd_->usage); } int32_t cros_gralloc_buffer::increase_refcount() @@ -91,7 +167,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla } } - for (uint32_t plane = 0; plane < num_planes_; plane++) + for (uint32_t plane = 0; plane < hnd_->num_planes; plane++) addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane); lockcount_++; @@ -148,16 +224,18 @@ int32_t cros_gralloc_buffer::flush() return 0; } -int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) +int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) const { - if (reserved_region_fd_ <= 0) { + int32_t reserved_region_fd = hnd_->fds[hnd_->num_planes]; + if (reserved_region_fd < 0) { drv_log("Buffer does not have reserved region.\n"); return -EINVAL; } if (!reserved_region_addr_) { - reserved_region_addr_ = mmap(nullptr, reserved_region_size_, PROT_WRITE | PROT_READ, - MAP_SHARED, reserved_region_fd_, 0); + reserved_region_addr_ = + mmap(nullptr, hnd_->reserved_region_size, PROT_WRITE | PROT_READ, MAP_SHARED, + reserved_region_fd, 0); if (reserved_region_addr_ == MAP_FAILED) { drv_log("Failed to mmap reserved region: %s.\n", strerror(errno)); return -errno; @@ -165,6 +243,6 @@ int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) } *addr = reserved_region_addr_; - *size = reserved_region_size_; + *size = hnd_->reserved_region_size; return 0; } diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index 3158454..21f8306 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -7,17 +7,30 @@ #ifndef CROS_GRALLOC_BUFFER_H #define CROS_GRALLOC_BUFFER_H +#include <memory> + #include "cros_gralloc_helpers.h" class cros_gralloc_buffer { public: - cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo, - struct cros_gralloc_handle *acquire_handle, int32_t reserved_region_fd, - uint64_t reserved_region_size); + static std::unique_ptr<cros_gralloc_buffer> + create(struct bo *acquire_bo, const struct cros_gralloc_handle *borrowed_handle); + ~cros_gralloc_buffer(); uint32_t get_id() const; + uint32_t get_width() const; + uint32_t get_height() const; + uint32_t get_format() const; + uint64_t get_format_modifier() const; + uint64_t get_total_size() const; + uint32_t get_num_planes() const; + uint32_t get_plane_offset(uint32_t plane) const; + uint32_t get_plane_stride(uint32_t plane) const; + uint32_t get_plane_size(uint32_t plane) const; + int32_t get_android_format() const; + uint64_t get_android_usage() const; /* The new reference count is returned by both these functions. */ int32_t increase_refcount(); @@ -32,28 +45,27 @@ class cros_gralloc_buffer int32_t invalidate(); int32_t flush(); - int32_t get_reserved_region(void **reserved_region_addr, uint64_t *reserved_region_size); + int32_t get_reserved_region(void **reserved_region_addr, + uint64_t *reserved_region_size) const; private: + cros_gralloc_buffer(struct bo *acquire_bo, struct cros_gralloc_handle *acquire_handle); + cros_gralloc_buffer(cros_gralloc_buffer const &); cros_gralloc_buffer operator=(cros_gralloc_buffer const &); - uint32_t id_; struct bo *bo_; /* Note: this will be nullptr for imported/retained buffers. */ struct cros_gralloc_handle *hnd_; - int32_t refcount_; - int32_t lockcount_; - uint32_t num_planes_; + int32_t refcount_ = 1; + int32_t lockcount_ = 0; struct mapping *lock_data_[DRV_MAX_PLANES]; /* Optional additional shared memory region attached to some gralloc buffers. */ - int32_t reserved_region_fd_; - uint64_t reserved_region_size_; - void *reserved_region_addr_; + mutable void *reserved_region_addr_ = nullptr; }; #endif diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 1381ff5..6ac094d 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -44,6 +44,22 @@ int memfd_create_wrapper(const char *name, unsigned int flags) return fd; } +int memfd_create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size) +{ + const std::string reserved_region_name = buffer_name + " reserved region"; + + int reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC); + if (reserved_region_fd == -1) + return -errno; + + if (ftruncate(reserved_region_fd, reserved_region_size)) { + drv_log("Failed to set reserved region size: %s.\n", strerror(errno)); + return -errno; + } + + return reserved_region_fd; +} + cros_gralloc_driver *cros_gralloc_driver::get_instance() { static cros_gralloc_driver s_instance; @@ -78,7 +94,7 @@ static struct driver *init_try_node(int idx, char const *str) return drv; } -cros_gralloc_driver::cros_gralloc_driver() +static struct driver *init_try_nodes() { /* * Create a driver from render nodes first, then try card @@ -87,6 +103,7 @@ cros_gralloc_driver::cros_gralloc_driver() * TODO(gsingh): Enable render nodes on udl/evdi. */ + struct driver *drv; char const *render_nodes_fmt = "%s/renderD%d"; char const *card_nodes_fmt = "%s/card%d"; uint32_t num_nodes = DRM_NUM_NODES; @@ -97,30 +114,36 @@ cros_gralloc_driver::cros_gralloc_driver() // Try render nodes... for (uint32_t i = min_render_node; i < max_render_node; i++) { - drv_ = init_try_node(i, render_nodes_fmt); - if (drv_) - return; + drv = init_try_node(i, render_nodes_fmt); + if (drv) + return drv; } // Try card nodes... for vkms mostly. for (uint32_t i = min_card_node; i < max_card_node; i++) { - drv_ = init_try_node(i, card_nodes_fmt); - if (drv_) - return; + drv = init_try_node(i, card_nodes_fmt); + if (drv) + return drv; } + + return nullptr; +} + +static void drv_destroy_and_close(struct driver *drv) +{ + int fd = drv_get_fd(drv); + drv_destroy(drv); + close(fd); +} + +cros_gralloc_driver::cros_gralloc_driver() : drv_(init_try_nodes(), drv_destroy_and_close) +{ } cros_gralloc_driver::~cros_gralloc_driver() { buffers_.clear(); handles_.clear(); - - if (drv_) { - int fd = drv_get_fd(drv_); - drv_destroy(drv_); - drv_ = nullptr; - close(fd); - } } bool cros_gralloc_driver::is_initialized() @@ -136,10 +159,10 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags( uint64_t resolved_use_flags; struct combination *combo; - drv_resolve_format_and_use_flags(drv_, descriptor->drm_format, descriptor->use_flags, + drv_resolve_format_and_use_flags(drv_.get(), descriptor->drm_format, descriptor->use_flags, &resolved_format, &resolved_use_flags); - combo = drv_get_combination(drv_, resolved_format, resolved_use_flags); + combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags); if (!combo && (descriptor->droid_usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && descriptor->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) { // Unmask BO_USE_HW_VIDEO_ENCODER for other formats. They are mostly @@ -147,12 +170,12 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags( // camera). YV12 is passed to the encoder component, but it is converted // to YCbCr_420_888 before being passed to the hw encoder. resolved_use_flags &= ~BO_USE_HW_VIDEO_ENCODER; - combo = drv_get_combination(drv_, resolved_format, resolved_use_flags); + combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags); } if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING)) { resolved_use_flags &= ~BO_USE_FRONT_RENDERING; resolved_use_flags |= BO_USE_LINEAR; - combo = drv_get_combination(drv_, resolved_format, resolved_use_flags); + combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags); } if (!combo) return false; @@ -166,7 +189,7 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript { uint32_t resolved_format; uint64_t resolved_use_flags; - uint32_t max_texture_size = drv_get_max_texture_2d_size(drv_); + uint32_t max_texture_size = drv_get_max_texture_2d_size(drv_.get()); if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) return false; @@ -177,53 +200,45 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript return descriptor->width <= max_texture_size && descriptor->height <= max_texture_size; } -int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size) +int cros_gralloc_driver::create_reserved_region(const std::string &buffer_name, + uint64_t reserved_region_size) { - std::string reserved_region_name = buffer_name + " reserved region"; - - int32_t reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC); - if (reserved_region_fd == -1) - return -errno; - - if (ftruncate(reserved_region_fd, reserved_region_size)) { - drv_log("Failed to set reserved region size: %s.\n", strerror(errno)); - return -errno; - } + int ret; - return reserved_region_fd; -} +#if ANDROID_API_LEVEL >= 31 + ret = allocator_.Alloc(kDmabufSystemHeapName, reserved_region_size); + if (ret >= 0) + return ret; +#endif -void cros_gralloc_driver::emplace_buffer(struct bo *bo, struct cros_gralloc_handle *hnd) -{ - auto buffer = new cros_gralloc_buffer(hnd->id, bo, hnd, hnd->fds[hnd->num_planes], - hnd->reserved_region_size); + ret = memfd_create_reserved_region(buffer_name, reserved_region_size); + if (ret >= 0) + return ret; - std::lock_guard<std::mutex> lock(mutex_); - buffers_.emplace(hnd->id, buffer); - handles_.emplace(hnd, std::make_pair(buffer, 1)); + drv_log("Failed to create_reserved_region.\n"); + return -1; } int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor, - buffer_handle_t *out_handle) + native_handle_t **out_handle) { int ret = 0; size_t num_planes; size_t num_fds; size_t num_ints; - size_t num_bytes; uint32_t resolved_format; uint32_t bytes_per_pixel; uint64_t resolved_use_flags; - char *name; struct bo *bo; struct cros_gralloc_handle *hnd; + std::unique_ptr<cros_gralloc_buffer> buffer; if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) { drv_log("Failed to resolve format and use_flags.\n"); return -EINVAL; } - bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, + bo = drv_bo_create(drv_.get(), descriptor->width, descriptor->height, resolved_format, resolved_use_flags); if (!bo) { drv_log("Failed to create bo.\n"); @@ -246,14 +261,8 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto if (descriptor->reserved_region_size > 0) num_fds += 1; - num_bytes = sizeof(struct cros_gralloc_handle); - num_bytes += (descriptor->name.size() + 1); - /* - * Ensure that the total number of bytes is a multiple of sizeof(int) as - * native_handle_clone() copies data based on hnd->base.numInts. - */ - num_bytes = ALIGN(num_bytes, sizeof(int)); - num_ints = ((num_bytes - sizeof(native_handle_t)) / sizeof(int)) - num_fds; + num_ints = ((sizeof(struct cros_gralloc_handle) - sizeof(native_handle_t)) / sizeof(int)) - + num_fds; hnd = reinterpret_cast<struct cros_gralloc_handle *>(native_handle_create(num_fds, num_ints)); @@ -296,14 +305,26 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto hnd->droid_format = descriptor->droid_format; hnd->usage = descriptor->droid_usage; hnd->total_size = descriptor->reserved_region_size + drv_bo_get_total_size(bo); - hnd->name_offset = handle_data_size; - name = (char *)(&hnd->data[hnd->name_offset]); - snprintf(name, descriptor->name.size() + 1, "%s", descriptor->name.c_str()); + buffer = cros_gralloc_buffer::create(bo, hnd); + if (!buffer) { + drv_log("Failed to allocate: failed to create cros_gralloc_buffer.\n"); + ret = -1; + goto destroy_hnd; + } + + { + std::lock_guard<std::mutex> lock(mutex_); - emplace_buffer(bo, hnd); + struct cros_gralloc_imported_handle_info hnd_info = { + .buffer = buffer.get(), + .refcount = 1, + }; + handles_.emplace(hnd, hnd_info); + buffers_.emplace(hnd->id, std::move(buffer)); + } - *out_handle = reinterpret_cast<buffer_handle_t>(hnd); + *out_handle = hnd; return 0; destroy_hnd: @@ -317,7 +338,6 @@ destroy_bo: int32_t cros_gralloc_driver::retain(buffer_handle_t handle) { - uint32_t id; std::lock_guard<std::mutex> lock(mutex_); auto hnd = cros_gralloc_convert_handle(handle); @@ -326,43 +346,65 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) return -EINVAL; } - auto buffer = get_buffer(hnd); - if (buffer) { - handles_[hnd].second++; - buffer->increase_refcount(); + auto hnd_it = handles_.find(hnd); + if (hnd_it != handles_.end()) { + // The underlying buffer (as multiple handles can refer to the same buffer) + // has already been imported into this process and the given handle has + // already been registered in this process. Increase both the buffer and + // handle reference count. + auto &hnd_info = hnd_it->second; + + hnd_info.buffer->increase_refcount(); + hnd_info.refcount++; + return 0; } - id = hnd->id; + uint32_t id = hnd->id; + + cros_gralloc_buffer *buffer = nullptr; - if (buffers_.count(id)) { - buffer = buffers_[id]; + auto buffer_it = buffers_.find(id); + if (buffer_it != buffers_.end()) { + // The underlying buffer (as multiple handles can refer to the same buffer) + // has already been imported into this process but the given handle has not + // yet been registered. Increase the buffer reference count (here) and start + // to track the handle (below). + buffer = buffer_it->second.get(); buffer->increase_refcount(); } else { - struct bo *bo; - struct drv_import_fd_data data; - data.format = hnd->format; - data.tiling = hnd->tiling; - - data.width = hnd->width; - data.height = hnd->height; - data.use_flags = hnd->use_flags; - + // The underlying buffer has not yet been imported into this process. Import + // and start to track the buffer (here) and start to track the handle (below). + struct drv_import_fd_data data = { + .format_modifier = hnd->format_modifier, + .width = hnd->width, + .height = hnd->height, + .format = hnd->format, + .tiling = hnd->tiling, + .use_flags = hnd->use_flags, + }; memcpy(data.fds, hnd->fds, sizeof(data.fds)); memcpy(data.strides, hnd->strides, sizeof(data.strides)); memcpy(data.offsets, hnd->offsets, sizeof(data.offsets)); - data.format_modifier = hnd->format_modifier; - bo = drv_bo_import(drv_, &data); + struct bo *bo = drv_bo_import(drv_.get(), &data); if (!bo) return -EFAULT; - buffer = new cros_gralloc_buffer(id, bo, nullptr, hnd->fds[hnd->num_planes], - hnd->reserved_region_size); - buffers_.emplace(id, buffer); + auto scoped_buffer = cros_gralloc_buffer::create(bo, hnd); + if (!scoped_buffer) { + drv_log("Failed to import: failed to create cros_gralloc_buffer.\n"); + return -1; + } + buffer = scoped_buffer.get(); + buffers_.emplace(id, std::move(scoped_buffer)); } - handles_.emplace(hnd, std::make_pair(buffer, 1)); + struct cros_gralloc_imported_handle_info hnd_info = { + .buffer = buffer, + .refcount = 1, + }; + handles_.emplace(hnd, hnd_info); return 0; } @@ -378,16 +420,15 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle) auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (release() called on unregistered handle).\n"); return -EINVAL; } - if (!--handles_[hnd].second) + if (!--handles_[hnd].refcount) handles_.erase(hnd); if (buffer->decrease_refcount() == 0) { buffers_.erase(buffer->get_id()); - delete buffer; } return 0; @@ -402,6 +443,7 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, return ret; std::lock_guard<std::mutex> lock(mutex_); + auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { drv_log("Invalid handle.\n"); @@ -410,7 +452,7 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (lock() called on unregistered handle).\n"); return -EINVAL; } @@ -429,7 +471,7 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fen auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (unlock() called on unregistered handle).\n"); return -EINVAL; } @@ -455,7 +497,7 @@ int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle) auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (invalidate() called on unregistered handle).\n"); return -EINVAL; } @@ -474,7 +516,7 @@ int32_t cros_gralloc_driver::flush(buffer_handle_t handle, int32_t *release_fenc auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (flush() called on unregistered handle).\n"); return -EINVAL; } @@ -500,7 +542,7 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (get_backing_store() called on unregistered handle).\n"); return -EINVAL; } @@ -522,7 +564,7 @@ int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t stri auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log("Invalid reference (resource_info() called on unregistered handle).\n"); return -EINVAL; } @@ -543,7 +585,8 @@ int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle, auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); + drv_log( + "Invalid reference (get_reserved_region() called on unregistered handle).\n"); return -EINVAL; } @@ -555,7 +598,7 @@ uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint6 uint32_t resolved_format; uint64_t resolved_use_flags; - drv_resolve_format_and_use_flags(drv_, drm_format, use_flags, &resolved_format, + drv_resolve_format_and_use_flags(drv_.get(), drm_format, use_flags, &resolved_format, &resolved_use_flags); return resolved_format; @@ -565,16 +608,30 @@ cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd) { /* Assumes driver mutex is held. */ if (handles_.count(hnd)) - return handles_[hnd].first; + return handles_[hnd].buffer; return nullptr; } -void cros_gralloc_driver::for_each_handle( - const std::function<void(cros_gralloc_handle_t)> &function) +void cros_gralloc_driver::with_buffer(cros_gralloc_handle_t hnd, + const std::function<void(cros_gralloc_buffer *)> &function) +{ + std::lock_guard<std::mutex> lock(mutex_); + + auto buffer = get_buffer(hnd); + if (!buffer) { + drv_log("Invalid reference (with_buffer() called on unregistered handle).\n"); + return; + } + + function(buffer); +} + +void cros_gralloc_driver::with_each_buffer( + const std::function<void(cros_gralloc_buffer *)> &function) { std::lock_guard<std::mutex> lock(mutex_); - for (const auto &pair : handles_) - function(pair.first); + for (const auto &pair : buffers_) + function(pair.second.get()); } diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index d1456a8..d9528d7 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -10,16 +10,22 @@ #include "cros_gralloc_buffer.h" #include <functional> +#include <memory> #include <mutex> +#include <string> #include <unordered_map> +#if ANDROID_API_LEVEL >= 31 +#include <BufferAllocator/BufferAllocator.h> +#endif + class cros_gralloc_driver { public: static cros_gralloc_driver *get_instance(); bool is_supported(const struct cros_gralloc_buffer_descriptor *descriptor); int32_t allocate(const struct cros_gralloc_buffer_descriptor *descriptor, - buffer_handle_t *out_handle); + native_handle_t **out_handle); int32_t retain(buffer_handle_t handle); int32_t release(buffer_handle_t handle); @@ -41,23 +47,42 @@ class cros_gralloc_driver uint32_t get_resolved_drm_format(uint32_t drm_format, uint64_t use_flags); - void for_each_handle(const std::function<void(cros_gralloc_handle_t)> &function); + void with_buffer(cros_gralloc_handle_t hnd, + const std::function<void(cros_gralloc_buffer *)> &function); + void with_each_buffer(const std::function<void(cros_gralloc_buffer *)> &function); private: cros_gralloc_driver(); ~cros_gralloc_driver(); bool is_initialized(); cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd); - void emplace_buffer(struct bo *bo, struct cros_gralloc_handle *hnd); bool get_resolved_format_and_use_flags(const struct cros_gralloc_buffer_descriptor *descriptor, uint32_t *out_format, uint64_t *out_use_flags); - struct driver *drv_ = nullptr; + int create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size); + +#if ANDROID_API_LEVEL >= 31 + /* For allocating cros_gralloc_buffer reserved regions for metadata. */ + BufferAllocator allocator_; +#endif + + std::unique_ptr<struct driver, void (*)(struct driver *)> drv_; + + struct cros_gralloc_imported_handle_info { + /* + * The underlying buffer for referred to by this handle (as multiple handles can + * refer to the same buffer). + */ + cros_gralloc_buffer *buffer = nullptr; + + /* The handle's refcount as a handle can be imported multiple times.*/ + int32_t refcount = 1; + }; + std::mutex mutex_; - std::unordered_map<uint32_t, cros_gralloc_buffer *> buffers_; - std::unordered_map<cros_gralloc_handle_t, std::pair<cros_gralloc_buffer *, int32_t>> - handles_; + std::unordered_map<uint32_t, std::unique_ptr<cros_gralloc_buffer>> buffers_; + std::unordered_map<cros_gralloc_handle_t, cros_gralloc_imported_handle_info> handles_; }; #endif diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index 2b70d4b..2d0e1ac 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -40,10 +40,6 @@ struct cros_gralloc_handle : public native_handle_t { uint32_t num_planes; uint64_t reserved_region_size; uint64_t total_size; /* Total allocation size */ - /* - * Name is a null terminated char array located at handle->base.data[handle->name_offset]. - */ - uint32_t name_offset; } __attribute__((packed)); typedef const struct cros_gralloc_handle *cros_gralloc_handle_t; diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 53c89fd..ce62521 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -8,6 +8,7 @@ #include "../cros_gralloc_driver.h" #include <cassert> +#include <cutils/native_handle.h> #include <hardware/gralloc.h> #include <memory.h> @@ -67,9 +68,10 @@ static int gralloc0_droid_yuv_format(int droid_format) } static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage, - buffer_handle_t *handle, int *stride) + buffer_handle_t *out_handle, int *out_stride) { int32_t ret; + native_handle_t *handle; struct cros_gralloc_buffer_descriptor descriptor; auto mod = (struct gralloc0_module const *)dev->common.module; @@ -89,20 +91,31 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa return -EINVAL; } - ret = mod->driver->allocate(&descriptor, handle); + ret = mod->driver->allocate(&descriptor, &handle); if (ret) return ret; - auto hnd = cros_gralloc_convert_handle(*handle); - *stride = hnd->pixel_stride; + auto hnd = cros_gralloc_convert_handle(handle); + *out_handle = handle; + *out_stride = hnd->pixel_stride; return 0; } static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle) { + int32_t ret; auto mod = (struct gralloc0_module const *)dev->common.module; - return mod->driver->release(handle); + + ret = mod->driver->release(handle); + if (ret) + return ret; + + auto hnd = const_cast<native_handle_t *>(handle); + native_handle_close(hnd); + native_handle_delete(hnd); + + return 0; } static int gralloc0_close(struct hw_device_t *dev) diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc index 0368e1a..6610c5e 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc @@ -10,8 +10,11 @@ #include <gralloctypes/Gralloc4.h> #include "cros_gralloc/cros_gralloc_helpers.h" +#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h" #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h" +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::Dataspace; using android::hardware::hidl_handle; using android::hardware::hidl_vec; using android::hardware::Return; @@ -28,6 +31,37 @@ Error CrosGralloc4Allocator::init() { return mDriver ? Error::NONE : Error::NO_RESOURCES; } +Error CrosGralloc4Allocator::initializeMetadata( + cros_gralloc_handle_t crosHandle, + const struct cros_gralloc_buffer_descriptor& crosDescriptor) { + if (!mDriver) { + drv_log("Failed to initializeMetadata. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + if (!crosHandle) { + drv_log("Failed to initializeMetadata. Invalid handle.\n"); + return Error::BAD_BUFFER; + } + + void* addr; + uint64_t size; + int ret = mDriver->get_reserved_region(crosHandle, &addr, &size); + if (ret) { + drv_log("Failed to getReservedRegion.\n"); + return Error::NO_RESOURCES; + } + + CrosGralloc4Metadata* crosMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr); + + snprintf(crosMetadata->name, CROS_GRALLOC4_METADATA_MAX_NAME_SIZE, "%s", + crosDescriptor.name.c_str()); + crosMetadata->dataspace = Dataspace::UNKNOWN; + crosMetadata->blendMode = BlendMode::INVALID; + + return Error::NONE; +} + Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride, hidl_handle* outHandle) { if (!mDriver) { @@ -44,6 +78,8 @@ Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, ui return Error::UNSUPPORTED; } + crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata); + if (!mDriver->is_supported(&crosDescriptor)) { std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format); std::string pixelFormatString = getPixelFormatString(descriptor.format); @@ -53,18 +89,24 @@ Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, ui return Error::UNSUPPORTED; } - buffer_handle_t handle; + native_handle_t* handle; int ret = mDriver->allocate(&crosDescriptor, &handle); if (ret) { return Error::NO_RESOURCES; } + outHandle->setTo(handle, /*shouldOwn=*/true); + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle); if (!crosHandle) { return Error::NO_RESOURCES; } - *outHandle = handle; + Error error = initializeMetadata(crosHandle, crosDescriptor); + if (error != Error::NONE) { + return error; + } + *outStride = crosHandle->pixel_stride; return Error::NONE; diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h index 1555a61..9c1c783 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h @@ -8,6 +8,8 @@ #include <android/hardware/graphics/mapper/4.0/IMapper.h> #include "cros_gralloc/cros_gralloc_driver.h" +#include "cros_gralloc/cros_gralloc_helpers.h" +#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h" class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_0::IAllocator { public: @@ -19,6 +21,10 @@ class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_ android::hardware::graphics::mapper::V4_0::Error init(); private: + android::hardware::graphics::mapper::V4_0::Error initializeMetadata( + cros_gralloc_handle_t crosHandle, + const struct cros_gralloc_buffer_descriptor& crosDescriptor); + android::hardware::graphics::mapper::V4_0::Error allocate( const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo& description, diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc index 8f952e1..cc2c4d5 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc @@ -418,11 +418,13 @@ Return<void> CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metada return Void(); } - get(crosHandle, metadataType, hidlCb); + mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) { + get(crosBuffer, metadataType, hidlCb); + }); return Void(); } -Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle, +Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType, get_cb hidlCb) { hidl_vec<uint8_t> encodedMetadata; @@ -432,40 +434,54 @@ Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle, return Void(); } - if (!crosHandle) { - drv_log("Failed to get. Invalid handle.\n"); + if (!crosBuffer) { + drv_log("Failed to get. Invalid buffer.\n"); hidlCb(Error::BAD_BUFFER, encodedMetadata); return Void(); } + const CrosGralloc4Metadata* crosMetadata = nullptr; + if (metadataType == android::gralloc4::MetadataType_BlendMode || + metadataType == android::gralloc4::MetadataType_Cta861_3 || + metadataType == android::gralloc4::MetadataType_Dataspace || + metadataType == android::gralloc4::MetadataType_Name || + metadataType == android::gralloc4::MetadataType_Smpte2086) { + Error error = getMetadata(crosBuffer, &crosMetadata); + if (error != Error::NONE) { + drv_log("Failed to get. Failed to get buffer metadata.\n"); + hidlCb(Error::NO_RESOURCES, encodedMetadata); + return Void(); + } + } + android::status_t status = android::NO_ERROR; if (metadataType == android::gralloc4::MetadataType_BufferId) { - status = android::gralloc4::encodeBufferId(crosHandle->id, &encodedMetadata); + status = android::gralloc4::encodeBufferId(crosBuffer->get_id(), &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Name) { - const char* name = (const char*)(&crosHandle->data[crosHandle->name_offset]); - status = android::gralloc4::encodeName(name, &encodedMetadata); + status = android::gralloc4::encodeName(crosMetadata->name, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Width) { - status = android::gralloc4::encodeWidth(crosHandle->width, &encodedMetadata); + status = android::gralloc4::encodeWidth(crosBuffer->get_width(), &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Height) { - status = android::gralloc4::encodeHeight(crosHandle->height, &encodedMetadata); + status = android::gralloc4::encodeHeight(crosBuffer->get_height(), &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_LayerCount) { status = android::gralloc4::encodeLayerCount(1, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) { - PixelFormat pixelFormat = static_cast<PixelFormat>(crosHandle->droid_format); + PixelFormat pixelFormat = static_cast<PixelFormat>(crosBuffer->get_android_format()); status = android::gralloc4::encodePixelFormatRequested(pixelFormat, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) { status = android::gralloc4::encodePixelFormatFourCC( - drv_get_standard_fourcc(crosHandle->format), &encodedMetadata); + drv_get_standard_fourcc(crosBuffer->get_format()), &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_PixelFormatModifier) { - status = android::gralloc4::encodePixelFormatModifier(crosHandle->format_modifier, + status = android::gralloc4::encodePixelFormatModifier(crosBuffer->get_format_modifier(), &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Usage) { - uint64_t usage = static_cast<uint64_t>(crosHandle->usage); - status = android::gralloc4::encodeUsage(usage, &encodedMetadata); + status = android::gralloc4::encodeUsage(crosBuffer->get_android_usage(), &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_AllocationSize) { - status = android::gralloc4::encodeAllocationSize(crosHandle->total_size, &encodedMetadata); + status = android::gralloc4::encodeAllocationSize(crosBuffer->get_total_size(), + &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) { - uint64_t hasProtectedContent = crosHandle->usage & BufferUsage::PROTECTED ? 1 : 0; + uint64_t hasProtectedContent = + crosBuffer->get_android_usage() & BufferUsage::PROTECTED ? 1 : 0; status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Compression) { status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None, @@ -478,38 +494,43 @@ Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_PlaneLayouts) { std::vector<PlaneLayout> planeLayouts; - getPlaneLayouts(crosHandle->format, &planeLayouts); + getPlaneLayouts(crosBuffer->get_format(), &planeLayouts); for (size_t plane = 0; plane < planeLayouts.size(); plane++) { PlaneLayout& planeLayout = planeLayouts[plane]; - planeLayout.offsetInBytes = crosHandle->offsets[plane]; - planeLayout.strideInBytes = crosHandle->strides[plane]; - planeLayout.totalSizeInBytes = crosHandle->sizes[plane]; - planeLayout.widthInSamples = crosHandle->width / planeLayout.horizontalSubsampling; - planeLayout.heightInSamples = crosHandle->height / planeLayout.verticalSubsampling; + planeLayout.offsetInBytes = crosBuffer->get_plane_offset(plane); + planeLayout.strideInBytes = crosBuffer->get_plane_stride(plane); + planeLayout.totalSizeInBytes = crosBuffer->get_plane_size(plane); + planeLayout.widthInSamples = + crosBuffer->get_width() / planeLayout.horizontalSubsampling; + planeLayout.heightInSamples = + crosBuffer->get_height() / planeLayout.verticalSubsampling; } status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Crop) { + const uint32_t numPlanes = crosBuffer->get_num_planes(); + const uint32_t w = crosBuffer->get_width(); + const uint32_t h = crosBuffer->get_height(); std::vector<aidl::android::hardware::graphics::common::Rect> crops; - for (size_t plane = 0; plane < crosHandle->num_planes; plane++) { + for (uint32_t plane = 0; plane < numPlanes; plane++) { aidl::android::hardware::graphics::common::Rect crop; crop.left = 0; crop.top = 0; - crop.right = crosHandle->width; - crop.bottom = crosHandle->height; + crop.right = w; + crop.bottom = h; crops.push_back(crop); } status = android::gralloc4::encodeCrop(crops, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Dataspace) { - status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata); + status = android::gralloc4::encodeDataspace(crosMetadata->dataspace, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_BlendMode) { - status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata); + status = android::gralloc4::encodeBlendMode(crosMetadata->blendMode, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) { - status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata); + status = android::gralloc4::encodeSmpte2086(crosMetadata->smpte2086, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) { - status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata); + status = android::gralloc4::encodeCta861_3(crosMetadata->cta861_3, &encodedMetadata); } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) { status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata); } else { @@ -528,7 +549,7 @@ Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle, } Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType, - const hidl_vec<uint8_t>& /*metadata*/) { + const hidl_vec<uint8_t>& encodedMetadata) { if (!mDriver) { drv_log("Failed to set. Driver is uninitialized.\n"); return Error::NO_RESOURCES; @@ -562,7 +583,68 @@ Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metad return Error::BAD_VALUE; } - return Error::UNSUPPORTED; + if (metadataType != android::gralloc4::MetadataType_BlendMode && + metadataType != android::gralloc4::MetadataType_Cta861_3 && + metadataType != android::gralloc4::MetadataType_Dataspace && + metadataType != android::gralloc4::MetadataType_Smpte2086) { + return Error::UNSUPPORTED; + } + + Error error = Error::NONE; + mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) { + error = set(crosBuffer, metadataType, encodedMetadata); + }); + + return error; +} + +Error CrosGralloc4Mapper::set(cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType, + const android::hardware::hidl_vec<uint8_t>& encodedMetadata) { + if (!mDriver) { + drv_log("Failed to set. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + if (!crosBuffer) { + drv_log("Failed to set. Invalid buffer.\n"); + return Error::BAD_BUFFER; + } + + CrosGralloc4Metadata* crosMetadata = nullptr; + + Error error = getMutableMetadata(crosBuffer, &crosMetadata); + if (error != Error::NONE) { + drv_log("Failed to set. Failed to get buffer metadata.\n"); + return Error::UNSUPPORTED; + } + + if (metadataType == android::gralloc4::MetadataType_BlendMode) { + auto status = android::gralloc4::decodeBlendMode(encodedMetadata, &crosMetadata->blendMode); + if (status != android::NO_ERROR) { + drv_log("Failed to set. Failed to decode blend mode.\n"); + return Error::UNSUPPORTED; + } + } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) { + auto status = android::gralloc4::decodeCta861_3(encodedMetadata, &crosMetadata->cta861_3); + if (status != android::NO_ERROR) { + drv_log("Failed to set. Failed to decode cta861_3.\n"); + return Error::UNSUPPORTED; + } + } else if (metadataType == android::gralloc4::MetadataType_Dataspace) { + auto status = android::gralloc4::decodeDataspace(encodedMetadata, &crosMetadata->dataspace); + if (status != android::NO_ERROR) { + drv_log("Failed to set. Failed to decode dataspace.\n"); + return Error::UNSUPPORTED; + } + } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) { + auto status = android::gralloc4::decodeSmpte2086(encodedMetadata, &crosMetadata->smpte2086); + if (status != android::NO_ERROR) { + drv_log("Failed to set. Failed to decode smpte2086.\n"); + return Error::UNSUPPORTED; + } + } + + return Error::NONE; } int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage, @@ -787,25 +869,25 @@ Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadat android::gralloc4::MetadataType_Dataspace, "", /*isGettable=*/true, - /*isSettable=*/false, + /*isSettable=*/true, }, { android::gralloc4::MetadataType_BlendMode, "", /*isGettable=*/true, - /*isSettable=*/false, + /*isSettable=*/true, }, { android::gralloc4::MetadataType_Smpte2086, "", /*isGettable=*/true, - /*isSettable=*/false, + /*isSettable=*/true, }, { android::gralloc4::MetadataType_Cta861_3, "", /*isGettable=*/true, - /*isSettable=*/false, + /*isSettable=*/true, }, { android::gralloc4::MetadataType_Smpte2094_40, @@ -842,10 +924,13 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlC return Void(); } - return dumpBuffer(crosHandle, hidlCb); + mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) { + dumpBuffer(crosBuffer, hidlCb); + }); + return Void(); } -Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle, +Return<void> CrosGralloc4Mapper::dumpBuffer(const cros_gralloc_buffer* crosBuffer, dumpBuffer_cb hidlCb) { BufferDump bufferDump; @@ -855,12 +940,6 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle, return Void(); } - if (!crosHandle) { - drv_log("Failed to dumpBuffer. Invalid handle.\n"); - hidlCb(Error::BAD_BUFFER, bufferDump); - return Void(); - } - std::vector<MetadataDump> metadataDumps; MetadataType metadataType = android::gralloc4::MetadataType_BufferId; @@ -872,55 +951,55 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle, }; metadataType = android::gralloc4::MetadataType_BufferId; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Name; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Width; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Height; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_LayerCount; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_PixelFormatRequested; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_PixelFormatFourCC; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_PixelFormatModifier; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Usage; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_AllocationSize; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_ProtectedContent; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Compression; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Interlaced; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_ChromaSiting; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_PlaneLayouts; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_Dataspace; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); metadataType = android::gralloc4::MetadataType_BlendMode; - get(crosHandle, metadataType, metadata_get_callback); + get(crosBuffer, metadataType, metadata_get_callback); bufferDump.metadataDump = metadataDumps; hidlCb(Error::NONE, bufferDump); @@ -938,22 +1017,89 @@ Return<void> CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) { Error error = Error::NONE; - auto handleCallback = [&](cros_gralloc_handle_t crosHandle) { - auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) { - error = err; - if (error == Error::NONE) { - bufferDumps.push_back(bufferDump); - } - }; - - dumpBuffer(crosHandle, dumpBufferCallback); + const auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) { + error = err; + if (error == Error::NONE) { + bufferDumps.push_back(bufferDump); + } }; - mDriver->for_each_handle(handleCallback); + + mDriver->with_each_buffer( + [&](cros_gralloc_buffer* crosBuffer) { dumpBuffer(crosBuffer, dumpBufferCallback); }); hidlCb(error, bufferDumps); return Void(); } +Error CrosGralloc4Mapper::getReservedRegionArea(const cros_gralloc_buffer* crosBuffer, + ReservedRegionArea area, void** outAddr, + uint64_t* outSize) { + if (!mDriver) { + drv_log("Failed to getReservedRegionArea. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + if (!crosBuffer) { + drv_log("Failed to getReservedRegionArea. Invalid buffer.\n"); + return Error::BAD_BUFFER; + } + + int ret = crosBuffer->get_reserved_region(outAddr, outSize); + if (ret) { + drv_log("Failed to getReservedRegionArea.\n"); + *outAddr = nullptr; + *outSize = 0; + return Error::NO_RESOURCES; + } + + switch (area) { + case ReservedRegionArea::MAPPER4_METADATA: { + // CrosGralloc4Metadata resides at the beginning reserved region. + *outSize = sizeof(CrosGralloc4Metadata); + break; + } + case ReservedRegionArea::USER_METADATA: { + // User metadata resides after the CrosGralloc4Metadata. + *outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(*outAddr) + + sizeof(CrosGralloc4Metadata)); + *outSize = *outSize - sizeof(CrosGralloc4Metadata); + break; + } + } + + return Error::NONE; +} + +Error CrosGralloc4Mapper::getMetadata(const cros_gralloc_buffer* crosBuffer, + const CrosGralloc4Metadata** outMetadata) { + void* addr = nullptr; + uint64_t size; + + Error error = + getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size); + if (error != Error::NONE) { + return error; + } + + *outMetadata = reinterpret_cast<const CrosGralloc4Metadata*>(addr); + return Error::NONE; +} + +Error CrosGralloc4Mapper::getMutableMetadata(cros_gralloc_buffer* crosBuffer, + CrosGralloc4Metadata** outMetadata) { + void* addr = nullptr; + uint64_t size; + + Error error = + getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size); + if (error != Error::NONE) { + return error; + } + + *outMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr); + return Error::NONE; +} + Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) { if (!mDriver) { drv_log("Failed to getReservedRegion. Driver is uninitialized.\n"); @@ -977,9 +1123,15 @@ Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedR void* reservedRegionAddr = nullptr; uint64_t reservedRegionSize = 0; - int ret = mDriver->get_reserved_region(bufferHandle, &reservedRegionAddr, &reservedRegionSize); - if (ret) { - drv_log("Failed to getReservedRegion.\n"); + + Error error = Error::NONE; + mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) { + error = getReservedRegionArea(crosBuffer, ReservedRegionArea::USER_METADATA, + &reservedRegionAddr, &reservedRegionSize); + }); + + if (error != Error::NONE) { + drv_log("Failed to getReservedRegion. Failed to getReservedRegionArea.\n"); hidlCb(Error::BAD_BUFFER, nullptr, 0); return Void(); } diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h index 0641b29..1734feb 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h @@ -8,6 +8,7 @@ #include "cros_gralloc/cros_gralloc_driver.h" #include "cros_gralloc/cros_gralloc_handle.h" +#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h" class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMapper { public: @@ -65,10 +66,32 @@ class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMa getReservedRegion_cb hidlCb) override; private: - android::hardware::Return<void> get(cros_gralloc_handle_t crosHandle, + enum class ReservedRegionArea { + /* CrosGralloc4Metadata */ + MAPPER4_METADATA, + + /* External user metadata */ + USER_METADATA, + }; + + android::hardware::graphics::mapper::V4_0::Error getReservedRegionArea( + const cros_gralloc_buffer* crosBuffer, ReservedRegionArea area, void** outAddr, + uint64_t* outSize); + + android::hardware::graphics::mapper::V4_0::Error getMetadata( + const cros_gralloc_buffer* crosBuffer, const CrosGralloc4Metadata** outMetadata); + + android::hardware::graphics::mapper::V4_0::Error getMutableMetadata( + cros_gralloc_buffer* crosBuffer, CrosGralloc4Metadata** outMetadata); + + android::hardware::Return<void> get(const cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType, get_cb hidlCb); - android::hardware::Return<void> dumpBuffer(cros_gralloc_handle_t crosHandle, + android::hardware::graphics::mapper::V4_0::Error set( + cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType, + const android::hardware::hidl_vec<uint8_t>& metadata); + + android::hardware::Return<void> dumpBuffer(const cros_gralloc_buffer* crosBuffer, dumpBuffer_cb hidlCb); int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat, diff --git a/cros_gralloc/gralloc4/CrosGralloc4Metadata.h b/cros_gralloc/gralloc4/CrosGralloc4Metadata.h new file mode 100644 index 0000000..c908e35 --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Metadata.h @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef CROSGRALLOC4METADATA_H +#define CROSGRALLOC4METADATA_H + +#include <aidl/android/hardware/graphics/common/BlendMode.h> +#include <aidl/android/hardware/graphics/common/Cta861_3.h> +#include <aidl/android/hardware/graphics/common/Dataspace.h> +#include <aidl/android/hardware/graphics/common/Smpte2086.h> + +#define CROS_GRALLOC4_METADATA_MAX_NAME_SIZE 1024 + +/* + * The metadata for cros_gralloc_buffer-s that should reside in a shared memory region + * instead of directly in cros_gralloc_handle-s. + * + * Any metadata that is mutable must be stored in this shared memory region as + * cros_gralloc_handle-s can not be tracked and updated across processes. + */ +struct CrosGralloc4Metadata { + /* + * Name is stored in the shared memory metadata to simplify cros_gralloc_handle + * creation. This allows us to keep handles small while avoiding variable sized + * handles. + */ + char name[CROS_GRALLOC4_METADATA_MAX_NAME_SIZE]; + aidl::android::hardware::graphics::common::BlendMode blendMode; + aidl::android::hardware::graphics::common::Dataspace dataspace; + std::optional<aidl::android::hardware::graphics::common::Cta861_3> cta861_3; + std::optional<aidl::android::hardware::graphics::common::Smpte2086> smpte2086; +}; + +#endif @@ -459,7 +459,7 @@ size_t dri_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_ } uint64_t planes; - GLboolean ret = dri->image_extension->queryDmaBufFormatModifierAttribs( + unsigned char ret = dri->image_extension->queryDmaBufFormatModifierAttribs( dri->device, format, modifier, __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT, &planes); if (!ret) return 0; @@ -41,6 +41,9 @@ static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_R I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR }; +static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR }; + struct modifier_support_t { const uint64_t *order; uint32_t count; @@ -163,6 +166,10 @@ static void i915_get_modifier_order(struct i915_device *i915) if (i915->gen == 12) { i915->modifier.order = gen12_modifier_order; i915->modifier.count = ARRAY_SIZE(gen12_modifier_order); + } + else if (i915->gen == 11) { + i915->modifier.order = gen11_modifier_order; + i915->modifier.count = ARRAY_SIZE(gen11_modifier_order); } else { i915->modifier.order = gen_modifier_order; i915->modifier.count = ARRAY_SIZE(gen_modifier_order); @@ -32,6 +32,8 @@ // All platforms except MT8173 should USE_NV12_FOR_HW_VIDEO_DECODING. #if defined(MTK_MT8183) || defined(MTK_MT8186) || defined(MTK_MT8192) || defined(MTK_MT8195) #define USE_NV12_FOR_HW_VIDEO_DECODING +#else +#define DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS #endif struct mediatek_private_map_data { @@ -56,8 +58,27 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; + +#ifdef DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS +static const uint32_t video_yuv_formats[] = { + DRM_FORMAT_NV21, + DRM_FORMAT_NV12, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID +}; // clang-format on +static bool is_video_yuv_format(uint32_t format) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE(video_yuv_formats); ++i) { + if (format == video_yuv_formats[i]) + return true; + } + return false; +} +#endif + static int mediatek_init(struct driver *drv) { struct format_metadata metadata; @@ -130,10 +151,17 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint /* * Since the ARM L1 cache line size is 64 bytes, align to that as a - * performance optimization. + * performance optimization, except for video buffers on certain platforms, + * these should only be accessed from the GPU and VCODEC subsystems (maybe + * also MDP), so it's better to align to macroblocks. */ stride = drv_stride_from_format(format, width, 0); +#ifdef DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS + const uint32_t alignment = is_video_yuv_format(format) ? 16 : 64; + stride = ALIGN(stride, alignment); +#else stride = ALIGN(stride, 64); +#endif if (bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER) { uint32_t aligned_height = ALIGN(height, 32); @@ -207,22 +207,6 @@ static bool should_avoid_ubwc(void) drv_log("WARNING: waffle detected, disabling UBWC\n"); return true; } - - /* The video_decode_accelerator_tests needs to read back the frames - * to verify they are correct. The frame verification relies on - * computing the MD5 of the video frame. UBWC results in a different - * MD5. This turns off UBWC for gtest until a proper frame - * comparison can be made - * Rely on the same mechanism that waffle is using, but this time check - * for a dynamic library function that is present in chrome, but missing - * in gtest. Cups is not loaded for video tests. - * - * See b/171260705 - */ - if (!dlsym(RTLD_DEFAULT, "cupsFilePrintf")) { - drv_log("WARNING: gtest detected, disabling UBWC\n"); - return true; - } #endif return false; } |