-/*
- * Copyright 2020 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.
- */
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
cc_defaults {
name: "minigbm_defaults",
"-Wcast-align",
"-Wno-unused-parameter",
],
-
cppflags: ["-std=c++14"],
vendor: true,
static_libs: ["libarect"],
export_static_lib_headers: ["libarect"],
-
- relative_install_path: "hw",
}
cc_defaults {
- name: "minigbm_gralloc_defaults",
+ name: "minigbm_cros_gralloc_defaults",
defaults: ["minigbm_defaults"],
}
cc_library_static {
- name: "libminigbm_gralloc",
- defaults: ["minigbm_gralloc_defaults"],
+ name: "libminigbm_cros_gralloc",
+ defaults: ["minigbm_cros_gralloc_defaults"],
shared_libs: ["liblog"],
static_libs: ["libdrm"],
cc_library_shared {
name: "gralloc.minigbm",
- defaults: ["minigbm_gralloc_defaults"],
+ defaults: ["minigbm_cros_gralloc_defaults"],
srcs: ["cros_gralloc/gralloc0/gralloc0.cc"],
}
cc_library_shared {
name: "gralloc.minigbm_intel",
- defaults: ["minigbm_gralloc_defaults"],
+ defaults: ["minigbm_cros_gralloc_defaults"],
enabled: false,
arch: {
x86: {
cc_library_shared {
name: "gralloc.minigbm_meson",
- defaults: ["minigbm_gralloc_defaults"],
+ defaults: ["minigbm_cros_gralloc_defaults"],
cflags: ["-DDRV_MESON"],
srcs: ["cros_gralloc/gralloc0/gralloc0.cc"],
}
\ No newline at end of file
/* DRI backend decides tiling in this case. */
#define TILE_TYPE_DRI 1
-/* Height alignement for Encoder/Decoder buffers */
-#define CHROME_HEIGHT_ALIGN 16
-
struct amdgpu_priv {
struct dri_driver dri;
int drm_version;
-
- /* sdma */
- struct drm_amdgpu_info_device dev_info;
- uint32_t sdma_ctx;
- uint32_t sdma_cmdbuf_bo;
- uint64_t sdma_cmdbuf_addr;
- uint64_t sdma_cmdbuf_size;
- uint32_t *sdma_cmdbuf_map;
-};
-
-struct amdgpu_linear_vma_priv {
- uint32_t handle;
- uint32_t map_flags;
};
const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
DRM_FORMAT_NV21, DRM_FORMAT_NV12,
DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_YVU420 };
-static int query_dev_info(int fd, struct drm_amdgpu_info_device *dev_info)
-{
- struct drm_amdgpu_info info_args = { 0 };
-
- info_args.return_pointer = (uintptr_t)dev_info;
- info_args.return_size = sizeof(*dev_info);
- info_args.query = AMDGPU_INFO_DEV_INFO;
-
- return drmCommandWrite(fd, DRM_AMDGPU_INFO, &info_args, sizeof(info_args));
-}
-
-static int sdma_init(struct amdgpu_priv *priv, int fd)
-{
- union drm_amdgpu_ctx ctx_args = { { 0 } };
- union drm_amdgpu_gem_create gem_create = { { 0 } };
- struct drm_amdgpu_gem_va va_args = { 0 };
- union drm_amdgpu_gem_mmap gem_map = { { 0 } };
- struct drm_gem_close gem_close = { 0 };
- int ret;
-
- /* Ensure we can make a submission without BO lists. */
- if (priv->drm_version < 27)
- return 0;
-
- /* Anything outside this range needs adjustments to the SDMA copy commands */
- if (priv->dev_info.family < AMDGPU_FAMILY_CI || priv->dev_info.family > AMDGPU_FAMILY_NV)
- return 0;
-
- ctx_args.in.op = AMDGPU_CTX_OP_ALLOC_CTX;
-
- ret = drmCommandWriteRead(fd, DRM_AMDGPU_CTX, &ctx_args, sizeof(ctx_args));
- if (ret < 0)
- return ret;
-
- priv->sdma_ctx = ctx_args.out.alloc.ctx_id;
-
- priv->sdma_cmdbuf_size = ALIGN(4096, priv->dev_info.virtual_address_alignment);
- gem_create.in.bo_size = priv->sdma_cmdbuf_size;
- gem_create.in.alignment = 4096;
- gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT;
-
- ret = drmCommandWriteRead(fd, DRM_AMDGPU_GEM_CREATE, &gem_create, sizeof(gem_create));
- if (ret < 0)
- goto fail_ctx;
-
- priv->sdma_cmdbuf_bo = gem_create.out.handle;
-
- priv->sdma_cmdbuf_addr =
- ALIGN(priv->dev_info.virtual_address_offset, priv->dev_info.virtual_address_alignment);
-
- /* Map the buffer into the GPU address space so we can use it from the GPU */
- va_args.handle = priv->sdma_cmdbuf_bo;
- va_args.operation = AMDGPU_VA_OP_MAP;
- va_args.flags = AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_EXECUTABLE;
- va_args.va_address = priv->sdma_cmdbuf_addr;
- va_args.offset_in_bo = 0;
- va_args.map_size = priv->sdma_cmdbuf_size;
-
- ret = drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
- if (ret)
- goto fail_bo;
-
- gem_map.in.handle = priv->sdma_cmdbuf_bo;
- ret = drmIoctl(fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &gem_map);
- if (ret)
- goto fail_va;
-
- priv->sdma_cmdbuf_map = mmap(0, priv->sdma_cmdbuf_size, PROT_READ | PROT_WRITE, MAP_SHARED,
- fd, gem_map.out.addr_ptr);
- if (priv->sdma_cmdbuf_map == MAP_FAILED) {
- priv->sdma_cmdbuf_map = NULL;
- ret = -ENOMEM;
- goto fail_va;
- }
-
- return 0;
-fail_va:
- va_args.operation = AMDGPU_VA_OP_UNMAP;
- va_args.flags = 0;
- drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
-fail_bo:
- gem_close.handle = priv->sdma_cmdbuf_bo;
- drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
-fail_ctx:
- memset(&ctx_args, 0, sizeof(ctx_args));
- ctx_args.in.op = AMDGPU_CTX_OP_FREE_CTX;
- ctx_args.in.ctx_id = priv->sdma_ctx;
- drmCommandWriteRead(fd, DRM_AMDGPU_CTX, &ctx_args, sizeof(ctx_args));
- return ret;
-}
-
-static void sdma_finish(struct amdgpu_priv *priv, int fd)
-{
- union drm_amdgpu_ctx ctx_args = { { 0 } };
- struct drm_amdgpu_gem_va va_args = { 0 };
- struct drm_gem_close gem_close = { 0 };
-
- if (!priv->sdma_cmdbuf_map)
- return;
-
- va_args.handle = priv->sdma_cmdbuf_bo;
- va_args.operation = AMDGPU_VA_OP_UNMAP;
- va_args.flags = 0;
- va_args.va_address = priv->sdma_cmdbuf_addr;
- va_args.offset_in_bo = 0;
- va_args.map_size = priv->sdma_cmdbuf_size;
- drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
-
- gem_close.handle = priv->sdma_cmdbuf_bo;
- drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
-
- ctx_args.in.op = AMDGPU_CTX_OP_FREE_CTX;
- ctx_args.in.ctx_id = priv->sdma_ctx;
- drmCommandWriteRead(fd, DRM_AMDGPU_CTX, &ctx_args, sizeof(ctx_args));
-}
-
-static int sdma_copy(struct amdgpu_priv *priv, int fd, uint32_t src_handle, uint32_t dst_handle,
- uint64_t size)
-{
- const uint64_t max_size_per_cmd = 0x3fff00;
- const uint32_t cmd_size = 7 * sizeof(uint32_t); /* 7 dwords, see loop below. */
- const uint64_t max_commands = priv->sdma_cmdbuf_size / cmd_size;
- uint64_t src_addr = priv->sdma_cmdbuf_addr + priv->sdma_cmdbuf_size;
- uint64_t dst_addr = src_addr + size;
- struct drm_amdgpu_gem_va va_args = { 0 };
- unsigned cmd = 0;
- uint64_t remaining_size = size;
- uint64_t cur_src_addr = src_addr;
- uint64_t cur_dst_addr = dst_addr;
- struct drm_amdgpu_cs_chunk_ib ib = { 0 };
- struct drm_amdgpu_cs_chunk chunks[2] = { { 0 } };
- uint64_t chunk_ptrs[2];
- union drm_amdgpu_cs cs = { { 0 } };
- struct drm_amdgpu_bo_list_in bo_list = { 0 };
- struct drm_amdgpu_bo_list_entry bo_list_entries[3] = { { 0 } };
- union drm_amdgpu_wait_cs wait_cs = { { 0 } };
- int ret = 0;
-
- if (size > UINT64_MAX - max_size_per_cmd ||
- DIV_ROUND_UP(size, max_size_per_cmd) > max_commands)
- return -ENOMEM;
-
- /* Map both buffers into the GPU address space so we can access them from the GPU. */
- va_args.handle = src_handle;
- va_args.operation = AMDGPU_VA_OP_MAP;
- va_args.flags = AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_DELAY_UPDATE;
- va_args.va_address = src_addr;
- va_args.map_size = size;
-
- ret = drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
- if (ret)
- return ret;
-
- va_args.handle = dst_handle;
- va_args.flags = AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_DELAY_UPDATE;
- va_args.va_address = dst_addr;
-
- ret = drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
- if (ret)
- goto unmap_src;
-
- while (remaining_size) {
- uint64_t cur_size = remaining_size;
- if (cur_size > max_size_per_cmd)
- cur_size = max_size_per_cmd;
-
- priv->sdma_cmdbuf_map[cmd++] = 0x01; /* linear copy */
- priv->sdma_cmdbuf_map[cmd++] =
- priv->dev_info.family >= AMDGPU_FAMILY_AI ? (cur_size - 1) : cur_size;
- priv->sdma_cmdbuf_map[cmd++] = 0;
- priv->sdma_cmdbuf_map[cmd++] = cur_src_addr;
- priv->sdma_cmdbuf_map[cmd++] = cur_src_addr >> 32;
- priv->sdma_cmdbuf_map[cmd++] = cur_dst_addr;
- priv->sdma_cmdbuf_map[cmd++] = cur_dst_addr >> 32;
-
- remaining_size -= cur_size;
- cur_src_addr += cur_size;
- cur_dst_addr += cur_size;
- }
-
- ib.va_start = priv->sdma_cmdbuf_addr;
- ib.ib_bytes = cmd * 4;
- ib.ip_type = AMDGPU_HW_IP_DMA;
-
- chunks[1].chunk_id = AMDGPU_CHUNK_ID_IB;
- chunks[1].length_dw = sizeof(ib) / 4;
- chunks[1].chunk_data = (uintptr_t)&ib;
-
- bo_list_entries[0].bo_handle = priv->sdma_cmdbuf_bo;
- bo_list_entries[0].bo_priority = 8; /* Middle of range, like RADV. */
- bo_list_entries[1].bo_handle = src_handle;
- bo_list_entries[1].bo_priority = 8;
- bo_list_entries[2].bo_handle = dst_handle;
- bo_list_entries[2].bo_priority = 8;
-
- bo_list.bo_number = 3;
- bo_list.bo_info_size = sizeof(bo_list_entries[0]);
- bo_list.bo_info_ptr = (uintptr_t)bo_list_entries;
-
- chunks[0].chunk_id = AMDGPU_CHUNK_ID_BO_HANDLES;
- chunks[0].length_dw = sizeof(bo_list) / 4;
- chunks[0].chunk_data = (uintptr_t)&bo_list;
-
- chunk_ptrs[0] = (uintptr_t)&chunks[0];
- chunk_ptrs[1] = (uintptr_t)&chunks[1];
-
- cs.in.ctx_id = priv->sdma_ctx;
- cs.in.num_chunks = 2;
- cs.in.chunks = (uintptr_t)chunk_ptrs;
-
- ret = drmCommandWriteRead(fd, DRM_AMDGPU_CS, &cs, sizeof(cs));
- if (ret) {
- drv_log("SDMA copy command buffer submission failed %d\n", ret);
- goto unmap_dst;
- }
-
- wait_cs.in.handle = cs.out.handle;
- wait_cs.in.ip_type = AMDGPU_HW_IP_DMA;
- wait_cs.in.ctx_id = priv->sdma_ctx;
- wait_cs.in.timeout = INT64_MAX;
-
- ret = drmCommandWriteRead(fd, DRM_AMDGPU_WAIT_CS, &wait_cs, sizeof(wait_cs));
- if (ret) {
- drv_log("Could not wait for CS to finish\n");
- } else if (wait_cs.out.status) {
- drv_log("Infinite wait timed out, likely GPU hang.\n");
- ret = -ENODEV;
- }
-
-unmap_dst:
- va_args.handle = dst_handle;
- va_args.operation = AMDGPU_VA_OP_UNMAP;
- va_args.flags = AMDGPU_VM_DELAY_UPDATE;
- va_args.va_address = dst_addr;
- drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
-
-unmap_src:
- va_args.handle = src_handle;
- va_args.operation = AMDGPU_VA_OP_UNMAP;
- va_args.flags = AMDGPU_VM_DELAY_UPDATE;
- va_args.va_address = src_addr;
- drmCommandWrite(fd, DRM_AMDGPU_GEM_VA, &va_args, sizeof(va_args));
-
- return ret;
-}
-
static int amdgpu_init(struct driver *drv)
{
struct amdgpu_priv *priv;
drv->priv = priv;
- if (query_dev_info(drv_get_fd(drv), &priv->dev_info)) {
- free(priv);
- drv->priv = NULL;
- return -ENODEV;
- }
if (dri_init(drv, DRI_PATH, "radeonsi")) {
free(priv);
drv->priv = NULL;
return -ENODEV;
}
- if (sdma_init(priv, drv_get_fd(drv))) {
- drv_log("SDMA init failed\n");
-
- /* Continue, as we can still succesfully map things without SDMA. */
- }
-
metadata.tiling = TILE_TYPE_LINEAR;
metadata.priority = 1;
metadata.modifier = DRM_FORMAT_MOD_LINEAR;
drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats),
&metadata, BO_USE_TEXTURE_MASK);
- /* NV12 format for camera, display, decoding and encoding. */
- drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
- BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER);
+ /*
+ * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the
+ * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future.
+ */
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER);
+ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER);
/* Android CTS tests require this. */
drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK);
drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_SCANOUT);
drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT);
+ /* YUV formats for camera and display. */
+ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
+ BO_USE_HW_VIDEO_DECODER);
+
drv_modify_combination(drv, DRM_FORMAT_NV21, &metadata, BO_USE_SCANOUT);
/*
* R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
- * from camera and input/output from hardware decoder/encoder.
+ * from camera.
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
/*
* The following formats will be allocated by the DRI backend and may be potentially tiled.
static void amdgpu_close(struct driver *drv)
{
- sdma_finish(drv->priv, drv_get_fd(drv));
dri_close(drv);
free(drv->priv);
drv->priv = NULL;
int ret;
uint32_t plane, stride;
union drm_amdgpu_gem_create gem_create;
- struct amdgpu_priv *priv = bo->drv->priv;
stride = drv_stride_from_format(format, width, 0);
stride = ALIGN(stride, 256);
- /*
- * Currently, allocator used by chrome aligns the height for Encoder/
- * Decoder buffers while allocator used by android(gralloc/minigbm)
- * doesn't provide any aligment.
- *
- * See b/153130069
- */
- if (use_flags & (BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER))
- height = ALIGN(height, CHROME_HEIGHT_ALIGN);
-
drv_bo_from_format(bo, stride, height, format);
memset(&gem_create, 0, sizeof(gem_create));
- gem_create.in.bo_size =
- ALIGN(bo->meta.total_size, priv->dev_info.virtual_address_alignment);
+ gem_create.in.bo_size = bo->meta.total_size;
gem_create.in.alignment = 256;
gem_create.in.domain_flags = 0;
gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT;
-
- /* Scanout in GTT requires USWC, otherwise try to use cachable memory
- * for buffers that are read often, because uncacheable reads can be
- * very slow. USWC should be faster on the GPU though. */
- if ((use_flags & BO_USE_SCANOUT) || !(use_flags & BO_USE_SW_READ_OFTEN))
+ if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT)))
gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC;
/* Allocate the buffer with the preferred heap. */
static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
{
- void *addr = MAP_FAILED;
int ret;
union drm_amdgpu_gem_mmap gem_map;
- struct drm_amdgpu_gem_create_in bo_info = { 0 };
- struct drm_amdgpu_gem_op gem_op = { 0 };
- uint32_t handle = bo->handles[plane].u32;
- struct amdgpu_linear_vma_priv *priv = NULL;
- struct amdgpu_priv *drv_priv;
if (bo->priv)
return dri_bo_map(bo, vma, plane, map_flags);
- drv_priv = bo->drv->priv;
- gem_op.handle = handle;
- gem_op.op = AMDGPU_GEM_OP_GET_GEM_CREATE_INFO;
- gem_op.value = (uintptr_t)&bo_info;
-
- ret = drmCommandWriteRead(bo->drv->fd, DRM_AMDGPU_GEM_OP, &gem_op, sizeof(gem_op));
- if (ret)
- return MAP_FAILED;
-
- vma->length = bo_info.bo_size;
-
- if (((bo_info.domains & AMDGPU_GEM_DOMAIN_VRAM) ||
- (bo_info.domain_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)) &&
- drv_priv->sdma_cmdbuf_map) {
- union drm_amdgpu_gem_create gem_create = { { 0 } };
-
- priv = calloc(1, sizeof(struct amdgpu_linear_vma_priv));
- if (!priv)
- return MAP_FAILED;
-
- gem_create.in.bo_size = bo_info.bo_size;
- gem_create.in.alignment = 4096;
- gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT;
-
- ret = drmCommandWriteRead(bo->drv->fd, DRM_AMDGPU_GEM_CREATE, &gem_create,
- sizeof(gem_create));
- if (ret < 0) {
- drv_log("GEM create failed\n");
- free(priv);
- return MAP_FAILED;
- }
-
- priv->map_flags = map_flags;
- handle = priv->handle = gem_create.out.handle;
-
- ret = sdma_copy(bo->drv->priv, bo->drv->fd, bo->handles[0].u32, priv->handle,
- bo_info.bo_size);
- if (ret) {
- drv_log("SDMA copy for read failed\n");
- goto fail;
- }
- }
-
memset(&gem_map, 0, sizeof(gem_map));
- gem_map.in.handle = handle;
+ gem_map.in.handle = bo->handles[plane].u32;
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &gem_map);
if (ret) {
drv_log("DRM_IOCTL_AMDGPU_GEM_MMAP failed\n");
- goto fail;
+ return MAP_FAILED;
}
- addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
- gem_map.out.addr_ptr);
- if (addr == MAP_FAILED)
- goto fail;
-
- vma->priv = priv;
- return addr;
+ vma->length = bo->meta.total_size;
-fail:
- if (priv) {
- struct drm_gem_close gem_close = { 0 };
- gem_close.handle = priv->handle;
- drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
- free(priv);
- }
- return MAP_FAILED;
+ return mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
+ gem_map.out.addr_ptr);
}
static int amdgpu_unmap_bo(struct bo *bo, struct vma *vma)
{
if (bo->priv)
return dri_bo_unmap(bo, vma);
- else {
- int r = munmap(vma->addr, vma->length);
- if (r)
- return r;
-
- if (vma->priv) {
- struct amdgpu_linear_vma_priv *priv = vma->priv;
- struct drm_gem_close gem_close = { 0 };
-
- if (BO_MAP_WRITE & priv->map_flags) {
- r = sdma_copy(bo->drv->priv, bo->drv->fd, priv->handle,
- bo->handles[0].u32, vma->length);
- if (r)
- return r;
- }
-
- gem_close.handle = priv->handle;
- r = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
- }
-
- return 0;
- }
+ else
+ return munmap(vma->addr, vma->length);
}
static int amdgpu_bo_invalidate(struct bo *bo, struct mapping *mapping)
LIBDRM_CFLAGS := $(shell $(PKG_CONFIG) --cflags libdrm)
LIBDRM_LIBS := $(shell $(PKG_CONFIG) --libs libdrm)
-CPPFLAGS += -Wall -fPIC -Werror -flto $(LIBDRM_CFLAGS) -D_GNU_SOURCE=1
+CPPFLAGS += -Wall -fPIC -Werror -flto $(LIBDRM_CFLAGS)
CXXFLAGS += -std=c++14
-CFLAGS += -std=c99 -D_GNU_SOURCE=1
+CFLAGS += -std=c99
LIBS += -shared -lcutils -lhardware -lsync $(LIBDRM_LIBS)
OBJS = $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source))))
struct mapping *lock_data_[DRV_MAX_PLANES];
- /* Optional additional shared memory region attached to some gralloc buffers. */
+ /* Optional additional shared memory region attached to some gralloc4 buffers. */
int32_t reserved_region_fd_;
uint64_t reserved_region_size_;
void *reserved_region_addr_;
int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size)
{
+ int32_t reserved_region_fd;
std::string reserved_region_name = buffer_name + " reserved region";
-#ifdef __NR_memfd_create
- int32_t reserved_region_fd = memfd_create(reserved_region_name.c_str(), FD_CLOEXEC);
+ reserved_region_fd = memfd_create(reserved_region_name.c_str(), FD_CLOEXEC);
if (reserved_region_fd == -1) {
drv_log("Failed to create reserved region fd: %s.\n", strerror(errno));
return -errno;
}
return reserved_region_fd;
-#else
- drv_log("Failed to create reserved region '%s': memfd_create not available.",
- reserved_region_name.c_str());
- return -1;
-#endif
}
int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor,
num_bytes = ALIGN(num_bytes, sizeof(int));
num_ints = num_bytes - sizeof(native_handle_t) - num_fds;
/*
- * Malloc is used as handles are ultimately destroyed via free in
+ * Malloc is used as handles are ultimetly destroyed via free in
* native_handle_delete().
*/
hnd = static_cast<struct cros_gralloc_handle *>(malloc(num_bytes));
+++ /dev/null
-/*
- * Copyright 2020 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.
- */
-
-cc_binary {
- name: "android.hardware.graphics.allocator@3.0-service.minigbm",
- relative_install_path: "hw",
- vendor: true,
- init_rc: ["android.hardware.graphics.allocator@3.0-service.minigbm.rc"],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "android.hardware.graphics.allocator@3.0",
- "android.hardware.graphics.mapper@3.0",
- "libbase",
- "libcutils",
- "libhidlbase",
- "liblog",
- "libsync",
- "libutils",
- ],
-
- static_libs: [
- "libdrm",
- "libminigbm_gralloc",
- ],
-
- srcs: [
- "CrosGralloc3Allocator.cc",
- "CrosGralloc3AllocatorService.cc",
- "CrosGralloc3Utils.cc",
- ],
-}
-
-cc_library_shared {
- name: "android.hardware.graphics.mapper@3.0-impl.minigbm",
- relative_install_path: "hw",
- vendor: true,
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "android.hardware.graphics.mapper@3.0",
- "libbase",
- "libcutils",
- "libhidlbase",
- "liblog",
- "libsync",
- "libutils",
- ],
-
- static_libs: [
- "libdrm",
- "libminigbm_gralloc",
- ],
-
- srcs: [
- "CrosGralloc3Mapper.cc",
- "CrosGralloc3Utils.cc",
- ],
-}
+++ /dev/null
-/*
- * Copyright 2020 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.
- */
-
-#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
-
-#include "cros_gralloc/cros_gralloc_driver.h"
-
-class CrosGralloc3Allocator : public android::hardware::graphics::allocator::V3_0::IAllocator {
- public:
- CrosGralloc3Allocator();
-
- android::hardware::Return<void> allocate(
- const android::hardware::hidl_vec<uint32_t>& descriptor, uint32_t count,
- allocate_cb hidl_cb) override;
-
- android::hardware::Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
-
- private:
- android::hardware::graphics::mapper::V3_0::Error allocate(
- const android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo&
- description,
- uint32_t* outStride, android::hardware::hidl_handle* outHandle);
-
- std::unique_ptr<cros_gralloc_driver> mDriver;
-};
+++ /dev/null
-/*
- * Copyright 2020 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.
- */
-
-#include "cros_gralloc/gralloc3/CrosGralloc3Mapper.h"
-
-#include <cutils/native_handle.h>
-
-#include "cros_gralloc/gralloc3/CrosGralloc3Utils.h"
-#include "helpers.h"
-
-using android::hardware::hidl_handle;
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::hardware::Void;
-using android::hardware::graphics::common::V1_2::BufferUsage;
-using android::hardware::graphics::common::V1_2::PixelFormat;
-using android::hardware::graphics::mapper::V3_0::Error;
-using android::hardware::graphics::mapper::V3_0::IMapper;
-using android::hardware::graphics::mapper::V3_0::YCbCrLayout;
-
-CrosGralloc3Mapper::CrosGralloc3Mapper() : mDriver(std::make_unique<cros_gralloc_driver>()) {
- if (mDriver->init()) {
- drv_log("Failed to initialize driver.\n");
- mDriver = nullptr;
- }
-}
-
-Return<void> CrosGralloc3Mapper::createDescriptor(const BufferDescriptorInfo& description,
- createDescriptor_cb hidlCb) {
- hidl_vec<uint32_t> descriptor;
-
- if (description.width == 0) {
- drv_log("Failed to createDescriptor. Bad width: %d.\n", description.width);
- hidlCb(Error::BAD_VALUE, descriptor);
- return Void();
- }
-
- if (description.height == 0) {
- drv_log("Failed to createDescriptor. Bad height: %d.\n", description.height);
- hidlCb(Error::BAD_VALUE, descriptor);
- return Void();
- }
-
- if (description.layerCount == 0) {
- drv_log("Failed to createDescriptor. Bad layer count: %d.\n", description.layerCount);
- hidlCb(Error::BAD_VALUE, descriptor);
- return Void();
- }
-
- auto descriptor_opt = encodeBufferDescriptorInfo(description);
- if (!descriptor_opt) {
- drv_log("Failed to createDescriptor. Failed to encodeBufferDescriptorInfo\n");
- hidlCb(Error::BAD_VALUE, descriptor);
- return Void();
- }
-
- descriptor = *descriptor_opt;
- hidlCb(Error::NONE, descriptor);
- return Void();
-}
-
-Return<void> CrosGralloc3Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) {
- if (!mDriver) {
- drv_log("Failed to import buffer. Driver is uninitialized.\n");
- hidlCb(Error::NO_RESOURCES, nullptr);
- return Void();
- }
-
- const native_handle_t* bufferHandle = handle.getNativeHandle();
- if (!bufferHandle || bufferHandle->numFds == 0) {
- drv_log("Failed to importBuffer. Bad handle.\n");
- hidlCb(Error::BAD_BUFFER, nullptr);
- return Void();
- }
-
- native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
- if (!importedBufferHandle) {
- drv_log("Failed to importBuffer. Handle clone failed.\n");
- hidlCb(Error::NO_RESOURCES, nullptr);
- return Void();
- }
-
- int ret = mDriver->retain(importedBufferHandle);
- if (ret) {
- native_handle_close(importedBufferHandle);
- native_handle_delete(importedBufferHandle);
- hidlCb(Error::NO_RESOURCES, nullptr);
- return Void();
- }
-
- hidlCb(Error::NONE, importedBufferHandle);
- return Void();
-}
-
-Return<Error> CrosGralloc3Mapper::freeBuffer(void* rawHandle) {
- if (!mDriver) {
- drv_log("Failed to freeBuffer. Driver is uninitialized.\n");
- return Error::NO_RESOURCES;
- }
-
- native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
- if (!bufferHandle) {
- drv_log("Failed to freeBuffer. Empty handle.\n");
- return Error::BAD_BUFFER;
- }
-
- int ret = mDriver->release(bufferHandle);
- if (ret) {
- drv_log("Failed to freeBuffer.\n");
- return Error::BAD_BUFFER;
- }
-
- native_handle_close(bufferHandle);
- native_handle_delete(bufferHandle);
- return Error::NONE;
-}
-
-Return<Error> CrosGralloc3Mapper::validateBufferSize(void* rawHandle,
- const BufferDescriptorInfo& descriptor,
- uint32_t stride) {
- if (!mDriver) {
- drv_log("Failed to validateBufferSize. Driver is uninitialized.\n");
- return Error::NO_RESOURCES;
- }
-
- native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
- if (!bufferHandle) {
- drv_log("Failed to validateBufferSize. Empty handle.\n");
- return Error::BAD_BUFFER;
- }
-
- cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
- if (!crosHandle) {
- drv_log("Failed to validateBufferSize. Invalid handle.\n");
- return Error::BAD_BUFFER;
- }
-
- PixelFormat crosHandleFormat = static_cast<PixelFormat>(crosHandle->droid_format);
- if (descriptor.format != crosHandleFormat) {
- drv_log("Failed to validateBufferSize. Format mismatch.\n");
- return Error::BAD_BUFFER;
- }
-
- if (descriptor.width != crosHandle->width) {
- drv_log("Failed to validateBufferSize. Width mismatch (%d vs %d).\n", descriptor.width,
- crosHandle->width);
- return Error::BAD_VALUE;
- }
-
- if (descriptor.height != crosHandle->height) {
- drv_log("Failed to validateBufferSize. Height mismatch (%d vs %d).\n", descriptor.height,
- crosHandle->height);
- return Error::BAD_VALUE;
- }
-
- if (stride != crosHandle->pixel_stride) {
- drv_log("Failed to validateBufferSize. Stride mismatch (%d vs %d).\n", stride,
- crosHandle->pixel_stride);
- return Error::BAD_VALUE;
- }
-
- return Error::NONE;
-}
-
-Return<void> CrosGralloc3Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) {
- if (!mDriver) {
- drv_log("Failed to getTransportSize. Driver is uninitialized.\n");
- hidlCb(Error::BAD_BUFFER, 0, 0);
- return Void();
- }
-
- native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
- if (!bufferHandle) {
- drv_log("Failed to getTransportSize. Bad handle.\n");
- hidlCb(Error::BAD_BUFFER, 0, 0);
- return Void();
- }
-
- // No local process data is currently stored on the native handle.
- hidlCb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
- return Void();
-}
-
-Return<void> CrosGralloc3Mapper::lock(void* rawHandle, uint64_t cpuUsage, const Rect& accessRegion,
- const hidl_handle& acquireFence, lock_cb hidlCb) {
- if (!mDriver) {
- drv_log("Failed to lock. Driver is uninitialized.\n");
- hidlCb(Error::NO_RESOURCES, nullptr, 0, 0);
- return Void();
- }
-
- buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
- if (!bufferHandle) {
- drv_log("Failed to lock. Empty handle.\n");
- hidlCb(Error::BAD_BUFFER, nullptr, 0, 0);
- return Void();
- }
-
- cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
- if (crosHandle == nullptr) {
- drv_log("Failed to lock. Invalid handle.\n");
- hidlCb(Error::BAD_BUFFER, nullptr, 0, 0);
- return Void();
- }
-
- LockResult result = lockInternal(crosHandle, cpuUsage, accessRegion, acquireFence);
- if (result.error != Error::NONE) {
- drv_log("Failed to lock. Failed to lockInternal.\n");
- hidlCb(result.error, nullptr, 0, 0);
- return Void();
- }
-
- int32_t bytesPerPixel = drv_bytes_per_pixel_from_format(crosHandle->format, 0);
- int32_t bytesPerStride = static_cast<int32_t>(crosHandle->strides[0]);
-
- hidlCb(Error::NONE, result.mapped[0], bytesPerPixel, bytesPerStride);
- return Void();
-}
-
-Return<void> CrosGralloc3Mapper::lockYCbCr(void* rawHandle, uint64_t cpuUsage,
- const Rect& accessRegion,
- const android::hardware::hidl_handle& acquireFence,
- lockYCbCr_cb hidlCb) {
- YCbCrLayout ycbcr = {};
-
- if (!mDriver) {
- drv_log("Failed to lock. Driver is uninitialized.\n");
- hidlCb(Error::NO_RESOURCES, ycbcr);
- return Void();
- }
-
- buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
- if (!bufferHandle) {
- drv_log("Failed to lockYCbCr. Empty handle.\n");
- hidlCb(Error::BAD_BUFFER, ycbcr);
- return Void();
- }
-
- cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
- if (crosHandle == nullptr) {
- drv_log("Failed to lockYCbCr. Invalid handle.\n");
- hidlCb(Error::BAD_BUFFER, ycbcr);
- return Void();
- }
-
- LockResult result = lockInternal(crosHandle, cpuUsage, accessRegion, acquireFence);
- if (result.error != Error::NONE) {
- drv_log("Failed to lockYCbCr. Failed to lockInternal.\n");
- hidlCb(result.error, ycbcr);
- return Void();
- }
-
- switch (crosHandle->format) {
- case DRM_FORMAT_NV12: {
- ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
- ycbcr.cb = result.mapped[0] + crosHandle->offsets[1];
- ycbcr.cr = result.mapped[0] + crosHandle->offsets[1] + 1;
- ycbcr.yStride = crosHandle->strides[0];
- ycbcr.cStride = crosHandle->strides[1];
- ycbcr.chromaStep = 2;
- break;
- }
- case DRM_FORMAT_NV21: {
- ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
- ycbcr.cb = result.mapped[0] + crosHandle->offsets[1] + 1;
- ycbcr.cr = result.mapped[0] + crosHandle->offsets[1];
- ycbcr.yStride = crosHandle->strides[0];
- ycbcr.cStride = crosHandle->strides[1];
- ycbcr.chromaStep = 2;
- break;
- }
- case DRM_FORMAT_YVU420: {
- ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
- ycbcr.cb = result.mapped[0] + crosHandle->offsets[1];
- ycbcr.cr = result.mapped[0] + crosHandle->offsets[2];
- ycbcr.yStride = crosHandle->strides[0];
- ycbcr.cStride = crosHandle->strides[1];
- ycbcr.chromaStep = 1;
- break;
- }
- case DRM_FORMAT_YVU420_ANDROID: {
- ycbcr.y = result.mapped[0] + crosHandle->offsets[0];
- ycbcr.cb = result.mapped[0] + crosHandle->offsets[2];
- ycbcr.cr = result.mapped[0] + crosHandle->offsets[1];
- ycbcr.yStride = crosHandle->strides[0];
- ycbcr.cStride = crosHandle->strides[1];
- ycbcr.chromaStep = 1;
- break;
- }
- default: {
- std::string format = getDrmFormatString(crosHandle->format);
- drv_log("Failed to lockYCbCr. Unhandled format: %s\n", format.c_str());
- hidlCb(Error::BAD_BUFFER, ycbcr);
- return Void();
- }
- }
-
- hidlCb(Error::NONE, ycbcr);
- return Void();
-}
-
-CrosGralloc3Mapper::LockResult CrosGralloc3Mapper::lockInternal(
- cros_gralloc_handle_t crosHandle, uint64_t cpuUsage, const Rect& region,
- const android::hardware::hidl_handle& acquireFence) {
- LockResult result = {};
-
- if (!mDriver) {
- drv_log("Failed to lock. Driver is uninitialized.\n");
- result.error = Error::NO_RESOURCES;
- return result;
- }
-
- if (cpuUsage == 0) {
- drv_log("Failed to lock. Bad cpu usage: %" PRIu64 ".\n", cpuUsage);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- uint32_t mapUsage = 0;
- int ret = convertToMapUsage(cpuUsage, &mapUsage);
- if (ret) {
- drv_log("Failed to lock. Convert usage failed.\n");
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- if (region.left < 0) {
- drv_log("Failed to lock. Invalid region: negative left value %d.\n", region.left);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- if (region.top < 0) {
- drv_log("Failed to lock. Invalid region: negative top value %d.\n", region.top);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- if (region.width < 0) {
- drv_log("Failed to lock. Invalid region: negative width value %d.\n", region.width);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- if (region.height < 0) {
- drv_log("Failed to lock. Invalid region: negative height value %d.\n", region.height);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- if (region.width > crosHandle->width) {
- drv_log("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).\n",
- region.width, crosHandle->width);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- if (region.height > crosHandle->height) {
- drv_log("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).\n",
- region.height, crosHandle->height);
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- struct rectangle rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
- static_cast<uint32_t>(region.width),
- static_cast<uint32_t>(region.height)};
-
- // An access region of all zeros means the entire buffer.
- if (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0) {
- rect.width = crosHandle->width;
- rect.height = crosHandle->height;
- }
-
- int acquireFenceFd = -1;
- ret = convertToFenceFd(acquireFence, &acquireFenceFd);
- if (ret) {
- drv_log("Failed to lock. Bad acquire fence.\n");
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(crosHandle);
- ret = mDriver->lock(bufferHandle, acquireFenceFd, false, &rect, mapUsage, result.mapped);
- if (ret) {
- result.error = Error::BAD_VALUE;
- return result;
- }
-
- result.error = Error::NONE;
- return result;
-}
-
-Return<void> CrosGralloc3Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
- if (!mDriver) {
- drv_log("Failed to unlock. Driver is uninitialized.\n");
- hidlCb(Error::BAD_BUFFER, nullptr);
- return Void();
- }
-
- buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
- if (!bufferHandle) {
- drv_log("Failed to unlock. Empty handle.\n");
- hidlCb(Error::BAD_BUFFER, nullptr);
- return Void();
- }
-
- int releaseFenceFd = -1;
- int ret = mDriver->unlock(bufferHandle, &releaseFenceFd);
- if (ret) {
- drv_log("Failed to unlock.\n");
- hidlCb(Error::BAD_BUFFER, nullptr);
- return Void();
- }
-
- hidl_handle releaseFenceHandle;
- ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
- if (ret) {
- drv_log("Failed to unlock. Failed to convert release fence to handle.\n");
- hidlCb(Error::BAD_BUFFER, nullptr);
- return Void();
- }
-
- hidlCb(Error::NONE, releaseFenceHandle);
- return Void();
-}
-
-Return<void> CrosGralloc3Mapper::isSupported(const BufferDescriptorInfo& descriptor,
- isSupported_cb hidlCb) {
- if (!mDriver) {
- drv_log("Failed to isSupported. Driver is uninitialized.\n");
- hidlCb(Error::BAD_VALUE, false);
- return Void();
- }
-
- struct cros_gralloc_buffer_descriptor crosDescriptor;
- if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
- hidlCb(Error::NONE, false);
- return Void();
- }
-
- bool supported = mDriver->is_supported(&crosDescriptor);
- if (!supported) {
- crosDescriptor.use_flags &= ~BO_USE_SCANOUT;
- supported = mDriver->is_supported(&crosDescriptor);
- }
-
- hidlCb(Error::NONE, supported);
- return Void();
-}
-
-int CrosGralloc3Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage,
- uint32_t* outDrmFormat) {
- uint32_t drmFormat;
- if (convertToDrmFormat(pixelFormat, &drmFormat)) {
- std::string pixelFormatString = getPixelFormatString(pixelFormat);
- drv_log("Failed to getResolvedDrmFormat. Failed to convert format %s\n",
- pixelFormatString.c_str());
- return -1;
- }
-
- uint64_t usage;
- if (convertToBufferUsage(bufferUsage, &usage)) {
- std::string usageString = getUsageString(bufferUsage);
- drv_log("Failed to getResolvedDrmFormat. Failed to convert usage %s\n",
- usageString.c_str());
- return -1;
- }
-
- uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage);
- if (resolvedDrmFormat == DRM_FORMAT_INVALID) {
- std::string drmFormatString = getDrmFormatString(drmFormat);
- drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n",
- drmFormatString.c_str());
- return -1;
- }
-
- *outDrmFormat = resolvedDrmFormat;
-
- return 0;
-}
-
-android::hardware::graphics::mapper::V3_0::IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
- return static_cast<android::hardware::graphics::mapper::V3_0::IMapper*>(new CrosGralloc3Mapper);
-}
+++ /dev/null
-/*
- * Copyright 2020 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.
- */
-
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
-
-#include <optional>
-
-#include "cros_gralloc/cros_gralloc_driver.h"
-#include "cros_gralloc/cros_gralloc_handle.h"
-
-class CrosGralloc3Mapper : public android::hardware::graphics::mapper::V3_0::IMapper {
- public:
- CrosGralloc3Mapper();
-
- android::hardware::Return<void> createDescriptor(const BufferDescriptorInfo& description,
- createDescriptor_cb hidlCb) override;
-
- android::hardware::Return<void> importBuffer(const android::hardware::hidl_handle& rawHandle,
- importBuffer_cb hidlCb) override;
-
- android::hardware::Return<android::hardware::graphics::mapper::V3_0::Error> freeBuffer(
- void* rawHandle) override;
-
- android::hardware::Return<android::hardware::graphics::mapper::V3_0::Error> validateBufferSize(
- void* rawHandle, const BufferDescriptorInfo& descriptor, uint32_t stride) override;
-
- android::hardware::Return<void> getTransportSize(void* rawHandle,
- getTransportSize_cb hidlCb) override;
-
- android::hardware::Return<void> lock(void* rawHandle, uint64_t cpuUsage,
- const Rect& accessRegion,
- const android::hardware::hidl_handle& acquireFence,
- lock_cb hidlCb) override;
-
- android::hardware::Return<void> lockYCbCr(void* rawHandle, uint64_t cpuUsage,
- const Rect& accessRegion,
- const android::hardware::hidl_handle& acquireFence,
- lockYCbCr_cb _hidl_cb) override;
-
- android::hardware::Return<void> unlock(void* rawHandle, unlock_cb hidlCb) override;
-
- android::hardware::Return<void> isSupported(const BufferDescriptorInfo& descriptor,
- isSupported_cb hidlCb) override;
-
- private:
- int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat,
- uint64_t bufferUsage, uint32_t* outDrmFormat);
-
- struct LockResult {
- android::hardware::graphics::mapper::V3_0::Error error;
-
- uint8_t* mapped[DRV_MAX_PLANES];
- };
- LockResult lockInternal(cros_gralloc_handle_t crosHandle, uint64_t cpuUsage,
- const Rect& accessRegion,
- const android::hardware::hidl_handle& acquireFence);
-
- std::unique_ptr<cros_gralloc_driver> mDriver;
-};
-
-extern "C" android::hardware::graphics::mapper::V3_0::IMapper* HIDL_FETCH_IMapper(const char* name);
+++ /dev/null
-#
-# Copyright 2020 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.
-#
-
-service vendor.graphics.allocator-3-0 /vendor/bin/hw/android.hardware.graphics.allocator@3.0-service.minigbm
- interface android.hardware.graphics.allocator@3.0::IAllocator default
- class hal animation
- user system
- group graphics drmrpc
- capabilities SYS_NICE
- onrestart restart surfaceflinger
- writepid /dev/cpuset/system-background/tasks
# Copyright 2020 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.
-
+#
# This directory is formatted to match the format of the interfaces implemented.
BasedOnStyle: Google
--- /dev/null
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_binary {
+ name: "android.hardware.graphics.allocator@4.0-service.minigbm",
+ relative_install_path: "hw",
+ vendor: true,
+ init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm.rc"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "android.hardware.graphics.allocator@4.0",
+ "android.hardware.graphics.mapper@4.0",
+ "libbase",
+ "libcutils",
+ "libgralloctypes",
+ "libhidlbase",
+ "liblog",
+ "libsync",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libdrm",
+ "libminigbm_cros_gralloc",
+ ],
+
+ srcs: [
+ "CrosGralloc4Allocator.cc",
+ "CrosGralloc4AllocatorService.cc",
+ "CrosGralloc4Utils.cc",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.graphics.mapper@4.0-impl.minigbm",
+ relative_install_path: "hw",
+ vendor: true,
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "android.hardware.graphics.mapper@4.0",
+ "libbase",
+ "libcutils",
+ "libgralloctypes",
+ "libhidlbase",
+ "liblog",
+ "libsync",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libdrm",
+ "libminigbm_cros_gralloc",
+ ],
+
+ srcs: [
+ "CrosGralloc4Mapper.cc",
+ "CrosGralloc4Utils.cc",
+ ],
+}
* found in the LICENSE file.
*/
-#include "cros_gralloc/gralloc3/CrosGralloc3Allocator.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Allocator.h"
-#include <optional>
-
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <gralloctypes/Gralloc4.h>
#include "cros_gralloc/cros_gralloc_helpers.h"
-#include "cros_gralloc/gralloc3/CrosGralloc3Utils.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
using android::hardware::hidl_handle;
using android::hardware::hidl_vec;
using android::hardware::Void;
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::common::V1_2::PixelFormat;
-using android::hardware::graphics::mapper::V3_0::Error;
+using android::hardware::graphics::mapper::V4_0::Error;
using BufferDescriptorInfo =
- android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo;
+ android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
-CrosGralloc3Allocator::CrosGralloc3Allocator() : mDriver(std::make_unique<cros_gralloc_driver>()) {
+CrosGralloc4Allocator::CrosGralloc4Allocator() : mDriver(std::make_unique<cros_gralloc_driver>()) {
if (mDriver->init()) {
drv_log("Failed to initialize driver.\n");
mDriver = nullptr;
}
}
-Error CrosGralloc3Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
+Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
hidl_handle* outHandle) {
if (!mDriver) {
drv_log("Failed to allocate. Driver is uninitialized.\n");
return Error::NONE;
}
-Return<void> CrosGralloc3Allocator::allocate(const hidl_vec<uint32_t>& encoded, uint32_t count,
+Return<void> CrosGralloc4Allocator::allocate(const hidl_vec<uint8_t>& descriptor, uint32_t count,
allocate_cb hidlCb) {
hidl_vec<hidl_handle> handles;
return Void();
}
- auto descriptor_opt = decodeBufferDescriptorInfo(encoded);
- if (!descriptor_opt) {
- drv_log("Failed to allocate. Failed to decode buffer descriptor.\n");
+ BufferDescriptorInfo description;
+
+ int ret = android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description);
+ if (ret) {
+ drv_log("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret);
hidlCb(Error::BAD_DESCRIPTOR, 0, handles);
return Void();
}
- BufferDescriptorInfo descriptor = *descriptor_opt;
-
handles.resize(count);
uint32_t stride = 0;
for (int i = 0; i < handles.size(); i++) {
- Error err = allocate(descriptor, &stride, &(handles[i]));
+ Error err = allocate(description, &stride, &(handles[i]));
if (err != Error::NONE) {
for (int j = 0; j < i; j++) {
mDriver->release(handles[j].getNativeHandle());
return Void();
}
-
-Return<void> CrosGralloc3Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
- hidl_cb("CrosGralloc3Allocator::dumpDebugInfo unimplemented.");
- return Void();
-}
--- /dev/null
+/*
+ * Copyright 2020 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.
+ */
+
+#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+
+#include "cros_gralloc/cros_gralloc_driver.h"
+
+class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_0::IAllocator {
+ public:
+ CrosGralloc4Allocator();
+
+ android::hardware::Return<void> allocate(const android::hardware::hidl_vec<uint8_t>& descriptor,
+ uint32_t count, allocate_cb hidl_cb) override;
+
+ private:
+ android::hardware::graphics::mapper::V4_0::Error allocate(
+ const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo&
+ description,
+ uint32_t* outStride, android::hardware::hidl_handle* outHandle);
+
+ std::unique_ptr<cros_gralloc_driver> mDriver;
+};
#include <hidl/LegacySupport.h>
-#include "cros_gralloc/gralloc3/CrosGralloc3Allocator.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Allocator.h"
using android::sp;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
-using android::hardware::graphics::allocator::V3_0::IAllocator;
+using android::hardware::graphics::allocator::V4_0::IAllocator;
int main(int, char**) {
- sp<IAllocator> allocator = new CrosGralloc3Allocator();
+ sp<IAllocator> allocator = new CrosGralloc4Allocator();
configureRpcThreadpool(4, true /* callerWillJoin */);
if (allocator->registerAsService() != android::NO_ERROR) {
- ALOGE("failed to register graphics IAllocator 3.0 service");
+ ALOGE("failed to register graphics IAllocator 4.0 service");
return -EINVAL;
}
- ALOGI("graphics IAllocator 3.0 service is initialized");
+ ALOGI("graphics IAllocator 4.0 service is initialized");
android::hardware::joinRpcThreadpool();
- ALOGI("graphics IAllocator 3.0 service is terminating");
+ ALOGI("graphics IAllocator 4.0 service is terminating");
return 0;
}
--- /dev/null
+/*
+ * Copyright 2020 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.
+ */
+
+#include "cros_gralloc/gralloc4/CrosGralloc4Mapper.h"
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayout.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <cutils/native_handle.h>
+#include <gralloctypes/Gralloc4.h>
+
+#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
+#include "helpers.h"
+
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::Rect;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::graphics::common::V1_2::BufferUsage;
+using android::hardware::graphics::common::V1_2::PixelFormat;
+using android::hardware::graphics::mapper::V4_0::Error;
+using android::hardware::graphics::mapper::V4_0::IMapper;
+
+CrosGralloc4Mapper::CrosGralloc4Mapper() : mDriver(std::make_unique<cros_gralloc_driver>()) {
+ if (mDriver->init()) {
+ drv_log("Failed to initialize driver.\n");
+ mDriver = nullptr;
+ }
+}
+
+Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& description,
+ createDescriptor_cb hidlCb) {
+ hidl_vec<uint8_t> descriptor;
+
+ if (description.width == 0) {
+ drv_log("Failed to createDescriptor. Bad width: %d.\n", description.width);
+ hidlCb(Error::BAD_VALUE, descriptor);
+ return Void();
+ }
+
+ if (description.height == 0) {
+ drv_log("Failed to createDescriptor. Bad height: %d.\n", description.height);
+ hidlCb(Error::BAD_VALUE, descriptor);
+ return Void();
+ }
+
+ if (description.layerCount == 0) {
+ drv_log("Failed to createDescriptor. Bad layer count: %d.\n", description.layerCount);
+ hidlCb(Error::BAD_VALUE, descriptor);
+ return Void();
+ }
+
+ int ret = android::gralloc4::encodeBufferDescriptorInfo(description, &descriptor);
+ if (ret) {
+ drv_log("Failed to createDescriptor. Failed to encode: %d.\n", ret);
+ hidlCb(Error::BAD_VALUE, descriptor);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, descriptor);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to import buffer. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ const native_handle_t* bufferHandle = handle.getNativeHandle();
+ if (!bufferHandle || bufferHandle->numFds == 0) {
+ drv_log("Failed to importBuffer. Bad handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
+ if (!importedBufferHandle) {
+ drv_log("Failed to importBuffer. Handle clone failed.\n");
+ hidlCb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ int ret = mDriver->retain(importedBufferHandle);
+ if (ret) {
+ native_handle_close(importedBufferHandle);
+ native_handle_delete(importedBufferHandle);
+ hidlCb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, importedBufferHandle);
+ return Void();
+}
+
+Return<Error> CrosGralloc4Mapper::freeBuffer(void* rawHandle) {
+ if (!mDriver) {
+ drv_log("Failed to freeBuffer. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to freeBuffer. Empty handle.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ int ret = mDriver->release(bufferHandle);
+ if (ret) {
+ return Error::BAD_BUFFER;
+ }
+
+ native_handle_close(bufferHandle);
+ native_handle_delete(bufferHandle);
+ return Error::NONE;
+}
+
+Return<Error> CrosGralloc4Mapper::validateBufferSize(void* rawHandle,
+ const BufferDescriptorInfo& descriptor,
+ uint32_t stride) {
+ if (!mDriver) {
+ drv_log("Failed to validateBufferSize. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to validateBufferSize. Empty handle.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ drv_log("Failed to validateBufferSize. Invalid handle.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ PixelFormat crosHandleFormat = static_cast<PixelFormat>(crosHandle->droid_format);
+ if (descriptor.format != crosHandleFormat) {
+ drv_log("Failed to validateBufferSize. Format mismatch.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ if (descriptor.width != crosHandle->width) {
+ drv_log("Failed to validateBufferSize. Width mismatch (%d vs %d).\n", descriptor.width,
+ crosHandle->width);
+ return Error::BAD_VALUE;
+ }
+
+ if (descriptor.height != crosHandle->height) {
+ drv_log("Failed to validateBufferSize. Height mismatch (%d vs %d).\n", descriptor.height,
+ crosHandle->height);
+ return Error::BAD_VALUE;
+ }
+
+ if (stride != crosHandle->pixel_stride) {
+ drv_log("Failed to validateBufferSize. Stride mismatch (%d vs %d).\n", stride,
+ crosHandle->pixel_stride);
+ return Error::BAD_VALUE;
+ }
+
+ return Error::NONE;
+}
+
+Return<void> CrosGralloc4Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to getTransportSize. Driver is uninitialized.\n");
+ hidlCb(Error::BAD_BUFFER, 0, 0);
+ return Void();
+ }
+
+ native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to getTransportSize. Bad handle.\n");
+ hidlCb(Error::BAD_BUFFER, 0, 0);
+ return Void();
+ }
+
+ // No local process data is currently stored on the native handle.
+ hidlCb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const Rect& region,
+ const hidl_handle& acquireFence, lock_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to lock. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawBuffer);
+ if (!bufferHandle) {
+ drv_log("Failed to lock. Empty handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ if (cpuUsage == 0) {
+ drv_log("Failed to lock. Bad cpu usage: %" PRIu64 ".\n", cpuUsage);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ uint32_t mapUsage = 0;
+ int ret = convertToMapUsage(cpuUsage, &mapUsage);
+ if (ret) {
+ drv_log("Failed to lock. Convert usage failed.\n");
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (crosHandle == nullptr) {
+ drv_log("Failed to lock. Invalid handle.\n");
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ if (region.left < 0) {
+ drv_log("Failed to lock. Invalid region: negative left value %d.\n", region.left);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ if (region.top < 0) {
+ drv_log("Failed to lock. Invalid region: negative top value %d.\n", region.top);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ if (region.width < 0) {
+ drv_log("Failed to lock. Invalid region: negative width value %d.\n", region.width);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ if (region.height < 0) {
+ drv_log("Failed to lock. Invalid region: negative height value %d.\n", region.height);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ if (region.width > crosHandle->width) {
+ drv_log("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).\n",
+ region.width, crosHandle->width);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ if (region.height > crosHandle->height) {
+ drv_log("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).\n",
+ region.height, crosHandle->height);
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ struct rectangle rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
+ static_cast<uint32_t>(region.width),
+ static_cast<uint32_t>(region.height)};
+
+ // An access region of all zeros means the entire buffer.
+ if (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0) {
+ rect.width = crosHandle->width;
+ rect.height = crosHandle->height;
+ }
+
+ int acquireFenceFd = -1;
+ ret = convertToFenceFd(acquireFence, &acquireFenceFd);
+ if (ret) {
+ drv_log("Failed to lock. Bad acquire fence.\n");
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ uint8_t* addr[DRV_MAX_PLANES];
+ ret = mDriver->lock(bufferHandle, acquireFenceFd, /*close_acquire_fence=*/false, &rect,
+ mapUsage, addr);
+ if (ret) {
+ hidlCb(Error::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, addr[0]);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to unlock. Driver is uninitialized.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to unlock. Empty handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ int releaseFenceFd = -1;
+ int ret = mDriver->unlock(bufferHandle, &releaseFenceFd);
+ if (ret) {
+ drv_log("Failed to unlock.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ hidl_handle releaseFenceHandle;
+ ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
+ if (ret) {
+ drv_log("Failed to unlock. Failed to convert release fence to handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, releaseFenceHandle);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedBuffer_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to flushLockedBuffer. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to flushLockedBuffer. Empty handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ int releaseFenceFd = -1;
+ int ret = mDriver->flush(bufferHandle, &releaseFenceFd);
+ if (ret) {
+ drv_log("Failed to flushLockedBuffer. Flush failed.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ hidl_handle releaseFenceHandle;
+ ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
+ if (ret) {
+ drv_log("Failed to flushLockedBuffer. Failed to convert release fence to handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, releaseFenceHandle);
+ return Void();
+}
+
+Return<Error> CrosGralloc4Mapper::rereadLockedBuffer(void* rawHandle) {
+ if (!mDriver) {
+ drv_log("Failed to rereadLockedBuffer. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to rereadLockedBuffer. Empty handle.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ int ret = mDriver->invalidate(bufferHandle);
+ if (ret) {
+ drv_log("Failed to rereadLockedBuffer. Failed to invalidate.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ return Error::NONE;
+}
+
+Return<void> CrosGralloc4Mapper::isSupported(const BufferDescriptorInfo& descriptor,
+ isSupported_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to isSupported. Driver is uninitialized.\n");
+ hidlCb(Error::BAD_VALUE, false);
+ return Void();
+ }
+
+ struct cros_gralloc_buffer_descriptor crosDescriptor;
+ if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
+ hidlCb(Error::NONE, false);
+ return Void();
+ }
+
+ bool supported = mDriver->is_supported(&crosDescriptor);
+ if (!supported) {
+ crosDescriptor.use_flags &= ~BO_USE_SCANOUT;
+ supported = mDriver->is_supported(&crosDescriptor);
+ }
+
+ hidlCb(Error::NONE, supported);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metadataType,
+ get_cb hidlCb) {
+ hidl_vec<uint8_t> encodedMetadata;
+
+ if (!mDriver) {
+ drv_log("Failed to get. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, encodedMetadata);
+ return Void();
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to get. Empty handle.\n");
+ hidlCb(Error::BAD_BUFFER, encodedMetadata);
+ return Void();
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ drv_log("Failed to get. Invalid handle.\n");
+ hidlCb(Error::BAD_BUFFER, encodedMetadata);
+ return Void();
+ }
+
+ get(crosHandle, metadataType, hidlCb);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle,
+ const MetadataType& metadataType, get_cb hidlCb) {
+ hidl_vec<uint8_t> encodedMetadata;
+
+ if (!mDriver) {
+ drv_log("Failed to get. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, encodedMetadata);
+ return Void();
+ }
+
+ if (!crosHandle) {
+ drv_log("Failed to get. Invalid handle.\n");
+ hidlCb(Error::BAD_BUFFER, encodedMetadata);
+ return Void();
+ }
+
+ android::status_t status = android::NO_ERROR;
+ if (metadataType == android::gralloc4::MetadataType_BufferId) {
+ status = android::gralloc4::encodeBufferId(crosHandle->id, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Name) {
+ const char* name = (const char*)(&crosHandle->base.data[crosHandle->name_offset]);
+ status = android::gralloc4::encodeName(name, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Width) {
+ status = android::gralloc4::encodeWidth(crosHandle->width, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Height) {
+ status = android::gralloc4::encodeHeight(crosHandle->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);
+ status = android::gralloc4::encodePixelFormatRequested(pixelFormat, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
+ status = android::gralloc4::encodePixelFormatFourCC(crosHandle->format, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_PixelFormatModifier) {
+ status = android::gralloc4::encodePixelFormatModifier(crosHandle->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);
+ } else if (metadataType == android::gralloc4::MetadataType_AllocationSize) {
+ status = android::gralloc4::encodeAllocationSize(crosHandle->total_size, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
+ uint64_t hasProtectedContent = crosHandle->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,
+ &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Interlaced) {
+ status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None,
+ &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) {
+ status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None,
+ &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_PlaneLayouts) {
+ std::vector<PlaneLayout> planeLayouts;
+ getPlaneLayouts(crosHandle->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.heightInSamples = crosHandle->height;
+ }
+
+ status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Crop) {
+ std::vector<aidl::android::hardware::graphics::common::Rect> crops;
+ for (size_t plane = 0; plane < crosHandle->num_planes; plane++) {
+ aidl::android::hardware::graphics::common::Rect crop;
+ crop.left = 0;
+ crop.top = 0;
+ crop.right = crosHandle->width;
+ crop.bottom = crosHandle->height;
+ crops.push_back(crop);
+ }
+
+ status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
+ status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
+ status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
+ status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
+ status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
+ status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
+ } else {
+ hidlCb(Error::UNSUPPORTED, encodedMetadata);
+ return Void();
+ }
+
+ if (status != android::NO_ERROR) {
+ hidlCb(Error::NO_RESOURCES, encodedMetadata);
+ drv_log("Failed to get. Failed to encode metadata.\n");
+ return Void();
+ }
+
+ hidlCb(Error::NONE, encodedMetadata);
+ return Void();
+}
+
+Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType,
+ const hidl_vec<uint8_t>& /*metadata*/) {
+ if (!mDriver) {
+ drv_log("Failed to set. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to set. Empty handle.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ drv_log("Failed to set. Invalid handle.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ if (metadataType == android::gralloc4::MetadataType_BufferId) {
+ return Error::BAD_VALUE;
+ } else if (metadataType == android::gralloc4::MetadataType_Name) {
+ return Error::BAD_VALUE;
+ } else if (metadataType == android::gralloc4::MetadataType_Width) {
+ return Error::BAD_VALUE;
+ } else if (metadataType == android::gralloc4::MetadataType_Height) {
+ return Error::BAD_VALUE;
+ } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
+ return Error::BAD_VALUE;
+ } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
+ return Error::BAD_VALUE;
+ } else if (metadataType == android::gralloc4::MetadataType_Usage) {
+ return Error::BAD_VALUE;
+ }
+
+ return Error::UNSUPPORTED;
+}
+
+int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage,
+ uint32_t* outDrmFormat) {
+ uint32_t drmFormat;
+ if (convertToDrmFormat(pixelFormat, &drmFormat)) {
+ std::string pixelFormatString = getPixelFormatString(pixelFormat);
+ drv_log("Failed to getResolvedDrmFormat. Failed to convert format %s\n",
+ pixelFormatString.c_str());
+ return -1;
+ }
+
+ uint64_t usage;
+ if (convertToBufferUsage(bufferUsage, &usage)) {
+ std::string usageString = getUsageString(bufferUsage);
+ drv_log("Failed to getResolvedDrmFormat. Failed to convert usage %s\n",
+ usageString.c_str());
+ return -1;
+ }
+
+ uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage);
+ if (resolvedDrmFormat == DRM_FORMAT_INVALID) {
+ std::string drmFormatString = getDrmFormatString(drmFormat);
+ drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n",
+ drmFormatString.c_str());
+ return -1;
+ }
+
+ *outDrmFormat = resolvedDrmFormat;
+
+ return 0;
+}
+
+Return<void> CrosGralloc4Mapper::getFromBufferDescriptorInfo(
+ const BufferDescriptorInfo& descriptor, const MetadataType& metadataType,
+ getFromBufferDescriptorInfo_cb hidlCb) {
+ hidl_vec<uint8_t> encodedMetadata;
+
+ if (!mDriver) {
+ drv_log("Failed to getFromBufferDescriptorInfo. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, encodedMetadata);
+ return Void();
+ }
+
+ android::status_t status = android::NO_ERROR;
+ if (metadataType == android::gralloc4::MetadataType_Name) {
+ status = android::gralloc4::encodeName(descriptor.name, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Width) {
+ status = android::gralloc4::encodeWidth(descriptor.width, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Height) {
+ status = android::gralloc4::encodeHeight(descriptor.height, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
+ status = android::gralloc4::encodeLayerCount(1, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
+ status = android::gralloc4::encodePixelFormatRequested(descriptor.format, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
+ uint32_t drmFormat;
+ if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) {
+ hidlCb(Error::BAD_VALUE, encodedMetadata);
+ return Void();
+ }
+ status = android::gralloc4::encodePixelFormatFourCC(drmFormat, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Usage) {
+ status = android::gralloc4::encodeUsage(descriptor.usage, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
+ uint64_t hasProtectedContent = descriptor.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,
+ &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Interlaced) {
+ status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None,
+ &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) {
+ status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None,
+ &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Crop) {
+ uint32_t drmFormat;
+ if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) {
+ hidlCb(Error::BAD_VALUE, encodedMetadata);
+ return Void();
+ }
+
+ size_t numPlanes = drv_num_planes_from_format(drmFormat);
+
+ std::vector<aidl::android::hardware::graphics::common::Rect> crops;
+ for (size_t plane = 0; plane < numPlanes; plane++) {
+ aidl::android::hardware::graphics::common::Rect crop;
+ crop.left = 0;
+ crop.top = 0;
+ crop.right = descriptor.width;
+ crop.bottom = descriptor.height;
+ crops.push_back(crop);
+ }
+ status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
+ status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
+ status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
+ status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
+ status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata);
+ } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
+ status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
+ } else {
+ hidlCb(Error::UNSUPPORTED, encodedMetadata);
+ return Void();
+ }
+
+ if (status != android::NO_ERROR) {
+ hidlCb(Error::NO_RESOURCES, encodedMetadata);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, encodedMetadata);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidlCb) {
+ hidl_vec<MetadataTypeDescription> supported;
+
+ if (!mDriver) {
+ drv_log("Failed to listSupportedMetadataTypes. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, supported);
+ return Void();
+ }
+
+ supported = hidl_vec<IMapper::MetadataTypeDescription>({
+ {
+ android::gralloc4::MetadataType_BufferId,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Name,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Width,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Height,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_LayerCount,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_PixelFormatRequested,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_PixelFormatFourCC,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_PixelFormatModifier,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Usage,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_AllocationSize,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_ProtectedContent,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Compression,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Interlaced,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_ChromaSiting,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_PlaneLayouts,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Dataspace,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_BlendMode,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Smpte2086,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Cta861_3,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ {
+ android::gralloc4::MetadataType_Smpte2094_40,
+ "",
+ /*isGettable=*/true,
+ /*isSettable=*/false,
+ },
+ });
+
+ hidlCb(Error::NONE, supported);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlCb) {
+ BufferDump bufferDump;
+
+ if (!mDriver) {
+ drv_log("Failed to dumpBuffer. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, bufferDump);
+ return Void();
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to dumpBuffer. Empty handle.\n");
+ hidlCb(Error::BAD_BUFFER, bufferDump);
+ return Void();
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ drv_log("Failed to dumpBuffer. Invalid handle.\n");
+ hidlCb(Error::BAD_BUFFER, bufferDump);
+ return Void();
+ }
+
+ return dumpBuffer(crosHandle, hidlCb);
+}
+
+Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle,
+ dumpBuffer_cb hidlCb) {
+ BufferDump bufferDump;
+
+ if (!mDriver) {
+ drv_log("Failed to dumpBuffer. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, bufferDump);
+ 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;
+ auto metadata_get_callback = [&](Error, hidl_vec<uint8_t> metadata) {
+ MetadataDump metadataDump;
+ metadataDump.metadataType = metadataType;
+ metadataDump.metadata = metadata;
+ metadataDumps.push_back(metadataDump);
+ };
+
+ metadataType = android::gralloc4::MetadataType_BufferId;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Name;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Width;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Height;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_LayerCount;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_PixelFormatRequested;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_PixelFormatFourCC;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_PixelFormatModifier;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Usage;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_AllocationSize;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_ProtectedContent;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Compression;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Interlaced;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_ChromaSiting;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_PlaneLayouts;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_Dataspace;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ metadataType = android::gralloc4::MetadataType_BlendMode;
+ get(crosHandle, metadataType, metadata_get_callback);
+
+ bufferDump.metadataDump = metadataDumps;
+ hidlCb(Error::NONE, bufferDump);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) {
+ std::vector<BufferDump> bufferDumps;
+
+ if (!mDriver) {
+ drv_log("Failed to dumpBuffers. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, bufferDumps);
+ return Void();
+ }
+
+ 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);
+ };
+ mDriver->for_each_handle(handleCallback);
+
+ hidlCb(error, bufferDumps);
+ return Void();
+}
+
+Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) {
+ if (!mDriver) {
+ drv_log("Failed to getReservedRegion. Driver is uninitialized.\n");
+ hidlCb(Error::NO_RESOURCES, nullptr, 0);
+ return Void();
+ }
+
+ buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
+ if (!bufferHandle) {
+ drv_log("Failed to getReservedRegion. Empty handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr, 0);
+ return Void();
+ }
+
+ cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
+ if (!crosHandle) {
+ drv_log("Failed to getReservedRegion. Invalid handle.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr, 0);
+ return Void();
+ }
+
+ void* reservedRegionAddr = nullptr;
+ uint64_t reservedRegionSize = 0;
+ int ret = mDriver->get_reserved_region(bufferHandle, &reservedRegionAddr, &reservedRegionSize);
+ if (ret) {
+ drv_log("Failed to getReservedRegion.\n");
+ hidlCb(Error::BAD_BUFFER, nullptr, 0);
+ return Void();
+ }
+
+ hidlCb(Error::NONE, reservedRegionAddr, reservedRegionSize);
+ return Void();
+}
+
+android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
+ return static_cast<android::hardware::graphics::mapper::V4_0::IMapper*>(new CrosGralloc4Mapper);
+}
--- /dev/null
+/*
+ * Copyright 2020 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.
+ */
+
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+
+#include "cros_gralloc/cros_gralloc_driver.h"
+#include "cros_gralloc/cros_gralloc_handle.h"
+
+class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMapper {
+ public:
+ CrosGralloc4Mapper();
+
+ android::hardware::Return<void> createDescriptor(const BufferDescriptorInfo& description,
+ createDescriptor_cb hidlCb) override;
+
+ android::hardware::Return<void> importBuffer(const android::hardware::hidl_handle& rawHandle,
+ importBuffer_cb hidlCb) override;
+
+ android::hardware::Return<android::hardware::graphics::mapper::V4_0::Error> freeBuffer(
+ void* rawHandle) override;
+
+ android::hardware::Return<android::hardware::graphics::mapper::V4_0::Error> validateBufferSize(
+ void* rawHandle, const BufferDescriptorInfo& descriptor, uint32_t stride) override;
+
+ android::hardware::Return<void> getTransportSize(void* rawHandle,
+ getTransportSize_cb hidlCb) override;
+
+ android::hardware::Return<void> lock(void* rawHandle, uint64_t cpuUsage,
+ const Rect& accessRegion,
+ const android::hardware::hidl_handle& acquireFence,
+ lock_cb hidlCb) override;
+
+ android::hardware::Return<void> unlock(void* rawHandle, unlock_cb hidlCb) override;
+
+ android::hardware::Return<void> flushLockedBuffer(void* rawHandle,
+ flushLockedBuffer_cb hidlCb) override;
+
+ android::hardware::Return<android::hardware::graphics::mapper::V4_0::Error> rereadLockedBuffer(
+ void* rawHandle) override;
+
+ android::hardware::Return<void> isSupported(const BufferDescriptorInfo& descriptor,
+ isSupported_cb hidlCb) override;
+
+ android::hardware::Return<void> get(void* rawHandle, const MetadataType& metadataType,
+ get_cb hidlCb) override;
+
+ android::hardware::Return<android::hardware::graphics::mapper::V4_0::Error> set(
+ void* rawHandle, const MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& metadata) override;
+
+ android::hardware::Return<void> getFromBufferDescriptorInfo(
+ const BufferDescriptorInfo& descriptor, const MetadataType& metadataType,
+ getFromBufferDescriptorInfo_cb hidlCb) override;
+
+ android::hardware::Return<void> listSupportedMetadataTypes(
+ listSupportedMetadataTypes_cb hidlCb) override;
+
+ android::hardware::Return<void> dumpBuffer(void* rawHandle, dumpBuffer_cb hidlCb) override;
+ android::hardware::Return<void> dumpBuffers(dumpBuffers_cb hidlCb) override;
+
+ android::hardware::Return<void> getReservedRegion(void* rawHandle,
+ getReservedRegion_cb hidlCb) override;
+
+ private:
+ android::hardware::Return<void> get(cros_gralloc_handle_t crosHandle,
+ const MetadataType& metadataType, get_cb hidlCb);
+
+ android::hardware::Return<void> dumpBuffer(cros_gralloc_handle_t crosHandle,
+ dumpBuffer_cb hidlCb);
+
+ int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat,
+ uint64_t bufferUsage, uint32_t* outDrmFormat);
+
+ std::unique_ptr<cros_gralloc_driver> mDriver;
+};
+
+extern "C" android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* name);
* found in the LICENSE file.
*/
-#include "cros_gralloc/gralloc3/CrosGralloc3Utils.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
#include <array>
-#include <limits>
#include <unordered_map>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/native_handle.h>
+#include <gralloctypes/Gralloc4.h>
#include "cros_gralloc/cros_gralloc_helpers.h"
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
using android::hardware::hidl_bitfield;
using android::hardware::hidl_handle;
-using android::hardware::hidl_vec;
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::common::V1_2::PixelFormat;
using BufferDescriptorInfo =
- android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo;
+ android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
std::string getDrmFormatString(uint32_t drmFormat) {
switch (drmFormat) {
return "DRM_FORMAT_BGRX8888";
case DRM_FORMAT_C8:
return "DRM_FORMAT_C8";
- case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
- return "DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED";
case DRM_FORMAT_GR88:
return "DRM_FORMAT_GR88";
case DRM_FORMAT_NV12:
return "DRM_FORMAT_YUYV";
case DRM_FORMAT_YVU420:
return "DRM_FORMAT_YVU420";
- case DRM_FORMAT_YVU420_ANDROID:
- return "DRM_FORMAT_YVU420";
case DRM_FORMAT_YVYU:
return "DRM_FORMAT_YVYU";
}
return 0;
}
-int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
- uint32_t mapUsage = BO_MAP_NONE;
-
- if (grallocUsage & BufferUsage::CPU_READ_MASK) {
- mapUsage |= BO_MAP_READ;
- }
- if (grallocUsage & BufferUsage::CPU_WRITE_MASK) {
- mapUsage |= BO_MAP_WRITE;
- }
-
- *outMapUsage = mapUsage;
- return 0;
-}
-
int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor,
struct cros_gralloc_buffer_descriptor* outCrosDescriptor) {
+ outCrosDescriptor->name = descriptor.name;
outCrosDescriptor->width = descriptor.width;
outCrosDescriptor->height = descriptor.height;
outCrosDescriptor->droid_format = static_cast<int32_t>(descriptor.format);
outCrosDescriptor->droid_usage = descriptor.usage;
- outCrosDescriptor->reserved_region_size = 0;
+ outCrosDescriptor->reserved_region_size = descriptor.reservedSize;
if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
std::string pixelFormatString = getPixelFormatString(descriptor.format);
- drv_log("Failed to convert descriptor. Unsupported format %s\n", pixelFormatString.c_str());
+ drv_log("Failed to convert descriptor. Unsupported fomat %s\n", pixelFormatString.c_str());
return -1;
}
if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
return 0;
}
+int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
+ uint32_t mapUsage = BO_MAP_NONE;
+
+ if (grallocUsage & BufferUsage::CPU_READ_MASK) {
+ mapUsage |= BO_MAP_READ;
+ }
+ if (grallocUsage & BufferUsage::CPU_WRITE_MASK) {
+ mapUsage |= BO_MAP_WRITE;
+ }
+
+ *outMapUsage = mapUsage;
+ return 0;
+}
+
int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
if (!outFenceFd) {
return -EINVAL;
return 0;
}
-std::optional<BufferDescriptorInfo> decodeBufferDescriptorInfo(const hidl_vec<uint32_t>& encoded) {
- if (encoded.size() != 5) {
- drv_log("Failed to decodeBufferDescriptorInfo. Invalid size: %zd.\n", encoded.size());
- return {};
- }
+const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
+ static const auto* kPlaneLayoutsMap =
+ new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
+ {DRM_FORMAT_ABGR8888,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 8,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 16,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_A,
+ .offsetInBits = 24,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 32,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_ABGR2101010,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 10},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 10,
+ .sizeInBits = 10},
+ {.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 20,
+ .sizeInBits = 10},
+ {.type = android::gralloc4::PlaneLayoutComponentType_A,
+ .offsetInBits = 30,
+ .sizeInBits = 2}},
+ .sampleIncrementInBits = 32,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_ABGR16161616F,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 16},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 16,
+ .sizeInBits = 16},
+ {.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 32,
+ .sizeInBits = 16},
+ {.type = android::gralloc4::PlaneLayoutComponentType_A,
+ .offsetInBits = 48,
+ .sizeInBits = 16}},
+ .sampleIncrementInBits = 64,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_ARGB8888,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 0,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 8,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 16,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_A,
+ .offsetInBits = 24,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 32,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_NV12,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ },
+ {
+ .components =
+ {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
+ .offsetInBits = 0,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_CR,
+ .offsetInBits = 8,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 16,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ }}},
+
+ {DRM_FORMAT_NV21,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ },
+ {
+ .components =
+ {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
+ .offsetInBits = 0,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_CB,
+ .offsetInBits = 8,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 16,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ }}},
- BufferDescriptorInfo descriptor;
- descriptor.width = encoded[0];
- descriptor.height = encoded[1];
- descriptor.layerCount = encoded[2];
- descriptor.format = static_cast<PixelFormat>(encoded[3]);
- descriptor.usage = encoded[4];
- return std::move(descriptor);
+ {DRM_FORMAT_P010,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
+ .offsetInBits = 6,
+ .sizeInBits = 10}},
+ .sampleIncrementInBits = 16,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ },
+ {
+ .components =
+ {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
+ .offsetInBits = 6,
+ .sizeInBits = 10},
+ {.type = android::gralloc4::PlaneLayoutComponentType_CR,
+ .offsetInBits = 22,
+ .sizeInBits = 10}},
+ .sampleIncrementInBits = 32,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ }}},
+
+ {DRM_FORMAT_R8,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_R16,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 16}},
+ .sampleIncrementInBits = 16,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_RGB565,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 5},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 5,
+ .sizeInBits = 6},
+ {.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 11,
+ .sizeInBits = 5}},
+ .sampleIncrementInBits = 16,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_RGB888,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 0,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 8,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 16,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 24,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_XBGR8888,
+ {{
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .offsetInBits = 0,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_G,
+ .offsetInBits = 8,
+ .sizeInBits = 8},
+ {.type = android::gralloc4::PlaneLayoutComponentType_R,
+ .offsetInBits = 16,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 32,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ }}},
+
+ {DRM_FORMAT_YVU420,
+ {
+ {
+ .components = {{.type = android::gralloc4::
+ PlaneLayoutComponentType_Y,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ },
+ {
+ .components = {{.type = android::gralloc4::
+ PlaneLayoutComponentType_CB,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ },
+ {
+ .components = {{.type = android::gralloc4::
+ PlaneLayoutComponentType_CR,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ },
+ }},
+
+ {DRM_FORMAT_YVU420_ANDROID,
+ {
+ {
+ .components = {{.type = android::gralloc4::
+ PlaneLayoutComponentType_Y,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 1,
+ .verticalSubsampling = 1,
+ },
+ {
+ .components = {{.type = android::gralloc4::
+ PlaneLayoutComponentType_CR,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ },
+ {
+ .components = {{.type = android::gralloc4::
+ PlaneLayoutComponentType_CB,
+ .offsetInBits = 0,
+ .sizeInBits = 8}},
+ .sampleIncrementInBits = 8,
+ .horizontalSubsampling = 2,
+ .verticalSubsampling = 2,
+ },
+ }},
+ });
+ return *kPlaneLayoutsMap;
}
-std::optional<hidl_vec<uint32_t>> encodeBufferDescriptorInfo(const BufferDescriptorInfo& info) {
- hidl_vec<uint32_t> encoded;
- encoded.resize(5);
- encoded[0] = info.width;
- encoded[1] = info.height;
- encoded[2] = info.layerCount;
- encoded[3] = static_cast<uint32_t>(info.format);
- encoded[4] = info.usage & std::numeric_limits<uint32_t>::max();
- return std::move(encoded);
+int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
+ const auto& planeLayoutsMap = GetPlaneLayoutsMap();
+ const auto it = planeLayoutsMap.find(drmFormat);
+ if (it == planeLayoutsMap.end()) {
+ drv_log("Unknown plane layout for format %d\n", drmFormat);
+ return -1;
+ }
+
+ *outPlaneLayouts = it->second;
+ return 0;
}
\ No newline at end of file
* found in the LICENSE file.
*/
-#include <optional>
#include <string>
#include <vector>
+#include <aidl/android/hardware/graphics/common/PlaneLayout.h>
#include <android/hardware/graphics/common/1.2/types.h>
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+
+#include "cros_gralloc/cros_gralloc_types.h"
std::string getDrmFormatString(uint32_t drmFormat);
int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage);
-int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage);
-
int convertToCrosDescriptor(
- const android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo& descriptor,
+ const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo& descriptor,
struct cros_gralloc_buffer_descriptor* outCrosDescriptor);
+int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage);
+
int convertToFenceFd(const android::hardware::hidl_handle& fence_handle, int* out_fence_fd);
int convertToFenceHandle(int fence_fd, android::hardware::hidl_handle* out_fence_handle);
-std::optional<android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo>
-decodeBufferDescriptorInfo(const android::hardware::hidl_vec<uint32_t>& encoded);
-
-std::optional<android::hardware::hidl_vec<uint32_t>> encodeBufferDescriptorInfo(
- const android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo& info);
+int getPlaneLayouts(
+ uint32_t drm_format,
+ std::vector<aidl::android::hardware::graphics::common::PlaneLayout>* out_layouts);
\ No newline at end of file
--- /dev/null
+#
+# Copyright 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+service vendor.graphics.allocator-4-0 /vendor/bin/hw/android.hardware.graphics.allocator@4.0-service.minigbm
+ interface android.hardware.graphics.allocator@4.0::IAllocator default
+ class hal animation
+ user system
+ group graphics drmrpc
+ capabilities SYS_NICE
+ onrestart restart surfaceflinger
+ writepid /dev/cpuset/system-background/tasks
texture_only);
drv_modify_linear_combinations(drv);
-
- /* NV12 format for camera, display, decoding and encoding. */
+ /*
+ * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the
+ * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future.
+ */
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER);
/* IPU3 camera ISP supports only NV12 output. */
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
- BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER |
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT);
/* Android CTS tests require this. */
drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK);
/*
* R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
- * from camera and input/output from hardware decoder/encoder.
+ * from camera.
*/
drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
render = unset_flags(render, linear_mask);
scanout_and_render = unset_flags(scanout_and_render, linear_mask);
DRM_FORMAT_MOD_LINEAR,
};
uint64_t modifier;
- struct i915_device *i915 = bo->drv->priv;
- bool huge_bo = (i915->gen <= 11) && (width > 4096);
if (modifiers) {
modifier =
modifier = combo->metadata.modifier;
}
- /*
- * i915 only supports linear/x-tiled above 4096 wide
- */
- if (huge_bo && modifier != I915_FORMAT_MOD_X_TILED && modifier != DRM_FORMAT_MOD_LINEAR) {
- uint32_t i;
- for (i = 0; modifiers && i < count; i++) {
- if (modifiers[i] == I915_FORMAT_MOD_X_TILED)
- break;
- }
- if (i == count)
- modifier = DRM_FORMAT_MOD_LINEAR;
- else
- modifier = I915_FORMAT_MOD_X_TILED;
- }
-
switch (modifier) {
case DRM_FORMAT_MOD_LINEAR:
bo->meta.tiling = I915_TILING_NONE;
drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
BO_USE_SW_MASK | BO_USE_LINEAR | BO_USE_PROTECTED);
+ /*
+ * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the
+ * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future.
+ */
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER);
+ drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER);
/* Android CTS tests require this. */
drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK);
drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER);
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_DECODER);
- /*
- * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB for input/output from
- * hardware decoder/encoder.
- */
- drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
- BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER);
-
#ifdef MTK_MT8183
- /* NV12 format for encoding and display. */
- drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
- BO_USE_SCANOUT | BO_USE_HW_VIDEO_ENCODER);
-
/* Only for MT8183 Camera subsystem */
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats),
&LINEAR_METADATA, texture_use_flags);
+ /*
+ * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the
+ * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future.
+ */
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER);
+ drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER);
+
/* The camera stack standardizes on NV12 for YUV buffers. */
- /* YVU420 and NV12 formats for camera, display and encoding. */
drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
- BO_USE_HW_VIDEO_ENCODER);
-
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT);
/*
* R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
- * from camera and input/output from hardware decoder/encoder.
+ * from camera.
*/
- drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
/* Android CTS tests require this. */
drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK);
static uint32_t msm_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags)
{
switch (format) {
- case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
- /* Camera subsystem requires NV12. */
- if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE))
- return DRM_FORMAT_NV12;
- /*HACK: See b/28671744 */
- return DRM_FORMAT_XBGR8888;
case DRM_FORMAT_FLEX_YCbCr_420_888:
return DRM_FORMAT_NV12;
default:
drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata,
BO_USE_TEXTURE_MASK);
- /* NV12 format for camera, display, decoding and encoding. */
+ /*
+ * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the
+ * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future.
+ */
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER);
/* Camera ISP supports only NV12 output. */
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
- BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_SCANOUT);
drv_modify_linear_combinations(drv);
/*
* R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
- * from camera and input/output from hardware decoder/encoder.
+ * from camera.
*/
drv_add_combination(drv, DRM_FORMAT_R8, &metadata,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK |
- BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_LINEAR | BO_USE_PROTECTED);
return 0;
}
#define VIRGL_BIND_LINEAR (1 << 22)
-#define VIRGL_BIND_SHARED_SUBFLAGS (0xff << 24)
-
-#define VIRGL_BIND_MINIGBM_CAMERA_WRITE (1 << 24)
-#define VIRGL_BIND_MINIGBM_CAMERA_READ (1 << 25)
-#define VIRGL_BIND_MINIGBM_HW_VIDEO_DECODER (1 << 26)
-#define VIRGL_BIND_MINIGBM_HW_VIDEO_ENCODER (1 << 27)
-#define VIRGL_BIND_MINIGBM_SW_READ_OFTEN (1 << 28)
-#define VIRGL_BIND_MINIGBM_SW_READ_RARELY (1 << 29)
-#define VIRGL_BIND_MINIGBM_SW_WRITE_OFTEN (1 << 30)
-#define VIRGL_BIND_MINIGBM_SW_WRITE_RARELY (1 << 31)
-#define VIRGL_BIND_MINIGBM_PROTECTED (0xf << 28) // Mutually exclusive with SW_ flags
-
struct virgl_caps_bool_set1 {
unsigned indep_blend_enable:1;
unsigned indep_blend_func:1;
handle_flag(&use_flags, BO_USE_CURSOR, &bind, VIRGL_BIND_CURSOR);
handle_flag(&use_flags, BO_USE_LINEAR, &bind, VIRGL_BIND_LINEAR);
- if (use_flags & BO_USE_PROTECTED) {
- handle_flag(&use_flags, BO_USE_PROTECTED, &bind, VIRGL_BIND_MINIGBM_PROTECTED);
- } else {
- // Make sure we don't set both flags, since that could be mistaken for
- // protected. Give OFTEN priority over RARELY.
- if (use_flags & BO_USE_SW_READ_OFTEN) {
- handle_flag(&use_flags, BO_USE_SW_READ_OFTEN, &bind,
- VIRGL_BIND_MINIGBM_SW_READ_OFTEN);
- } else {
- handle_flag(&use_flags, BO_USE_SW_READ_RARELY, &bind,
- VIRGL_BIND_MINIGBM_SW_READ_RARELY);
- }
- if (use_flags & BO_USE_SW_WRITE_OFTEN) {
- handle_flag(&use_flags, BO_USE_SW_WRITE_OFTEN, &bind,
- VIRGL_BIND_MINIGBM_SW_WRITE_OFTEN);
- } else {
- handle_flag(&use_flags, BO_USE_SW_WRITE_RARELY, &bind,
- VIRGL_BIND_MINIGBM_SW_WRITE_RARELY);
- }
- }
+ handle_flag(&use_flags, BO_USE_SW_READ_OFTEN, &bind, VIRGL_BIND_LINEAR);
+ handle_flag(&use_flags, BO_USE_SW_READ_RARELY, &bind, VIRGL_BIND_LINEAR);
+ handle_flag(&use_flags, BO_USE_SW_WRITE_OFTEN, &bind, VIRGL_BIND_LINEAR);
+ handle_flag(&use_flags, BO_USE_SW_WRITE_RARELY, &bind, VIRGL_BIND_LINEAR);
- handle_flag(&use_flags, BO_USE_CAMERA_WRITE, &bind, VIRGL_BIND_MINIGBM_CAMERA_WRITE);
- handle_flag(&use_flags, BO_USE_CAMERA_READ, &bind, VIRGL_BIND_MINIGBM_CAMERA_READ);
- handle_flag(&use_flags, BO_USE_HW_VIDEO_DECODER, &bind,
- VIRGL_BIND_MINIGBM_HW_VIDEO_DECODER);
- handle_flag(&use_flags, BO_USE_HW_VIDEO_ENCODER, &bind,
- VIRGL_BIND_MINIGBM_HW_VIDEO_ENCODER);
+ // All host drivers only support linear camera buffer formats. If
+ // that changes, this will need to be modified.
+ handle_flag(&use_flags, BO_USE_CAMERA_READ, &bind, VIRGL_BIND_LINEAR);
+ handle_flag(&use_flags, BO_USE_CAMERA_WRITE, &bind, VIRGL_BIND_LINEAR);
if (use_flags) {
drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags);
virtio_gpu_add_combination(drv, DRM_FORMAT_ABGR16161616F, &LINEAR_METADATA,
BO_USE_SW_MASK | BO_USE_TEXTURE_MASK);
- drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
- drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &LINEAR_METADATA,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
BO_USE_HW_VIDEO_ENCODER);
drv_modify_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
BO_USE_HW_VIDEO_ENCODER);
- drv_modify_combination(drv, DRM_FORMAT_R16, &LINEAR_METADATA,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER);
- drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
- BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_RENDERSCRIPT);
drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &LINEAR_METADATA,
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
- BO_USE_HW_VIDEO_ENCODER);
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_RENDERSCRIPT);
+ drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER);
+ drv_modify_combination(drv, DRM_FORMAT_R16, &LINEAR_METADATA,
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER);
return drv_modify_linear_combinations(drv);
}
memset(&xfer, 0, sizeof(xfer));
xfer.bo_handle = mapping->vma->handle;
- if (mapping->rect.x || mapping->rect.y) {
- /*
- * virglrenderer uses the box parameters and assumes that offset == 0 for planar
- * images
- */
- if (bo->meta.num_planes == 1) {
- xfer.offset =
- (bo->meta.strides[0] * mapping->rect.y) +
- drv_bytes_per_pixel_from_format(bo->meta.format, 0) * mapping->rect.x;
- }
- }
-
if ((bo->meta.use_flags & BO_USE_RENDERING) == 0) {
// Unfortunately, the kernel doesn't actually pass the guest layer_stride
// and guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h).
memset(&xfer, 0, sizeof(xfer));
xfer.bo_handle = mapping->vma->handle;
- if (mapping->rect.x || mapping->rect.y) {
- /*
- * virglrenderer uses the box parameters and assumes that offset == 0 for planar
- * images
- */
- if (bo->meta.num_planes == 1) {
- xfer.offset =
- (bo->meta.strides[0] * mapping->rect.y) +
- drv_bytes_per_pixel_from_format(bo->meta.format, 0) * mapping->rect.x;
- }
- }
-
// Unfortunately, the kernel doesn't actually pass the guest layer_stride and
// guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use
// the level to work around this.