summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Macnak <natsu@google.com>2022-03-02 00:17:14 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-03-02 00:17:14 +0000
commitee8cf75deb53583e269f1a9b4588793708a9c15d (patch)
tree5dfda0d170f7dd6c5085f475dcd5f3319258cd3b
parent391024e0da35e62dafc748e3018536990f826ae7 (diff)
parent72c3089009061eda00519a76107b2d0ec612d6ea (diff)
downloadminigbm-ee8cf75deb53583e269f1a9b4588793708a9c15d.tar.gz
Merge "Merge remote-tracking branch 'aosp/upstream-main' into 'aosp/master'"
-rw-r--r--Android.bp1
-rw-r--r--cros_gralloc/cros_gralloc_buffer.cc118
-rw-r--r--cros_gralloc/cros_gralloc_buffer.h34
-rw-r--r--cros_gralloc/cros_gralloc_driver.cc247
-rw-r--r--cros_gralloc/cros_gralloc_driver.h39
-rw-r--r--cros_gralloc/cros_gralloc_handle.h4
-rw-r--r--cros_gralloc/gralloc0/gralloc0.cc23
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Allocator.cc46
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Allocator.h6
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Mapper.cc298
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Mapper.h27
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Metadata.h37
-rw-r--r--dri.c2
-rw-r--r--i915.c7
-rw-r--r--mediatek.c30
-rw-r--r--msm.c16
16 files changed, 698 insertions, 237 deletions
diff --git a/Android.bp b/Android.bp
index 9eb75e5..3038f22 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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
diff --git a/dri.c b/dri.c
index 4ee133d..ea8c757 100644
--- a/dri.c
+++ b/dri.c
@@ -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;
diff --git a/i915.c b/i915.c
index 055c582..6a44448 100644
--- a/i915.c
+++ b/i915.c
@@ -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);
diff --git a/mediatek.c b/mediatek.c
index 8456edd..cd3e641 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -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);
diff --git a/msm.c b/msm.c
index 255e723..14ecf2b 100644
--- a/msm.c
+++ b/msm.c
@@ -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;
}