Merge remote-tracking branch 'aosp/upstream-main' into 'aosp/master'
... to pull in support for `gralloc->set(<metadata>)` for Cuttlefish from https://crrev.com/c/3421048 and the related changes in the chain. Bug: b/219757060 Test: cvd start Test: cts dEQP-VK.api.external.memory.android_hardware_buffer.* Test: vts -m VtsHalGraphicsMapperV4_0Target Test: cvd start --gpu_mode=gfxstream Test: cts dEQP-VK.api.external.memory.android_hardware_buffer.* Test: vts -m VtsHalGraphicsMapperV4_0Target Change-Id: I541d479da3b208c25666fcc50f89c790c361f1f6
This commit is contained in:
commit
72c3089009
19 changed files with 727 additions and 252 deletions
|
|
@ -113,6 +113,7 @@ cc_defaults {
|
|||
|
||||
shared_libs: [
|
||||
"libcutils",
|
||||
"libdmabufheap",
|
||||
"libdrm",
|
||||
"libnativewindow",
|
||||
"libsync",
|
||||
|
|
|
|||
3
OWNERS
3
OWNERS
|
|
@ -5,6 +5,7 @@ gurchetansingh@chromium.org
|
|||
hiroh@chromium.org
|
||||
hoegsberg@chromium.org
|
||||
marcheu@chromium.org
|
||||
mcasas@chromium.org
|
||||
olv@google.com
|
||||
robdclark@chromium.org
|
||||
stevensd@chromium.org
|
||||
|
|
@ -14,7 +15,7 @@ zzyiwei@chromium.org
|
|||
# just reference for backend specific reviews
|
||||
per-file amdgpu.c = basni@chromium.org, ddavenport@chromium.org
|
||||
per-file i915.c = chadversary@chromium.org, hoegsberg@chromium.org
|
||||
per-file mediatek.c = fshao@chromium.org, tzungbi@chromium.org
|
||||
per-file mediatek.c = fshao@chromium.org, hsinyi@chromium.org, tzungbi@chromium.org
|
||||
per-file msm.c = robdclark@chromium.org, hoegsberg@chromium.org
|
||||
per-file rockchip.c = tfiga@chromium.org
|
||||
per-file virtgpu* = jbates@chromium.org, natsu@google.com, olv@google.com, zzyiwei@chromium.org
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
int ret;
|
||||
|
||||
int32_t reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC);
|
||||
if (reserved_region_fd == -1)
|
||||
return -errno;
|
||||
#if ANDROID_API_LEVEL >= 31
|
||||
ret = allocator_.Alloc(kDmabufSystemHeapName, reserved_region_size);
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
if (ftruncate(reserved_region_fd, reserved_region_size)) {
|
||||
drv_log("Failed to set reserved region size: %s.\n", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
ret = memfd_create_reserved_region(buffer_name, reserved_region_size);
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
|
||||
return reserved_region_fd;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
emplace_buffer(bo, hnd);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
*out_handle = reinterpret_cast<buffer_handle_t>(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 = 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;
|
||||
|
||||
if (buffers_.count(id)) {
|
||||
buffer = buffers_[id];
|
||||
cros_gralloc_buffer *buffer = nullptr;
|
||||
|
||||
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_);
|
||||
|
||||
for (const auto &pair : handles_)
|
||||
function(pair.first);
|
||||
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 : buffers_)
|
||||
function(pair.second.get());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
37
cros_gralloc/gralloc4/CrosGralloc4Metadata.h
Normal file
37
cros_gralloc/gralloc4/CrosGralloc4Metadata.h
Normal file
|
|
@ -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
|
||||
|
|
@ -315,13 +315,13 @@ const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap
|
|||
|
||||
{DRM_FORMAT_XBGR8888,
|
||||
{{
|
||||
.components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
|
||||
.components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
|
||||
.offsetInBits = 0,
|
||||
.sizeInBits = 8},
|
||||
{.type = android::gralloc4::PlaneLayoutComponentType_G,
|
||||
.offsetInBits = 8,
|
||||
.sizeInBits = 8},
|
||||
{.type = android::gralloc4::PlaneLayoutComponentType_R,
|
||||
{.type = android::gralloc4::PlaneLayoutComponentType_B,
|
||||
.offsetInBits = 16,
|
||||
.sizeInBits = 8}},
|
||||
.sampleIncrementInBits = 32,
|
||||
|
|
|
|||
2
dri.c
2
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;
|
||||
|
|
|
|||
7
i915.c
7
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);
|
||||
|
|
|
|||
62
mediatek.c
62
mediatek.c
|
|
@ -25,6 +25,17 @@
|
|||
|
||||
#define TILE_TYPE_LINEAR 0
|
||||
|
||||
#if defined(MTK_MT8183) || defined(MTK_MT8186)
|
||||
#define SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
|
||||
#endif
|
||||
|
||||
// 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 {
|
||||
void *cached_addr;
|
||||
void *gem_addr;
|
||||
|
|
@ -35,15 +46,37 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA
|
|||
DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_XRGB8888 };
|
||||
|
||||
#ifdef MTK_MT8183
|
||||
// clang-format off
|
||||
static const uint32_t texture_source_formats[] = {
|
||||
DRM_FORMAT_NV21, DRM_FORMAT_NV12, DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_ABGR16161616F
|
||||
#ifdef SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
|
||||
DRM_FORMAT_NV21,
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_ABGR16161616F,
|
||||
#endif
|
||||
DRM_FORMAT_NV12,
|
||||
DRM_FORMAT_YVU420,
|
||||
DRM_FORMAT_YVU420_ANDROID
|
||||
};
|
||||
#else
|
||||
static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID,
|
||||
DRM_FORMAT_NV12 };
|
||||
|
||||
#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)
|
||||
|
|
@ -67,7 +100,7 @@ static int mediatek_init(struct driver *drv)
|
|||
metadata.modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_DECODER);
|
||||
drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER);
|
||||
#if defined(MTK_MT8183) || defined(MTK_MT8192) || defined(MTK_MT8195)
|
||||
#ifdef USE_NV12_FOR_HW_VIDEO_DECODING
|
||||
// TODO(hiroh): Switch to use NV12 for video decoder on MT8173 as well.
|
||||
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_DECODER);
|
||||
#endif
|
||||
|
|
@ -118,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);
|
||||
|
|
@ -135,7 +175,7 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
|
|||
|
||||
drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding);
|
||||
} else {
|
||||
#ifdef MTK_MT8183
|
||||
#ifdef SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
|
||||
/*
|
||||
* JPEG Encoder Accelerator requires 16x16 alignment. We want the buffer
|
||||
* from camera can be put in JEA directly so align the height to 16
|
||||
|
|
@ -304,7 +344,7 @@ static void mediatek_resolve_format_and_use_flags(struct driver *drv, uint32_t f
|
|||
*out_use_flags &= ~BO_USE_HW_VIDEO_ENCODER;
|
||||
break;
|
||||
case DRM_FORMAT_FLEX_YCbCr_420_888:
|
||||
#if defined(MTK_MT8183) || defined(MTK_MT8192) || defined(MTK_MT8195)
|
||||
#ifdef USE_NV12_FOR_HW_VIDEO_DECODING
|
||||
// TODO(hiroh): Switch to use NV12 for video decoder on MT8173 as well.
|
||||
if (use_flags & (BO_USE_HW_VIDEO_DECODER)) {
|
||||
*out_format = DRM_FORMAT_NV12;
|
||||
|
|
|
|||
19
msm.c
19
msm.c
|
|
@ -38,7 +38,8 @@
|
|||
|
||||
static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_XRGB8888 };
|
||||
DRM_FORMAT_XRGB8888, DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_ABGR16161616F };
|
||||
|
||||
static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8,
|
||||
DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID,
|
||||
|
|
@ -206,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -633,7 +633,7 @@ static int virgl_init(struct driver *drv)
|
|||
/* Android CTS tests require this. */
|
||||
virgl_add_combination(drv, DRM_FORMAT_RGB888, &LINEAR_METADATA, BO_USE_SW_MASK);
|
||||
virgl_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK);
|
||||
virgl_add_combination(drv, DRM_FORMAT_P010, &LINEAR_METADATA,
|
||||
virgl_add_combination(drv, DRM_FORMAT_P010, &LINEAR_METADATA, BO_USE_TEXTURE |
|
||||
BO_USE_SW_MASK | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
|
||||
drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
|
||||
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue