diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-09 00:04:59 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-09 00:04:59 +0000 |
commit | ad7fcdb22ffb98dc08dbea1ac2b286a16ca45031 (patch) | |
tree | 7db8addd59af78ff5b81242d00962d3021fe5ff5 | |
parent | 16fff9020de6b0cfbc98a9dca392c37d7d244ff8 (diff) | |
parent | d1770ed2e4fbb4e88f90d6b7086f5ec56cdc00d2 (diff) | |
download | minigbm-android12L-tests-release.tar.gz |
Snap for 7981408 from d1770ed2e4fbb4e88f90d6b7086f5ec56cdc00d2 to sc-v2-releaseandroid-vts-12.1_r9android-vts-12.1_r8android-vts-12.1_r7android-vts-12.1_r6android-vts-12.1_r5android-vts-12.1_r4android-vts-12.1_r3android-vts-12.1_r2android-vts-12.1_r10android-vts-12.1_r1android-platform-12.1.0_r9android-platform-12.1.0_r8android-platform-12.1.0_r7android-platform-12.1.0_r6android-platform-12.1.0_r5android-platform-12.1.0_r4android-platform-12.1.0_r3android-platform-12.1.0_r27android-platform-12.1.0_r26android-platform-12.1.0_r25android-platform-12.1.0_r24android-platform-12.1.0_r23android-platform-12.1.0_r22android-platform-12.1.0_r21android-platform-12.1.0_r20android-platform-12.1.0_r2android-platform-12.1.0_r19android-platform-12.1.0_r18android-platform-12.1.0_r17android-platform-12.1.0_r16android-platform-12.1.0_r15android-platform-12.1.0_r14android-platform-12.1.0_r13android-platform-12.1.0_r12android-platform-12.1.0_r11android-platform-12.1.0_r10android-platform-12.1.0_r1android-cts-12.1_r9android-cts-12.1_r8android-cts-12.1_r7android-cts-12.1_r6android-cts-12.1_r5android-cts-12.1_r4android-cts-12.1_r3android-cts-12.1_r2android-cts-12.1_r10android-cts-12.1_r1android-12.1.0_r6android-12.1.0_r5android-12.1.0_r4android-12.1.0_r3android-12.1.0_r27android-12.1.0_r2android-12.1.0_r1android12L-tests-releaseandroid12L-s1-releaseandroid12L-releaseandroid12L-platform-release
Change-Id: I42b1ccf388040b06beab25790f5f7b69b9aeaf6a
60 files changed, 1559 insertions, 2651 deletions
@@ -32,16 +32,15 @@ license { ], } -cc_defaults { - name: "minigbm_defaults", +filegroup { + name: "minigbm_core_files", srcs: [ "amdgpu.c", "drv.c", + "drv_array_helpers.c", + "drv_helpers.c", "dumb_driver.c", - "exynos.c", - "helpers_array.c", - "helpers.c", "i915.c", "mediatek.c", "msm.c", @@ -51,6 +50,25 @@ cc_defaults { "virtgpu_cross_domain.c", "virtgpu_virgl.c", ], +} + +filegroup { + name: "minigbm_gralloc_common_files", + + srcs: [ + "cros_gralloc/cros_gralloc_buffer.cc", + "cros_gralloc/cros_gralloc_helpers.cc", + "cros_gralloc/cros_gralloc_driver.cc", + ], +} + +filegroup { + name: "minigbm_gralloc0_files", + srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], +} + +cc_defaults { + name: "minigbm_defaults", cflags: [ "-D_GNU_SOURCE=1", @@ -63,7 +81,18 @@ cc_defaults { "-Wno-unused-parameter", ], - cppflags: ["-std=c++14"], + product_variables: { + platform_sdk_version: { + cflags: ["-DANDROID_API_LEVEL=%d"], + }, + }, +} + +cc_library_headers { + name: "minigbm_headers", + host_supported: true, + vendor_available: true, + export_include_dirs: ["."], } cc_defaults { @@ -74,27 +103,12 @@ cc_defaults { header_libs: [ "libhardware_headers", "libnativebase_headers", - "libnativewindow_headers", "libsystem_headers", - ], - - export_header_lib_headers: [ - "libhardware_headers", - "libnativebase_headers", - "libnativewindow_headers", - "libsystem_headers", - ], - - srcs: [ - "cros_gralloc/cros_gralloc_buffer.cc", - "cros_gralloc/cros_gralloc_helpers.cc", - "cros_gralloc/cros_gralloc_driver.cc", + "minigbm_headers", ], static_libs: ["libarect"], - export_static_lib_headers: ["libarect"], - vendor: true, shared_libs: [ @@ -104,28 +118,38 @@ cc_defaults { "libsync", "liblog", ], - - relative_install_path: "hw", } cc_defaults { - name: "gbm_defaults", - - defaults: ["minigbm_defaults"], + name: "minigbm_cros_gralloc_library_defaults", + defaults: ["minigbm_cros_gralloc_defaults"], srcs: [ - "gbm.c", - "gbm_helpers.c", + ":minigbm_core_files", + ":minigbm_gralloc_common_files", ], +} - export_include_dirs: ["."], +cc_defaults { + name: "minigbm_cros_gralloc0_defaults", + + defaults: ["minigbm_cros_gralloc_defaults"], + relative_install_path: "hw", + + srcs: [":minigbm_gralloc0_files"], } cc_library { name: "libgbm", - defaults: ["gbm_defaults"], + defaults: ["minigbm_defaults"], host_supported: true, + srcs: [ + ":minigbm_core_files", + "gbm.c", + "gbm_helpers.c", + ], + target: { host: { // Avoid linking to another host copy of libdrm; this library will cause @@ -145,31 +169,42 @@ cc_library { "//apex_available:platform", "com.android.virt", ], -} - -cc_defaults { - name: "libminigbm_cros_gralloc_defaults", - defaults: ["minigbm_cros_gralloc_defaults"], - shared_libs: ["liblog"], - static_libs: ["libdrm"], export_include_dirs: ["."], } -cc_library_static { - name: "libminigbm_cros_gralloc", - defaults: ["libminigbm_cros_gralloc_defaults"], +// Generic +cc_library_shared { + name: "libminigbm_gralloc", + defaults: ["minigbm_cros_gralloc_library_defaults"], } cc_library_shared { name: "gralloc.minigbm", - defaults: ["minigbm_cros_gralloc_defaults"], - srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], + defaults: ["minigbm_cros_gralloc0_defaults"], + shared_libs: ["libminigbm_gralloc"], +} + +// Intel +cc_library_shared { + name: "libminigbm_gralloc_intel", + defaults: ["minigbm_cros_gralloc_library_defaults"], + cflags: ["-DDRV_I915"], + enabled: false, + arch: { + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, + }, } cc_library_shared { name: "gralloc.minigbm_intel", - defaults: ["minigbm_cros_gralloc_defaults"], + defaults: ["minigbm_cros_gralloc0_defaults"], + shared_libs: ["libminigbm_gralloc_intel"], enabled: false, arch: { x86: { @@ -179,28 +214,46 @@ cc_library_shared { enabled: true, }, }, - cflags: ["-DDRV_I915"], - srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], } +// Meson cc_library_shared { - name: "gralloc.minigbm_meson", - defaults: ["minigbm_cros_gralloc_defaults"], + name: "libminigbm_gralloc_meson", + defaults: ["minigbm_cros_gralloc_library_defaults"], cflags: ["-DDRV_MESON"], - srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], } cc_library_shared { - name: "gralloc.minigbm_msm", - defaults: ["minigbm_cros_gralloc_defaults"], - cflags: ["-DDRV_MSM"], - srcs: [ - "cros_gralloc/gralloc0/gralloc0.cc", + name: "gralloc.minigbm_meson", + defaults: ["minigbm_cros_gralloc0_defaults"], + shared_libs: ["libminigbm_gralloc_meson"], +} + +// MSM +cc_library_shared { + name: "libminigbm_gralloc_msm", + defaults: ["minigbm_cros_gralloc_library_defaults"], + cflags: [ + "-DDRV_MSM", + "-DQCOM_DISABLE_COMPRESSED_NV12", ], } -cc_library_static { - name: "libminigbm_cros_gralloc_msm", - defaults: ["libminigbm_cros_gralloc_defaults"], - cflags: ["-DDRV_MSM"], +cc_library_shared { + name: "gralloc.minigbm_msm", + defaults: ["minigbm_cros_gralloc0_defaults"], + shared_libs: ["libminigbm_gralloc_msm"], +} + +// ARCVM +cc_library_shared { + name: "libminigbm_gralloc_arcvm", + defaults: ["minigbm_cros_gralloc_library_defaults"], + cflags: ["-DVIRTIO_GPU_NEXT"], +} + +cc_library_shared { + name: "gralloc.minigbm_arcvm", + defaults: ["minigbm_cros_gralloc0_defaults"], + shared_libs: ["libminigbm_gralloc_arcvm"], } diff --git a/Android.gralloc.mk b/Android.gralloc.mk deleted file mode 100644 index ff269c0..0000000 --- a/Android.gralloc.mk +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2017 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. - -LOCAL_CPP_EXTENSION := .cc - -LOCAL_SRC_FILES += \ - cros_gralloc/cros_gralloc_buffer.cc \ - cros_gralloc/cros_gralloc_driver.cc \ - cros_gralloc/cros_gralloc_helpers.cc \ - cros_gralloc/gralloc0/gralloc0.cc @@ -16,9 +16,6 @@ ifdef DRV_AMDGPU CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amdgpu) LDLIBS += -ldrm_amdgpu -ldl endif -ifdef DRV_EXYNOS - CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_exynos) -endif ifdef DRV_I915 CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_intel) endif @@ -49,6 +46,7 @@ MINIGBM_FILENAME := libminigbm.so.$(MINIGBM_VERSION) CC_LIBRARY($(MINIGBM_FILENAME)): LDFLAGS += -Wl,-soname,libgbm.so.$(GBM_VERSION_MAJOR) CC_LIBRARY($(MINIGBM_FILENAME)): $(C_OBJECTS) +CC_STATIC_LIBRARY(libminigbm.pie.a): $(C_OBJECTS) all: CC_LIBRARY($(MINIGBM_FILENAME)) @@ -1,10 +1,20 @@ +basni@chromium.org +dbehr@chromium.org +ddavenport@chromium.org gurchetansingh@chromium.org +hiroh@chromium.org hoegsberg@chromium.org marcheu@chromium.org +olv@google.com +robdclark@chromium.org stevensd@chromium.org tfiga@chromium.org +zzyiwei@chromium.org -# Also natsu@google.com is great for gralloc/Android stuff but doesn't have a -# chromium account. -# So any team members can +2 -* +# just reference for backend specific reviews +per-file amdgpu.c = basni@chromium.org, ddavenport@chromium.org +per-file i915.c = chadversary@chromium.org, hoegsberg@chromium.org +per-file mediatek.c = fshao@chromium.org, tzungbi@chromium.org +per-file msm.c = robdclark@chromium.org, hoegsberg@chromium.org +per-file rockchip.c = tfiga@chromium.org +per-file virtgpu* = jbates@chromium.org, natsu@google.com, olv@google.com, zzyiwei@chromium.org @@ -6,16 +6,21 @@ #ifdef DRV_AMDGPU #include <amdgpu.h> #include <amdgpu_drm.h> +#include <assert.h> +#include <drm_fourcc.h> #include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> +#include <unistd.h> #include <xf86drm.h> +#include <xf86drmMode.h> #include "dri.h" +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" // clang-format off @@ -23,8 +28,10 @@ // clang-format on #define TILE_TYPE_LINEAR 0 +/* We decide a modifier and then use DRI to manage allocation */ +#define TILE_TYPE_DRI_MODIFIER 1 /* DRI backend decides tiling in this case. */ -#define TILE_TYPE_DRI 1 +#define TILE_TYPE_DRI 2 /* Height alignement for Encoder/Decoder buffers */ #define CHROME_HEIGHT_ALIGN 16 @@ -305,6 +312,39 @@ unmap_src: return ret; } +static bool is_modifier_scanout_capable(struct amdgpu_priv *priv, uint32_t format, + uint64_t modifier) +{ + unsigned bytes_per_pixel = drv_stride_from_format(format, 1, 0); + + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + + if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_AMD) + return false; + + unsigned swizzle = AMD_FMT_MOD_GET(TILE, modifier); + if (priv->dev_info.family >= AMDGPU_FAMILY_RV) { /* DCN based GPUs */ + /* D swizzle only supported for 64 bpp */ + if ((swizzle & 3) == 2 && bytes_per_pixel != 8) + return false; + + /* S swizzle not supported for 64 bpp */ + if ((swizzle & 3) == 1 && bytes_per_pixel == 8) + return false; + } else { /* DCE based GPUs with GFX9 based modifier swizzling. */ + assert(priv->dev_info.family == AMDGPU_FAMILY_AI); + /* Only D swizzles are allowed for display */ + if ((swizzle & 3) != 2) + return false; + } + + if (AMD_FMT_MOD_GET(DCC, modifier) && + (AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier) || !AMD_FMT_MOD_GET(DCC_RETILE, modifier))) + return false; + return true; +} + static int amdgpu_init(struct driver *drv) { struct amdgpu_priv *priv; @@ -370,6 +410,7 @@ static int amdgpu_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_RGB565, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_ABGR2101010, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_ARGB2101010, &metadata, BO_USE_SCANOUT); @@ -394,24 +435,60 @@ static int amdgpu_init(struct driver *drv) use_flags &= ~BO_USE_RENDERSCRIPT; use_flags &= ~BO_USE_SW_WRITE_OFTEN; use_flags &= ~BO_USE_SW_READ_OFTEN; +#if __ANDROID__ + use_flags &= ~BO_USE_SW_WRITE_RARELY; + use_flags &= ~BO_USE_SW_READ_RARELY; +#endif use_flags &= ~BO_USE_LINEAR; - metadata.tiling = TILE_TYPE_DRI; metadata.priority = 2; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_flags); - - /* Potentially tiled formats supported by display. */ - drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); - drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); - drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_SCANOUT); - drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); - - drv_modify_combination(drv, DRM_FORMAT_ABGR2101010, &metadata, BO_USE_SCANOUT); - drv_modify_combination(drv, DRM_FORMAT_ARGB2101010, &metadata, BO_USE_SCANOUT); - drv_modify_combination(drv, DRM_FORMAT_XBGR2101010, &metadata, BO_USE_SCANOUT); - drv_modify_combination(drv, DRM_FORMAT_XRGB2101010, &metadata, BO_USE_SCANOUT); + for (unsigned f = 0; f < ARRAY_SIZE(render_target_formats); ++f) { + uint32_t format = render_target_formats[f]; + int mod_cnt; + if (dri_query_modifiers(drv, format, 0, NULL, &mod_cnt) && mod_cnt) { + uint64_t *modifiers = calloc(mod_cnt, sizeof(uint64_t)); + dri_query_modifiers(drv, format, mod_cnt, modifiers, &mod_cnt); + metadata.tiling = TILE_TYPE_DRI_MODIFIER; + for (int i = 0; i < mod_cnt; ++i) { + bool scanout = + is_modifier_scanout_capable(drv->priv, format, modifiers[i]); + + /* LINEAR will be handled using the LINEAR metadata. */ + if (modifiers[i] == DRM_FORMAT_MOD_LINEAR) + continue; + + /* The virtgpu minigbm can't handle auxiliary planes in the host. */ + if (dri_num_planes_from_modifier(drv, format, modifiers[i]) != + drv_num_planes_from_format(format)) + continue; + + metadata.modifier = modifiers[i]; + drv_add_combination(drv, format, &metadata, + use_flags | (scanout ? BO_USE_SCANOUT : 0)); + } + free(modifiers); + } else { + bool scanout = false; + switch (format) { + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_XRGB2101010: + scanout = true; + break; + default: + break; + } + metadata.tiling = TILE_TYPE_DRI; + drv_add_combination(drv, format, &metadata, + use_flags | (scanout ? BO_USE_SCANOUT : 0)); + } + } return 0; } @@ -439,9 +516,11 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh * For multiplane formats, align the stride to 512 to ensure that subsample strides are 256 * aligned. This uses more memory than necessary since the first plane only needs to be * 256 aligned, but it's acceptable for a short-term fix. It's probably safe for other gpu - * families, but let's restrict it to Raven for now (b/171013552). + * families, but let's restrict it to Raven and Stoney for now (b/171013552, b/190484589). * */ - if (priv->dev_info.family == AMDGPU_FAMILY_RV && num_planes > 1) + if (num_planes > 1 && + (priv->dev_info.family == AMDGPU_FAMILY_RV || + (priv->dev_info.family == AMDGPU_FAMILY_CZ && !(use_flags & BO_USE_HW_VIDEO_ENCODER)))) stride = ALIGN(stride, 512); else stride = ALIGN(stride, 256); @@ -503,28 +582,16 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint return -EINVAL; if (combo->metadata.tiling == TILE_TYPE_DRI) { - bool needs_alignment = false; -#ifdef __ANDROID__ - /* - * Currently, the gralloc API doesn't differentiate between allocation time and map - * time strides. A workaround for amdgpu DRI buffers is to always to align to 256 at - * allocation time. - * - * See b/115946221,b/117942643 - */ - if (use_flags & (BO_USE_SW_MASK)) - needs_alignment = true; -#endif // See b/122049612 - if (use_flags & (BO_USE_SCANOUT) && priv->dev_info.family == AMDGPU_FAMILY_CZ) - needs_alignment = true; - - if (needs_alignment) { + if (use_flags & (BO_USE_SCANOUT) && priv->dev_info.family == AMDGPU_FAMILY_CZ) { uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(format, 0); width = ALIGN(width, 256 / bytes_per_pixel); } return dri_bo_create(bo, width, height, format, use_flags); + } else if (combo->metadata.tiling == TILE_TYPE_DRI_MODIFIER) { + return dri_bo_create_with_modifiers(bo, width, height, format, + &combo->metadata.modifier, 1); } return amdgpu_create_bo_linear(bo, width, height, format, use_flags); @@ -555,7 +622,7 @@ static int amdgpu_import_bo(struct bo *bo, struct drv_import_fd_data *data) if (!combo) return -EINVAL; - dri_tiling = combo->metadata.tiling == TILE_TYPE_DRI; + dri_tiling = combo->metadata.tiling != TILE_TYPE_LINEAR; } if (dri_tiling) @@ -564,6 +631,14 @@ static int amdgpu_import_bo(struct bo *bo, struct drv_import_fd_data *data) return drv_prime_bo_import(bo, data); } +static int amdgpu_release_bo(struct bo *bo) +{ + if (bo->priv) + return dri_bo_release(bo); + + return 0; +} + static int amdgpu_destroy_bo(struct bo *bo) { if (bo->priv) @@ -713,12 +788,13 @@ const struct backend backend_amdgpu = { .close = amdgpu_close, .bo_create = amdgpu_create_bo, .bo_create_with_modifiers = amdgpu_create_bo_with_modifiers, + .bo_release = amdgpu_release_bo, .bo_destroy = amdgpu_destroy_bo, .bo_import = amdgpu_import_bo, .bo_map = amdgpu_map_bo, .bo_unmap = amdgpu_unmap_bo, .bo_invalidate = amdgpu_bo_invalidate, - .resolve_format = drv_resolve_format_helper, + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, .num_planes_from_modifier = dri_num_planes_from_modifier, }; diff --git a/cros_gralloc/OWNERS b/cros_gralloc/OWNERS new file mode 100644 index 0000000..cd8d003 --- /dev/null +++ b/cros_gralloc/OWNERS @@ -0,0 +1,3 @@ +set noparent +natsu@google.com +zzyiwei@chromium.org diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index 9bc0ef0..3158454 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -7,7 +7,6 @@ #ifndef CROS_GRALLOC_BUFFER_H #define CROS_GRALLOC_BUFFER_H -#include "../drv.h" #include "cros_gralloc_helpers.h" class cros_gralloc_buffer diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index f0c0392..1381ff5 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -8,12 +8,11 @@ #include <cstdlib> #include <fcntl.h> +#include <hardware/gralloc.h> #include <sys/mman.h> #include <syscall.h> #include <xf86drm.h> -#include "../drv_priv.h" -#include "../helpers.h" #include "../util.h" // Constants taken from pipe_loader_drm.c in Mesa @@ -45,21 +44,16 @@ int memfd_create_wrapper(const char *name, unsigned int flags) return fd; } -cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr) +cros_gralloc_driver *cros_gralloc_driver::get_instance() { -} - -cros_gralloc_driver::~cros_gralloc_driver() -{ - buffers_.clear(); - handles_.clear(); + static cros_gralloc_driver s_instance; - if (drv_) { - int fd = drv_get_fd(drv_); - drv_destroy(drv_); - drv_ = nullptr; - close(fd); + if (!s_instance.is_initialized()) { + drv_log("Failed to initialize driver.\n"); + return nullptr; } + + return &s_instance; } static struct driver *init_try_node(int idx, char const *str) @@ -84,7 +78,7 @@ static struct driver *init_try_node(int idx, char const *str) return drv; } -int32_t cros_gralloc_driver::init() +cros_gralloc_driver::cros_gralloc_driver() { /* * Create a driver from render nodes first, then try card @@ -105,26 +99,82 @@ int32_t cros_gralloc_driver::init() for (uint32_t i = min_render_node; i < max_render_node; i++) { drv_ = init_try_node(i, render_nodes_fmt); if (drv_) - return 0; + return; } // Try card nodes... for vkms mostly. for (uint32_t i = min_card_node; i < max_card_node; i++) { drv_ = init_try_node(i, card_nodes_fmt); if (drv_) - return 0; + return; + } +} + +cros_gralloc_driver::~cros_gralloc_driver() +{ + buffers_.clear(); + handles_.clear(); + + if (drv_) { + int fd = drv_get_fd(drv_); + drv_destroy(drv_); + drv_ = nullptr; + close(fd); } +} - return -ENODEV; +bool cros_gralloc_driver::is_initialized() +{ + return drv_ != nullptr; } -bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor) +bool cros_gralloc_driver::get_resolved_format_and_use_flags( + const struct cros_gralloc_buffer_descriptor *descriptor, uint32_t *out_format, + uint64_t *out_use_flags) { + uint32_t resolved_format; + uint64_t resolved_use_flags; struct combination *combo; + + drv_resolve_format_and_use_flags(drv_, descriptor->drm_format, descriptor->use_flags, + &resolved_format, &resolved_use_flags); + + combo = drv_get_combination(drv_, resolved_format, resolved_use_flags); + if (!combo && (descriptor->droid_usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && + descriptor->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) { + // Unmask BO_USE_HW_VIDEO_ENCODER for other formats. They are mostly + // intermediate formats not passed directly to the encoder (e.g. + // camera). YV12 is passed to the encoder component, but it is converted + // to YCbCr_420_888 before being passed to the hw encoder. + resolved_use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + combo = drv_get_combination(drv_, resolved_format, resolved_use_flags); + } + if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING)) { + resolved_use_flags &= ~BO_USE_FRONT_RENDERING; + resolved_use_flags |= BO_USE_LINEAR; + combo = drv_get_combination(drv_, resolved_format, resolved_use_flags); + } + if (!combo) + return false; + + *out_format = resolved_format; + *out_use_flags = resolved_use_flags; + return true; +} + +bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor) +{ uint32_t resolved_format; - resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); - combo = drv_get_combination(drv_, resolved_format, descriptor->use_flags); - return (combo != nullptr); + uint64_t resolved_use_flags; + uint32_t max_texture_size = drv_get_max_texture_2d_size(drv_); + if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) + return false; + + // Allow blob buffers to go beyond the limit. + if (descriptor->droid_format == HAL_PIXEL_FORMAT_BLOB) + return true; + + return descriptor->width <= max_texture_size && descriptor->height <= max_texture_size; } int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size) @@ -163,24 +213,18 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto size_t num_bytes; uint32_t resolved_format; uint32_t bytes_per_pixel; - uint64_t use_flags; + uint64_t resolved_use_flags; char *name; struct bo *bo; struct cros_gralloc_handle *hnd; - resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); - use_flags = descriptor->use_flags; - - /* - * This unmask is a backup in the case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED is resolved - * to non-YUV formats. - */ - if (descriptor->drm_format == DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED && - (resolved_format == DRM_FORMAT_XBGR8888 || resolved_format == DRM_FORMAT_ABGR8888)) { - use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) { + drv_log("Failed to resolve format and use_flags.\n"); + return -EINVAL; } - bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, use_flags); + bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, + resolved_use_flags); if (!bo) { drv_log("Failed to create bo.\n"); return -errno; @@ -243,15 +287,15 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto hnd->width = drv_bo_get_width(bo); hnd->height = drv_bo_get_height(bo); hnd->format = drv_bo_get_format(bo); - hnd->tiling = bo->meta.tiling; + hnd->tiling = drv_bo_get_tiling(bo); hnd->format_modifier = drv_bo_get_format_modifier(bo); - hnd->use_flags = descriptor->use_flags; + hnd->use_flags = drv_bo_get_use_flags(bo); bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0); hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel); hnd->magic = cros_gralloc_magic; hnd->droid_format = descriptor->droid_format; hnd->usage = descriptor->droid_usage; - hnd->total_size = descriptor->reserved_region_size + bo->meta.total_size; + hnd->total_size = descriptor->reserved_region_size + drv_bo_get_total_size(bo); hnd->name_offset = handle_data_size; name = (char *)(&hnd->data[hnd->name_offset]); @@ -506,9 +550,15 @@ int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle, return buffer->get_reserved_region(reserved_region_addr, reserved_region_size); } -uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t usage) +uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t use_flags) { - return drv_resolve_format(drv_, drm_format, usage); + uint32_t resolved_format; + uint64_t resolved_use_flags; + + drv_resolve_format_and_use_flags(drv_, drm_format, use_flags, &resolved_format, + &resolved_use_flags); + + return resolved_format; } cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd) diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index ef9e21f..d1456a8 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -16,10 +16,7 @@ class cros_gralloc_driver { public: - cros_gralloc_driver(); - ~cros_gralloc_driver(); - - int32_t init(); + static cros_gralloc_driver *get_instance(); bool is_supported(const struct cros_gralloc_buffer_descriptor *descriptor); int32_t allocate(const struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *out_handle); @@ -42,17 +39,21 @@ class cros_gralloc_driver int32_t get_reserved_region(buffer_handle_t handle, void **reserved_region_addr, uint64_t *reserved_region_size); - uint32_t get_resolved_drm_format(uint32_t drm_format, uint64_t usage); + uint32_t get_resolved_drm_format(uint32_t drm_format, uint64_t use_flags); void for_each_handle(const std::function<void(cros_gralloc_handle_t)> &function); private: - cros_gralloc_driver(cros_gralloc_driver const &); - cros_gralloc_driver operator=(cros_gralloc_driver const &); + cros_gralloc_driver(); + ~cros_gralloc_driver(); + bool is_initialized(); cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd); void emplace_buffer(struct bo *bo, struct cros_gralloc_handle *hnd); + bool + get_resolved_format_and_use_flags(const struct cros_gralloc_buffer_descriptor *descriptor, + uint32_t *out_format, uint64_t *out_use_flags); - struct driver *drv_; + struct driver *drv_ = nullptr; std::mutex mutex_; std::unordered_map<uint32_t, cros_gralloc_buffer *> buffers_; std::unordered_map<cros_gralloc_handle_t, std::pair<cros_gralloc_buffer *, int32_t>> diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 4319936..3301522 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -6,8 +6,15 @@ #include "cros_gralloc_helpers.h" +#include <hardware/gralloc.h> #include <sync/sync.h> +/* Define to match AIDL BufferUsage::VIDEO_DECODER. */ +#define BUFFER_USAGE_VIDEO_DECODER (1 << 22) + +/* Define to match AIDL BufferUsage::GPU_DATA_BUFFER. */ +#define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24) + uint32_t cros_gralloc_convert_format(int format) { /* @@ -16,24 +23,27 @@ uint32_t cros_gralloc_convert_format(int format) */ switch (format) { - case HAL_PIXEL_FORMAT_BGRA_8888: - return DRM_FORMAT_ARGB8888; - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; - case HAL_PIXEL_FORMAT_RAW16: - return DRM_FORMAT_R16; - case HAL_PIXEL_FORMAT_RGB_565: - return DRM_FORMAT_RGB565; - case HAL_PIXEL_FORMAT_RGB_888: - return DRM_FORMAT_BGR888; case HAL_PIXEL_FORMAT_RGBA_8888: return DRM_FORMAT_ABGR8888; case HAL_PIXEL_FORMAT_RGBX_8888: return DRM_FORMAT_XBGR8888; - case HAL_PIXEL_FORMAT_YCbCr_420_888: - return DRM_FORMAT_FLEX_YCbCr_420_888; - case HAL_PIXEL_FORMAT_YV12: - return DRM_FORMAT_YVU420_ANDROID; + case HAL_PIXEL_FORMAT_RGB_888: + return DRM_FORMAT_BGR888; + /* + * Confusingly, HAL_PIXEL_FORMAT_RGB_565 is defined as: + * + * "16-bit packed format that has 5-bit R, 6-bit G, and 5-bit B components, in that + * order, from the most-sigfinicant bits to the least-significant bits." + * + * so the order of the components is intentionally not flipped between the pixel + * format and the DRM format. + */ + case HAL_PIXEL_FORMAT_RGB_565: + return DRM_FORMAT_RGB565; + case HAL_PIXEL_FORMAT_BGRA_8888: + return DRM_FORMAT_ARGB8888; + case HAL_PIXEL_FORMAT_RAW16: + return DRM_FORMAT_R16; /* * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width @@ -41,17 +51,97 @@ uint32_t cros_gralloc_convert_format(int format) */ case HAL_PIXEL_FORMAT_BLOB: return DRM_FORMAT_R8; -#if ANDROID_VERSION >= 0x0a00 - case HAL_PIXEL_FORMAT_RGBA_1010102: - return DRM_FORMAT_ABGR2101010; + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: + return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; + case HAL_PIXEL_FORMAT_YCbCr_420_888: + return DRM_FORMAT_FLEX_YCbCr_420_888; + case HAL_PIXEL_FORMAT_Y8: + return DRM_FORMAT_R8; + case HAL_PIXEL_FORMAT_Y16: + return DRM_FORMAT_R16; + case HAL_PIXEL_FORMAT_YV12: + return DRM_FORMAT_YVU420_ANDROID; +#if ANDROID_API_LEVEL >= 29 case HAL_PIXEL_FORMAT_RGBA_FP16: return DRM_FORMAT_ABGR16161616F; + case HAL_PIXEL_FORMAT_RGBA_1010102: + return DRM_FORMAT_ABGR2101010; +#endif +#if ANDROID_API_LEVEL >= 30 + case HAL_PIXEL_FORMAT_YCBCR_P010: + return DRM_FORMAT_P010; #endif } return DRM_FORMAT_NONE; } +static inline void handle_usage(uint64_t *gralloc_usage, uint64_t gralloc_mask, + uint64_t *bo_use_flags, uint64_t bo_mask) +{ + if ((*gralloc_usage) & gralloc_mask) { + (*gralloc_usage) &= ~gralloc_mask; + (*bo_use_flags) |= bo_mask; + } +} + +uint64_t cros_gralloc_convert_usage(uint64_t usage) +{ + uint64_t use_flags = BO_USE_NONE; + + /* + * GRALLOC_USAGE_SW_READ_OFTEN contains GRALLOC_USAGE_SW_READ_RARELY, thus OFTEN must be + * handled first. The same applies to GRALLOC_USAGE_SW_WRITE_OFTEN. + */ + handle_usage(&usage, GRALLOC_USAGE_SW_READ_OFTEN, &use_flags, BO_USE_SW_READ_OFTEN); + handle_usage(&usage, GRALLOC_USAGE_SW_READ_RARELY, &use_flags, BO_USE_SW_READ_RARELY); + handle_usage(&usage, GRALLOC_USAGE_SW_WRITE_OFTEN, &use_flags, BO_USE_SW_WRITE_OFTEN); + handle_usage(&usage, GRALLOC_USAGE_SW_WRITE_RARELY, &use_flags, BO_USE_SW_WRITE_RARELY); + handle_usage(&usage, GRALLOC_USAGE_HW_TEXTURE, &use_flags, BO_USE_TEXTURE); + handle_usage(&usage, GRALLOC_USAGE_HW_RENDER, &use_flags, BO_USE_RENDERING); + handle_usage(&usage, GRALLOC_USAGE_HW_2D, &use_flags, BO_USE_RENDERING); + /* HWC wants to use display hardware, but can defer to OpenGL. */ + handle_usage(&usage, GRALLOC_USAGE_HW_COMPOSER, &use_flags, + BO_USE_SCANOUT | BO_USE_TEXTURE); + handle_usage(&usage, GRALLOC_USAGE_HW_FB, &use_flags, BO_USE_NONE); + /* + * This flag potentially covers external display for the normal drivers (i915/rockchip) and + * usb monitors (evdi/udl). It's complicated so ignore it. + */ + handle_usage(&usage, GRALLOC_USAGE_EXTERNAL_DISP, &use_flags, BO_USE_NONE); + /* Map PROTECTED to linear until real HW protection is available on Android. */ + handle_usage(&usage, GRALLOC_USAGE_PROTECTED, &use_flags, BO_USE_LINEAR); + handle_usage(&usage, GRALLOC_USAGE_CURSOR, &use_flags, BO_USE_NONE); + /* HACK: See b/30054495 for BO_USE_SW_READ_OFTEN. */ + handle_usage(&usage, GRALLOC_USAGE_HW_VIDEO_ENCODER, &use_flags, + BO_USE_HW_VIDEO_ENCODER | BO_USE_SW_READ_OFTEN); + handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_WRITE, &use_flags, BO_USE_CAMERA_WRITE); + handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_READ, &use_flags, BO_USE_CAMERA_READ); + handle_usage(&usage, GRALLOC_USAGE_RENDERSCRIPT, &use_flags, BO_USE_RENDERSCRIPT); + handle_usage(&usage, BUFFER_USAGE_VIDEO_DECODER, &use_flags, BO_USE_HW_VIDEO_DECODER); + handle_usage(&usage, BUFFER_USAGE_GPU_DATA_BUFFER, &use_flags, BO_USE_GPU_DATA_BUFFER); + handle_usage(&usage, BUFFER_USAGE_FRONT_RENDERING, &use_flags, BO_USE_FRONT_RENDERING); + + if (usage) { + drv_log("Unhandled gralloc usage: %llx\n", (unsigned long long)usage); + return BO_USE_NONE; + } + + return use_flags; +} + +uint32_t cros_gralloc_convert_map_usage(uint64_t usage) +{ + uint32_t map_flags = BO_MAP_NONE; + + if (usage & GRALLOC_USAGE_SW_READ_MASK) + map_flags |= BO_MAP_READ; + if (usage & GRALLOC_USAGE_SW_WRITE_MASK) + map_flags |= BO_MAP_WRITE; + + return map_flags; +} + cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) { auto hnd = reinterpret_cast<cros_gralloc_handle_t>(handle); diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index a43833d..312d2f7 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -9,17 +9,38 @@ #include "../drv.h" #include "cros_gralloc_handle.h" -#include "cros_gralloc_types.h" #include <system/graphics.h> #include <system/window.h> +#include <string> + +// Reserve the GRALLOC_USAGE_PRIVATE_0 bit from hardware/gralloc.h for buffers +// used for front rendering. minigbm backend later decides to use +// BO_USE_FRONT_RENDERING or BO_USE_LINEAR upon buffer allocaton. +#define BUFFER_USAGE_FRONT_RENDERING (1U << 28) + +struct cros_gralloc_buffer_descriptor { + uint32_t width; + uint32_t height; + int32_t droid_format; + int32_t droid_usage; + uint32_t drm_format; + uint64_t use_flags; + uint64_t reserved_region_size; + std::string name; +}; + constexpr uint32_t cros_gralloc_magic = 0xABCDDCBA; constexpr uint32_t handle_data_size = ((sizeof(struct cros_gralloc_handle) - offsetof(cros_gralloc_handle, fds[0])) / sizeof(int)); uint32_t cros_gralloc_convert_format(int32_t format); +uint64_t cros_gralloc_convert_usage(uint64_t usage); + +uint32_t cros_gralloc_convert_map_usage(uint64_t usage); + cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence); diff --git a/cros_gralloc/cros_gralloc_types.h b/cros_gralloc/cros_gralloc_types.h deleted file mode 100644 index 22f58e2..0000000 --- a/cros_gralloc/cros_gralloc_types.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef CROS_GRALLOC_TYPES_H -#define CROS_GRALLOC_TYPES_H - -#include <string> - -struct cros_gralloc_buffer_descriptor { - uint32_t width; - uint32_t height; - int32_t droid_format; - int32_t droid_usage; - uint32_t drm_format; - uint64_t use_flags; - uint64_t reserved_region_size; - std::string name; -}; - -#endif diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 5899d5a..53c89fd 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -4,7 +4,6 @@ * found in the LICENSE file. */ -#include "../../helpers.h" #include "../../util.h" #include "../cros_gralloc_driver.h" @@ -15,7 +14,7 @@ struct gralloc0_module { gralloc_module_t base; std::unique_ptr<alloc_device_t> alloc; - std::unique_ptr<cros_gralloc_driver> driver; + cros_gralloc_driver *driver; bool initialized; std::mutex initialization_mutex; }; @@ -61,84 +60,8 @@ enum { }; // clang-format on -// Gralloc0 doesn't define a video decoder flag. However, the IAllocator gralloc0 -// passthrough gives the low 32-bits of the BufferUsage flags to gralloc0 in their -// entirety, so we can detect the video decoder flag passed by IAllocator clients. -#define BUFFER_USAGE_VIDEO_DECODER (1 << 22) - -// Reserve the GRALLOC_USAGE_PRIVATE_0 bit for buffers used for front rendering. -// minigbm backend later decides to use BO_USE_FRONT_RENDERING or BO_USE_LINEAR -// upon buffer allocaton. -#define BUFFER_USAGE_FRONT_RENDERING GRALLOC_USAGE_PRIVATE_0 - -static uint64_t gralloc0_convert_usage(int usage) -{ - uint64_t use_flags = BO_USE_NONE; - - if (usage & GRALLOC_USAGE_CURSOR) - use_flags |= BO_USE_NONE; - if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY) - use_flags |= BO_USE_SW_READ_RARELY; - if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) - use_flags |= BO_USE_SW_READ_OFTEN; - if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) - use_flags |= BO_USE_SW_WRITE_RARELY; - if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN) - use_flags |= BO_USE_SW_WRITE_OFTEN; - if (usage & GRALLOC_USAGE_HW_TEXTURE) - use_flags |= BO_USE_TEXTURE; - if (usage & GRALLOC_USAGE_HW_RENDER) - use_flags |= BO_USE_RENDERING; - if (usage & GRALLOC_USAGE_HW_2D) - use_flags |= BO_USE_RENDERING; - if (usage & GRALLOC_USAGE_HW_COMPOSER) - /* HWC wants to use display hardware, but can defer to OpenGL. */ - use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE; - if (usage & GRALLOC_USAGE_HW_FB) - use_flags |= BO_USE_NONE; - if (usage & GRALLOC_USAGE_EXTERNAL_DISP) - /* - * This flag potentially covers external display for the normal drivers (i915, - * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it. - * */ - use_flags |= BO_USE_NONE; - /* Map this flag to linear until real HW protection is available on Android. */ - if (usage & GRALLOC_USAGE_PROTECTED) - use_flags |= BO_USE_LINEAR; - if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { - use_flags |= BO_USE_HW_VIDEO_ENCODER; - /*HACK: See b/30054495 */ - use_flags |= BO_USE_SW_READ_OFTEN; - } - if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) - use_flags |= BO_USE_CAMERA_WRITE; - if (usage & GRALLOC_USAGE_HW_CAMERA_READ) - use_flags |= BO_USE_CAMERA_READ; - if (usage & GRALLOC_USAGE_RENDERSCRIPT) - use_flags |= BO_USE_RENDERSCRIPT; - if (usage & BUFFER_USAGE_VIDEO_DECODER) - use_flags |= BO_USE_HW_VIDEO_DECODER; - if (usage & BUFFER_USAGE_FRONT_RENDERING) - use_flags |= BO_USE_FRONT_RENDERING; - - return use_flags; -} - -static uint32_t gralloc0_convert_map_usage(int map_usage) -{ - uint32_t map_flags = BO_MAP_NONE; - - if (map_usage & GRALLOC_USAGE_SW_READ_MASK) - map_flags |= BO_MAP_READ; - if (map_usage & GRALLOC_USAGE_SW_WRITE_MASK) - map_flags |= BO_MAP_WRITE; - - return map_flags; -} - static int gralloc0_droid_yuv_format(int droid_format) { - return (droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888 || droid_format == HAL_PIXEL_FORMAT_YV12); } @@ -147,7 +70,6 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa buffer_handle_t *handle, int *stride) { int32_t ret; - bool supported; struct cros_gralloc_buffer_descriptor descriptor; auto mod = (struct gralloc0_module const *)dev->common.module; @@ -156,31 +78,10 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa descriptor.droid_format = format; descriptor.droid_usage = usage; descriptor.drm_format = cros_gralloc_convert_format(format); - descriptor.use_flags = gralloc0_convert_usage(usage); + descriptor.use_flags = cros_gralloc_convert_usage(usage); descriptor.reserved_region_size = 0; - supported = mod->driver->is_supported(&descriptor); - if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) { - descriptor.use_flags &= ~BO_USE_SCANOUT; - supported = mod->driver->is_supported(&descriptor); - } - if (!supported && (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && - format != HAL_PIXEL_FORMAT_YCbCr_420_888) { - // Unmask BO_USE_HW_VIDEO_ENCODER for other formats. They are mostly - // intermediate formats not passed directly to the encoder (e.g. - // camera). YV12 is passed to the encoder component, but it is converted - // to YCbCr_420_888 before being passed to the hw encoder. - descriptor.use_flags &= ~BO_USE_HW_VIDEO_ENCODER; - drv_log("Retrying format %u allocation without encoder flag", format); - supported = mod->driver->is_supported(&descriptor); - } - if (!supported && (usage & BUFFER_USAGE_FRONT_RENDERING)) { - descriptor.use_flags &= ~BO_USE_FRONT_RENDERING; - descriptor.use_flags |= BO_USE_LINEAR; - supported = mod->driver->is_supported(&descriptor); - } - - if (!supported) { + if (!mod->driver->is_supported(&descriptor)) { drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, " "drv_format: %4.4s, use_flags: %llu\n", format, usage, reinterpret_cast<char *>(&descriptor.drm_format), @@ -217,11 +118,9 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) if (mod->initialized) return 0; - mod->driver = std::make_unique<cros_gralloc_driver>(); - if (mod->driver->init()) { - drv_log("Failed to initialize driver.\n"); + mod->driver = cros_gralloc_driver::get_instance(); + if (!mod->driver) return -ENODEV; - } if (initialize_alloc) { mod->alloc = std::make_unique<alloc_device_t>(); @@ -381,20 +280,20 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) memset(info, 0, sizeof(*info)); info->drm_fourcc = drv_get_standard_fourcc(hnd->format); info->num_fds = hnd->num_planes; + for (int i = 0; i < info->num_fds; i++) + info->fds[i] = hnd->fds[i]; + ret = mod->driver->resource_info(handle, strides, offsets, &format_modifier); if (ret) break; info->modifier = format_modifier ? format_modifier : hnd->format_modifier; - for (uint32_t i = 0; i < hnd->num_planes; i++) { - info->fds[i] = hnd->fds[i]; - if (strides[i]) { - info->stride[i] = strides[i]; - info->offset[i] = offsets[i]; - } else { - info->stride[i] = hnd->strides[i]; - info->offset[i] = hnd->offsets[i]; - } + for (uint32_t i = 0; i < DRV_MAX_PLANES; i++) { + if (!strides[i]) + break; + + info->stride[i] = strides[i]; + info->offset[i] = offsets[i]; } break; case GRALLOC_DRM_GET_USAGE: @@ -453,7 +352,7 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han assert(w >= 0); assert(h >= 0); - map_flags = gralloc0_convert_map_usage(usage); + map_flags = cros_gralloc_convert_map_usage(static_cast<uint64_t>(usage)); ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr); *vaddr = addr[0]; return ret; @@ -505,7 +404,7 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff assert(w >= 0); assert(h >= 0); - map_flags = gralloc0_convert_map_usage(usage); + map_flags = cros_gralloc_convert_map_usage(static_cast<uint64_t>(usage)); ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr); if (ret) return ret; diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c index eea36e4..9d8101c 100644 --- a/cros_gralloc/gralloc0/tests/gralloctest.c +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -262,6 +262,8 @@ static struct gralloctest_context *test_init_gralloc() int err; hw_module_t const *hw_module; struct gralloctest_context *ctx = calloc(1, sizeof(*ctx)); + if (!ctx) + return NULL; err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module); if (err) diff --git a/cros_gralloc/gralloc3/.clang-format b/cros_gralloc/gralloc3/.clang-format deleted file mode 100644 index 534cd32..0000000 --- a/cros_gralloc/gralloc3/.clang-format +++ /dev/null @@ -1,19 +0,0 @@ -# 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 -Standard: Cpp11 -AccessModifierOffset: -2 -AllowShortFunctionsOnASingleLine: Inline -ColumnLimit: 100 -CommentPragmas: NOLINT:.* -DerivePointerAlignment: false -IncludeBlocks: Preserve -IndentWidth: 4 -ContinuationIndentWidth: 8 -PointerAlignment: Left -TabWidth: 4 -UseTab: Never
\ No newline at end of file diff --git a/cros_gralloc/gralloc3/Android.bp b/cros_gralloc/gralloc3/Android.bp deleted file mode 100644 index 6e36c5b..0000000 --- a/cros_gralloc/gralloc3/Android.bp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright (C) 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. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "external_minigbm_license" - // to get the below license kinds: - // SPDX-license-identifier-BSD - default_applicable_licenses: ["external_minigbm_license"], -} - -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_cros_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_cros_gralloc", - ], - - srcs: [ - "CrosGralloc3Mapper.cc", - "CrosGralloc3Utils.cc", - ], -} diff --git a/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc b/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc deleted file mode 100644 index 57c49e9..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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/CrosGralloc3Allocator.h" - -#include <optional> - -#include <android/hardware/graphics/mapper/3.0/IMapper.h> - -#include "cros_gralloc/cros_gralloc_helpers.h" -#include "cros_gralloc/gralloc3/CrosGralloc3Utils.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 BufferDescriptorInfo = - android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo; - -CrosGralloc3Allocator::CrosGralloc3Allocator() : 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, - hidl_handle* outHandle) { - if (!mDriver) { - drv_log("Failed to allocate. Driver is uninitialized.\n"); - return Error::NO_RESOURCES; - } - - if (!outStride || !outHandle) { - return Error::NO_RESOURCES; - } - - struct cros_gralloc_buffer_descriptor crosDescriptor; - if (convertToCrosDescriptor(descriptor, &crosDescriptor)) { - return Error::UNSUPPORTED; - } - - bool supported = mDriver->is_supported(&crosDescriptor); - if (!supported && (descriptor.usage & BufferUsage::COMPOSER_OVERLAY)) { - crosDescriptor.use_flags &= ~BO_USE_SCANOUT; - supported = mDriver->is_supported(&crosDescriptor); - } - - if (!supported) { - std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format); - std::string pixelFormatString = getPixelFormatString(descriptor.format); - std::string usageString = getUsageString(descriptor.usage); - drv_log("Unsupported combination -- pixel format: %s, drm format:%s, usage: %s\n", - pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str()); - return Error::UNSUPPORTED; - } - - buffer_handle_t handle; - int ret = mDriver->allocate(&crosDescriptor, &handle); - if (ret) { - return Error::NO_RESOURCES; - } - - cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle); - if (!crosHandle) { - return Error::NO_RESOURCES; - } - - *outHandle = handle; - *outStride = crosHandle->pixel_stride; - - return Error::NONE; -} - -Return<void> CrosGralloc3Allocator::allocate(const hidl_vec<uint32_t>& encoded, uint32_t count, - allocate_cb hidlCb) { - hidl_vec<hidl_handle> handles; - - if (!mDriver) { - drv_log("Failed to allocate. Driver is uninitialized.\n"); - hidlCb(Error::NO_RESOURCES, 0, handles); - return Void(); - } - - auto descriptor_opt = decodeBufferDescriptorInfo(encoded); - if (!descriptor_opt) { - drv_log("Failed to allocate. Failed to decode buffer descriptor.\n"); - 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])); - if (err != Error::NONE) { - for (int j = 0; j < i; j++) { - mDriver->release(handles[j].getNativeHandle()); - } - handles.resize(0); - hidlCb(err, 0, handles); - return Void(); - } - } - - hidlCb(Error::NONE, stride, handles); - - for (const hidl_handle& handle : handles) { - mDriver->release(handle.getNativeHandle()); - } - - return Void(); -} - -Return<void> CrosGralloc3Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) { - hidl_cb("CrosGralloc3Allocator::dumpDebugInfo unimplemented."); - return Void(); -} diff --git a/cros_gralloc/gralloc3/CrosGralloc3Allocator.h b/cros_gralloc/gralloc3/CrosGralloc3Allocator.h deleted file mode 100644 index 655143c..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3Allocator.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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; -}; diff --git a/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc b/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc deleted file mode 100644 index daab508..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ - -#define LOG_TAG "AllocatorService" - -#include <hidl/LegacySupport.h> - -#include "cros_gralloc/gralloc3/CrosGralloc3Allocator.h" - -using android::sp; -using android::hardware::configureRpcThreadpool; -using android::hardware::joinRpcThreadpool; -using android::hardware::graphics::allocator::V3_0::IAllocator; - -int main(int, char**) { - sp<IAllocator> allocator = new CrosGralloc3Allocator(); - configureRpcThreadpool(4, true /* callerWillJoin */); - if (allocator->registerAsService() != android::NO_ERROR) { - ALOGE("failed to register graphics IAllocator 3.0 service"); - return -EINVAL; - } - - ALOGI("graphics IAllocator 3.0 service is initialized"); - android::hardware::joinRpcThreadpool(); - ALOGI("graphics IAllocator 3.0 service is terminating"); - return 0; -} diff --git a/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc b/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc deleted file mode 100644 index 08da016..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc +++ /dev/null @@ -1,490 +0,0 @@ -/* - * 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/cros_gralloc_helpers.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 = get_drm_format_string(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 -EINVAL; - } - - 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 -EINVAL; - } - - uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage); - if (resolvedDrmFormat == DRM_FORMAT_INVALID) { - std::string drmFormatString = get_drm_format_string(drmFormat); - drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n", - drmFormatString.c_str()); - return -EINVAL; - } - - *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); -} diff --git a/cros_gralloc/gralloc3/CrosGralloc3Mapper.h b/cros_gralloc/gralloc3/CrosGralloc3Mapper.h deleted file mode 100644 index 7ec92d5..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3Mapper.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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); diff --git a/cros_gralloc/gralloc3/CrosGralloc3Utils.cc b/cros_gralloc/gralloc3/CrosGralloc3Utils.cc deleted file mode 100644 index 3f39305..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3Utils.cc +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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/CrosGralloc3Utils.h" - -#include <array> -#include <limits> -#include <unordered_map> - -#include <android-base/stringprintf.h> -#include <android-base/strings.h> -#include <cutils/native_handle.h> - -#include "cros_gralloc/cros_gralloc_helpers.h" - -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; - -std::string getPixelFormatString(PixelFormat format) { - switch (format) { - case PixelFormat::BGRA_8888: - return "PixelFormat::BGRA_8888"; - case PixelFormat::BLOB: - return "PixelFormat::BLOB"; - case PixelFormat::DEPTH_16: - return "PixelFormat::DEPTH_16"; - case PixelFormat::DEPTH_24: - return "PixelFormat::DEPTH_24"; - case PixelFormat::DEPTH_24_STENCIL_8: - return "PixelFormat::DEPTH_24_STENCIL_8"; - case PixelFormat::DEPTH_32F: - return "PixelFormat::DEPTH_24"; - case PixelFormat::DEPTH_32F_STENCIL_8: - return "PixelFormat::DEPTH_24_STENCIL_8"; - case PixelFormat::HSV_888: - return "PixelFormat::HSV_888"; - case PixelFormat::IMPLEMENTATION_DEFINED: - return "PixelFormat::IMPLEMENTATION_DEFINED"; - case PixelFormat::RAW10: - return "PixelFormat::RAW10"; - case PixelFormat::RAW12: - return "PixelFormat::RAW12"; - case PixelFormat::RAW16: - return "PixelFormat::RAW16"; - case PixelFormat::RAW_OPAQUE: - return "PixelFormat::RAW_OPAQUE"; - case PixelFormat::RGBA_1010102: - return "PixelFormat::RGBA_1010102"; - case PixelFormat::RGBA_8888: - return "PixelFormat::RGBA_8888"; - case PixelFormat::RGBA_FP16: - return "PixelFormat::RGBA_FP16"; - case PixelFormat::RGBX_8888: - return "PixelFormat::RGBX_8888"; - case PixelFormat::RGB_565: - return "PixelFormat::RGB_565"; - case PixelFormat::RGB_888: - return "PixelFormat::RGB_888"; - case PixelFormat::STENCIL_8: - return "PixelFormat::STENCIL_8"; - case PixelFormat::Y16: - return "PixelFormat::Y16"; - case PixelFormat::Y8: - return "PixelFormat::Y8"; - case PixelFormat::YCBCR_420_888: - return "PixelFormat::YCBCR_420_888"; - case PixelFormat::YCBCR_422_I: - return "PixelFormat::YCBCR_422_I"; - case PixelFormat::YCBCR_422_SP: - return "PixelFormat::YCBCR_422_SP"; - case PixelFormat::YCBCR_P010: - return "PixelFormat::YCBCR_P010"; - case PixelFormat::YCRCB_420_SP: - return "PixelFormat::YCRCB_420_SP"; - case PixelFormat::YV12: - return "PixelFormat::YV12"; - } - return android::base::StringPrintf("PixelFormat::Unknown(%d)", static_cast<uint32_t>(format)); -} - -std::string getUsageString(hidl_bitfield<BufferUsage> bufferUsage) { - using Underlying = typename std::underlying_type<BufferUsage>::type; - - Underlying usage = static_cast<Underlying>(bufferUsage); - - std::vector<std::string> usages; - if (usage & BufferUsage::CAMERA_INPUT) { - usage &= ~static_cast<Underlying>(BufferUsage::CAMERA_INPUT); - usages.push_back("BufferUsage::CAMERA_INPUT"); - } - if (usage & BufferUsage::CAMERA_OUTPUT) { - usage &= ~static_cast<Underlying>(BufferUsage::CAMERA_OUTPUT); - usages.push_back("BufferUsage::CAMERA_OUTPUT"); - } - if (usage & BufferUsage::COMPOSER_CURSOR) { - usage &= ~static_cast<Underlying>(BufferUsage::COMPOSER_CURSOR); - usages.push_back("BufferUsage::COMPOSER_CURSOR"); - } - if (usage & BufferUsage::COMPOSER_OVERLAY) { - usage &= ~static_cast<Underlying>(BufferUsage::COMPOSER_OVERLAY); - usages.push_back("BufferUsage::COMPOSER_OVERLAY"); - } - if (usage & BufferUsage::CPU_READ_OFTEN) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_READ_OFTEN); - usages.push_back("BufferUsage::CPU_READ_OFTEN"); - } - if (usage & BufferUsage::CPU_READ_NEVER) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_READ_NEVER); - usages.push_back("BufferUsage::CPU_READ_NEVER"); - } - if (usage & BufferUsage::CPU_READ_RARELY) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_READ_RARELY); - usages.push_back("BufferUsage::CPU_READ_RARELY"); - } - if (usage & BufferUsage::CPU_WRITE_NEVER) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_WRITE_NEVER); - usages.push_back("BufferUsage::CPU_WRITE_NEVER"); - } - if (usage & BufferUsage::CPU_WRITE_OFTEN) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_WRITE_OFTEN); - usages.push_back("BufferUsage::CPU_WRITE_OFTEN"); - } - if (usage & BufferUsage::CPU_WRITE_RARELY) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_WRITE_RARELY); - usages.push_back("BufferUsage::CPU_WRITE_RARELY"); - } - if (usage & BufferUsage::GPU_RENDER_TARGET) { - usage &= ~static_cast<Underlying>(BufferUsage::GPU_RENDER_TARGET); - usages.push_back("BufferUsage::GPU_RENDER_TARGET"); - } - if (usage & BufferUsage::GPU_TEXTURE) { - usage &= ~static_cast<Underlying>(BufferUsage::GPU_TEXTURE); - usages.push_back("BufferUsage::GPU_TEXTURE"); - } - if (usage & BufferUsage::PROTECTED) { - usage &= ~static_cast<Underlying>(BufferUsage::PROTECTED); - usages.push_back("BufferUsage::PROTECTED"); - } - if (usage & BufferUsage::RENDERSCRIPT) { - usage &= ~static_cast<Underlying>(BufferUsage::RENDERSCRIPT); - usages.push_back("BufferUsage::RENDERSCRIPT"); - } - if (usage & BufferUsage::VIDEO_DECODER) { - usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_DECODER); - usages.push_back("BufferUsage::VIDEO_DECODER"); - } - if (usage & BufferUsage::VIDEO_ENCODER) { - usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_ENCODER); - usages.push_back("BufferUsage::VIDEO_ENCODER"); - } - - if (usage) { - usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage)); - } - - return android::base::Join(usages, '|'); -} - -int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) { - switch (format) { - case PixelFormat::BGRA_8888: - *outDrmFormat = DRM_FORMAT_ARGB8888; - return 0; - /** - * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers - * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width - * equal to their size in bytes. - */ - case PixelFormat::BLOB: - *outDrmFormat = DRM_FORMAT_R8; - return 0; - case PixelFormat::DEPTH_16: - return -EINVAL; - case PixelFormat::DEPTH_24: - return -EINVAL; - case PixelFormat::DEPTH_24_STENCIL_8: - return -EINVAL; - case PixelFormat::DEPTH_32F: - return -EINVAL; - case PixelFormat::DEPTH_32F_STENCIL_8: - return -EINVAL; - case PixelFormat::HSV_888: - return -EINVAL; - case PixelFormat::IMPLEMENTATION_DEFINED: - *outDrmFormat = DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; - return 0; - case PixelFormat::RAW10: - return -EINVAL; - case PixelFormat::RAW12: - return -EINVAL; - case PixelFormat::RAW16: - *outDrmFormat = DRM_FORMAT_R16; - return 0; - /* TODO use blob */ - case PixelFormat::RAW_OPAQUE: - return -EINVAL; - case PixelFormat::RGBA_1010102: - *outDrmFormat = DRM_FORMAT_ABGR2101010; - return 0; - case PixelFormat::RGBA_8888: - *outDrmFormat = DRM_FORMAT_ABGR8888; - return 0; - case PixelFormat::RGBA_FP16: - *outDrmFormat = DRM_FORMAT_ABGR16161616F; - return 0; - case PixelFormat::RGBX_8888: - *outDrmFormat = DRM_FORMAT_XBGR8888; - return 0; - case PixelFormat::RGB_565: - *outDrmFormat = DRM_FORMAT_RGB565; - return 0; - case PixelFormat::RGB_888: - *outDrmFormat = DRM_FORMAT_RGB888; - return 0; - case PixelFormat::STENCIL_8: - return -EINVAL; - case PixelFormat::Y16: - *outDrmFormat = DRM_FORMAT_R16; - return 0; - case PixelFormat::Y8: - *outDrmFormat = DRM_FORMAT_R8; - return 0; - case PixelFormat::YCBCR_420_888: - *outDrmFormat = DRM_FORMAT_FLEX_YCbCr_420_888; - return 0; - case PixelFormat::YCBCR_422_SP: - return -EINVAL; - case PixelFormat::YCBCR_422_I: - return -EINVAL; - case PixelFormat::YCBCR_P010: - *outDrmFormat = DRM_FORMAT_P010; - return 0; - case PixelFormat::YCRCB_420_SP: - *outDrmFormat = DRM_FORMAT_NV21; - return 0; - case PixelFormat::YV12: - *outDrmFormat = DRM_FORMAT_YVU420_ANDROID; - return 0; - }; - return -EINVAL; -} - -int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) { - uint64_t bufferUsage = BO_USE_NONE; - - if ((grallocUsage & BufferUsage::CPU_READ_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) { - bufferUsage |= BO_USE_SW_READ_RARELY; - } - if ((grallocUsage & BufferUsage::CPU_READ_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN)) { - bufferUsage |= BO_USE_SW_READ_OFTEN; - } - if ((grallocUsage & BufferUsage::CPU_WRITE_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) { - bufferUsage |= BO_USE_SW_WRITE_RARELY; - } - if ((grallocUsage & BufferUsage::CPU_WRITE_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN)) { - bufferUsage |= BO_USE_SW_WRITE_OFTEN; - } - if (grallocUsage & BufferUsage::GPU_TEXTURE) { - bufferUsage |= BO_USE_TEXTURE; - } - if (grallocUsage & BufferUsage::GPU_RENDER_TARGET) { - bufferUsage |= BO_USE_RENDERING; - } - if (grallocUsage & BufferUsage::COMPOSER_OVERLAY) { - /* HWC wants to use display hardware, but can defer to OpenGL. */ - bufferUsage |= BO_USE_SCANOUT | BO_USE_TEXTURE; - } - /* Map this flag to linear until real HW protection is available on Android. */ - if (grallocUsage & BufferUsage::PROTECTED) { - bufferUsage |= BO_USE_LINEAR; - } - if (grallocUsage & BufferUsage::COMPOSER_CURSOR) { - bufferUsage |= BO_USE_NONE; - } - if (grallocUsage & BufferUsage::VIDEO_ENCODER) { - /*HACK: See b/30054495 */ - bufferUsage |= BO_USE_SW_READ_OFTEN; - } - if (grallocUsage & BufferUsage::CAMERA_OUTPUT) { - bufferUsage |= BO_USE_CAMERA_WRITE; - } - if (grallocUsage & BufferUsage::CAMERA_INPUT) { - bufferUsage |= BO_USE_CAMERA_READ; - } - if (grallocUsage & BufferUsage::RENDERSCRIPT) { - bufferUsage |= BO_USE_RENDERSCRIPT; - } - if (grallocUsage & BufferUsage::VIDEO_DECODER) { - bufferUsage |= BO_USE_HW_VIDEO_DECODER; - } - - *outBufferUsage = bufferUsage; - 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->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; - if (descriptor.layerCount > 1) { - drv_log("Failed to convert descriptor. Unsupported layerCount: %d\n", - descriptor.layerCount); - return -EINVAL; - } - 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()); - return -EINVAL; - } - if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) { - std::string usageString = getUsageString(descriptor.usage); - drv_log("Failed to convert descriptor. Unsupported usage flags %s\n", usageString.c_str()); - return -EINVAL; - } - return 0; -} - -int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) { - if (!outFenceFd) { - return -EINVAL; - } - - const native_handle_t* nativeHandle = fenceHandle.getNativeHandle(); - if (nativeHandle && nativeHandle->numFds > 1) { - return -EINVAL; - } - - *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1; - return 0; -} - -int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) { - if (!outFenceHandle) { - return -EINVAL; - } - if (fenceFd < 0) { - return 0; - } - - NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0); - auto fenceHandle = native_handle_init(handleStorage, 1, 0); - fenceHandle->data[0] = fenceFd; - - *outFenceHandle = fenceHandle; - 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 {}; - } - - 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); -} - -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); -} diff --git a/cros_gralloc/gralloc3/CrosGralloc3Utils.h b/cros_gralloc/gralloc3/CrosGralloc3Utils.h deleted file mode 100644 index 0492568..0000000 --- a/cros_gralloc/gralloc3/CrosGralloc3Utils.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 <optional> -#include <string> -#include <vector> - -#include <android/hardware/graphics/common/1.2/types.h> -#include <android/hardware/graphics/mapper/3.0/IMapper.h> - -std::string getPixelFormatString(android::hardware::graphics::common::V1_2::PixelFormat format); - -std::string getUsageString( - android::hardware::hidl_bitfield<android::hardware::graphics::common::V1_2::BufferUsage> - usage); - -int convertToDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat format, - uint32_t* outDrmFormat); - -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, - struct cros_gralloc_buffer_descriptor* outCrosDescriptor); - -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); diff --git a/cros_gralloc/gralloc3/android.hardware.graphics.allocator@3.0-service.minigbm.rc b/cros_gralloc/gralloc3/android.hardware.graphics.allocator@3.0-service.minigbm.rc deleted file mode 100644 index 7377cee..0000000 --- a/cros_gralloc/gralloc3/android.hardware.graphics.allocator@3.0-service.minigbm.rc +++ /dev/null @@ -1,14 +0,0 @@ -# -# 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 diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android.bp index 4d2b542..b779704 100644 --- a/cros_gralloc/gralloc4/Android.bp +++ b/cros_gralloc/gralloc4/Android.bp @@ -23,108 +23,125 @@ package { default_applicable_licenses: ["external_minigbm_license"], } -cc_defaults { - name: "service_minigbm_defaults", - relative_install_path: "hw", - vendor: true, - - vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], +filegroup { + name: "minigbm_gralloc4_allocator_files", + srcs: [ + "CrosGralloc4Allocator.cc", + "CrosGralloc4AllocatorService.cc", + "CrosGralloc4Utils.cc", + ], +} - cflags: [ - "-Wall", - "-Werror", +filegroup { + name: "minigbm_gralloc4_mapper_files", + srcs: [ + "CrosGralloc4Mapper.cc", + "CrosGralloc4Utils.cc", ], +} + +cc_defaults { + name: "minigbm_gralloc4_common_defaults", + defaults: ["minigbm_cros_gralloc_defaults"], shared_libs: [ - "android.hardware.graphics.allocator@4.0", "android.hardware.graphics.mapper@4.0", - "libbase", - "libcutils", "libgralloctypes", "libhidlbase", - "liblog", - "libsync", + "libbase", "libutils", ], - static_libs: [ - "libdrm", - ], + cflags: ["-Wno-sign-compare"], + relative_install_path: "hw", +} - srcs: [ - "CrosGralloc4Allocator.cc", - "CrosGralloc4AllocatorService.cc", - "CrosGralloc4Utils.cc", - ], +cc_defaults { + name: "minigbm_gralloc4_allocator_defaults", + defaults: ["minigbm_gralloc4_common_defaults"], + + shared_libs: ["android.hardware.graphics.allocator@4.0"], + srcs: [":minigbm_gralloc4_allocator_files"], } cc_binary { name: "android.hardware.graphics.allocator@4.0-service.minigbm", + defaults: ["minigbm_gralloc4_allocator_defaults"], + shared_libs: ["libminigbm_gralloc"], + vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm.rc"], - defaults: ["service_minigbm_defaults"], - static_libs: [ - "libminigbm_cros_gralloc", - ], } cc_binary { name: "android.hardware.graphics.allocator@4.0-service.minigbm_msm", + defaults: ["minigbm_gralloc4_allocator_defaults"], + shared_libs: ["libminigbm_gralloc_msm"], + vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc"], - defaults: ["service_minigbm_defaults"], - static_libs: [ - "libminigbm_cros_gralloc_msm", - ], } -cc_defaults { - name: "impl_minigbm_defaults", - relative_install_path: "hw", - vendor: true, - - vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], - - cflags: [ - "-Wall", - "-Werror", - ], - - shared_libs: [ - "android.hardware.graphics.mapper@4.0", - "libbase", - "libcutils", - "libgralloctypes", - "libhidlbase", - "liblog", - "libsync", - "libutils", - ], - - static_libs: [ - "libdrm", - ], +cc_binary { + name: "android.hardware.graphics.allocator@4.0-service.minigbm_arcvm", + defaults: ["minigbm_gralloc4_allocator_defaults"], + shared_libs: ["libminigbm_gralloc_arcvm"], + vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], + init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_arcvm.rc"], +} - srcs: [ - "CrosGralloc4Mapper.cc", - "CrosGralloc4Utils.cc", - ], +cc_binary { + name: "android.hardware.graphics.allocator@4.0-service.minigbm_intel", + defaults: ["minigbm_gralloc4_allocator_defaults"], + shared_libs: ["libminigbm_gralloc_intel"], + vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], + init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_intel.rc"], + enabled: false, + arch: { + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, + }, } cc_library_shared { name: "android.hardware.graphics.mapper@4.0-impl.minigbm", - defaults: ["impl_minigbm_defaults"], - - static_libs: [ - "libminigbm_cros_gralloc", - ], - + defaults: ["minigbm_gralloc4_common_defaults"], + shared_libs: ["libminigbm_gralloc"], + vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], + srcs: [":minigbm_gralloc4_mapper_files"], } cc_library_shared { name: "android.hardware.graphics.mapper@4.0-impl.minigbm_msm", - defaults: ["impl_minigbm_defaults"], + defaults: ["minigbm_gralloc4_common_defaults"], + shared_libs: ["libminigbm_gralloc_msm"], + vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], + srcs: [":minigbm_gralloc4_mapper_files"], +} - static_libs: [ - "libminigbm_cros_gralloc_msm", - ], +cc_library_shared { + name: "android.hardware.graphics.mapper@4.0-impl.minigbm_arcvm", + defaults: ["minigbm_gralloc4_common_defaults"], + shared_libs: ["libminigbm_gralloc_arcvm"], + vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], + srcs: [":minigbm_gralloc4_mapper_files"], +} +cc_library_shared { + name: "android.hardware.graphics.mapper@4.0-impl.minigbm_intel", + defaults: ["minigbm_gralloc4_common_defaults"], + shared_libs: ["libminigbm_gralloc_intel"], + vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], + srcs: [":minigbm_gralloc4_mapper_files"], + enabled: false, + arch: { + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, + }, } diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc index e7e5f3a..0368e1a 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc @@ -23,11 +23,9 @@ using android::hardware::graphics::mapper::V4_0::Error; using BufferDescriptorInfo = android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo; -CrosGralloc4Allocator::CrosGralloc4Allocator() : mDriver(std::make_unique<cros_gralloc_driver>()) { - if (mDriver->init()) { - drv_log("Failed to initialize driver.\n"); - mDriver = nullptr; - } +Error CrosGralloc4Allocator::init() { + mDriver = cros_gralloc_driver::get_instance(); + return mDriver ? Error::NONE : Error::NO_RESOURCES; } Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride, @@ -46,13 +44,7 @@ Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, ui return Error::UNSUPPORTED; } - bool supported = mDriver->is_supported(&crosDescriptor); - if (!supported && (descriptor.usage & BufferUsage::COMPOSER_OVERLAY)) { - crosDescriptor.use_flags &= ~BO_USE_SCANOUT; - supported = mDriver->is_supported(&crosDescriptor); - } - - if (!supported) { + if (!mDriver->is_supported(&crosDescriptor)) { std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format); std::string pixelFormatString = getPixelFormatString(descriptor.format); std::string usageString = getUsageString(descriptor.usage); diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h index 21ad7ad..1555a61 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h @@ -11,16 +11,18 @@ class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_0::IAllocator { public: - CrosGralloc4Allocator(); + CrosGralloc4Allocator() = default; android::hardware::Return<void> allocate(const android::hardware::hidl_vec<uint8_t>& descriptor, uint32_t count, allocate_cb hidl_cb) override; + android::hardware::graphics::mapper::V4_0::Error init(); + 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; + cros_gralloc_driver* mDriver = nullptr; }; diff --git a/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc b/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc index 5b79860..99bc92e 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc @@ -13,18 +13,23 @@ using android::sp; using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; -using android::hardware::graphics::allocator::V4_0::IAllocator; +using android::hardware::graphics::mapper::V4_0::Error; int main(int, char**) { - sp<IAllocator> allocator = new CrosGralloc4Allocator(); + sp<CrosGralloc4Allocator> allocator = new CrosGralloc4Allocator(); + if (allocator->init() != Error::NONE) { + ALOGE("Failed to initialize IAllocator 4.0 service."); + return -EINVAL; + } + configureRpcThreadpool(4, true /* callerWillJoin */); if (allocator->registerAsService() != android::NO_ERROR) { - ALOGE("failed to register graphics IAllocator 4.0 service"); + ALOGE("Failed to register graphics IAllocator 4.0 service."); return -EINVAL; } - ALOGI("graphics IAllocator 4.0 service is initialized"); + ALOGI("IAllocator 4.0 service is initialized."); android::hardware::joinRpcThreadpool(); - ALOGI("graphics IAllocator 4.0 service is terminating"); + ALOGI("IAllocator 4.0 service is terminating."); return 0; } diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc index 1bfd442..8f952e1 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc @@ -16,8 +16,6 @@ #include "cros_gralloc/cros_gralloc_helpers.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; @@ -31,62 +29,6 @@ using android::hardware::graphics::common::V1_2::PixelFormat; using android::hardware::graphics::mapper::V4_0::Error; using android::hardware::graphics::mapper::V4_0::IMapper; -namespace { - -// Provides a single instance of cros_gralloc_driver to all active instances of -// CrosGralloc4Mapper in a single process while destroying the cros_gralloc_driver -// when there are no active instances of CrosGralloc4Mapper. -class DriverProvider { - public: - static DriverProvider* Get() { - static DriverProvider* instance = new DriverProvider(); - return instance; - } - - cros_gralloc_driver* GetAndReferenceDriver() { - std::lock_guard<std::mutex> lock(mMutex); - if (!mDriver) { - mDriver = std::make_unique<cros_gralloc_driver>(); - if (mDriver->init()) { - drv_log("Failed to initialize driver.\n"); - mDriver.reset(); - return nullptr; - } - } - - ++mReferenceCount; - return mDriver.get(); - } - - void UnreferenceDriver() { - std::lock_guard<std::mutex> lock(mMutex); - - --mReferenceCount; - - if (mReferenceCount == 0) { - mDriver.reset(); - } - } - - private: - DriverProvider() = default; - - std::mutex mMutex; - std::unique_ptr<cros_gralloc_driver> mDriver; - std::size_t mReferenceCount = 0; -}; - -} // namespace - -CrosGralloc4Mapper::CrosGralloc4Mapper() { - mDriver = DriverProvider::Get()->GetAndReferenceDriver(); -} - -CrosGralloc4Mapper::~CrosGralloc4Mapper() { - mDriver = nullptr; - DriverProvider::Get()->UnreferenceDriver(); -} - Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& description, createDescriptor_cb hidlCb) { hidl_vec<uint8_t> descriptor; @@ -448,13 +390,7 @@ Return<void> CrosGralloc4Mapper::isSupported(const BufferDescriptorInfo& descrip 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); + hidlCb(Error::NONE, mDriver->is_supported(&crosDescriptor)); return Void(); } diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h index 3c159a2..0641b29 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h @@ -11,8 +11,7 @@ class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMapper { public: - CrosGralloc4Mapper(); - ~CrosGralloc4Mapper(); + CrosGralloc4Mapper() = default; android::hardware::Return<void> createDescriptor(const BufferDescriptorInfo& description, createDescriptor_cb hidlCb) override; @@ -75,7 +74,7 @@ class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMa int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat, uint64_t bufferUsage, uint32_t* outDrmFormat); - cros_gralloc_driver* mDriver = nullptr; + cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance(); }; extern "C" android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* name); diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc index 9bc27cb..63ec8af 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc @@ -30,283 +30,28 @@ using BufferDescriptorInfo = android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo; std::string getPixelFormatString(PixelFormat format) { - switch (format) { - case PixelFormat::BGRA_8888: - return "PixelFormat::BGRA_8888"; - case PixelFormat::BLOB: - return "PixelFormat::BLOB"; - case PixelFormat::DEPTH_16: - return "PixelFormat::DEPTH_16"; - case PixelFormat::DEPTH_24: - return "PixelFormat::DEPTH_24"; - case PixelFormat::DEPTH_24_STENCIL_8: - return "PixelFormat::DEPTH_24_STENCIL_8"; - case PixelFormat::DEPTH_32F: - return "PixelFormat::DEPTH_24"; - case PixelFormat::DEPTH_32F_STENCIL_8: - return "PixelFormat::DEPTH_24_STENCIL_8"; - case PixelFormat::HSV_888: - return "PixelFormat::HSV_888"; - case PixelFormat::IMPLEMENTATION_DEFINED: - return "PixelFormat::IMPLEMENTATION_DEFINED"; - case PixelFormat::RAW10: - return "PixelFormat::RAW10"; - case PixelFormat::RAW12: - return "PixelFormat::RAW12"; - case PixelFormat::RAW16: - return "PixelFormat::RAW16"; - case PixelFormat::RAW_OPAQUE: - return "PixelFormat::RAW_OPAQUE"; - case PixelFormat::RGBA_1010102: - return "PixelFormat::RGBA_1010102"; - case PixelFormat::RGBA_8888: - return "PixelFormat::RGBA_8888"; - case PixelFormat::RGBA_FP16: - return "PixelFormat::RGBA_FP16"; - case PixelFormat::RGBX_8888: - return "PixelFormat::RGBX_8888"; - case PixelFormat::RGB_565: - return "PixelFormat::RGB_565"; - case PixelFormat::RGB_888: - return "PixelFormat::RGB_888"; - case PixelFormat::STENCIL_8: - return "PixelFormat::STENCIL_8"; - case PixelFormat::Y16: - return "PixelFormat::Y16"; - case PixelFormat::Y8: - return "PixelFormat::Y8"; - case PixelFormat::YCBCR_420_888: - return "PixelFormat::YCBCR_420_888"; - case PixelFormat::YCBCR_422_I: - return "PixelFormat::YCBCR_422_I"; - case PixelFormat::YCBCR_422_SP: - return "PixelFormat::YCBCR_422_SP"; - case PixelFormat::YCBCR_P010: - return "PixelFormat::YCBCR_P010"; - case PixelFormat::YCRCB_420_SP: - return "PixelFormat::YCRCB_420_SP"; - case PixelFormat::YV12: - return "PixelFormat::YV12"; - } - return android::base::StringPrintf("PixelFormat::Unknown(%d)", static_cast<uint32_t>(format)); + return android::hardware::graphics::common::V1_2::toString(format); } std::string getUsageString(hidl_bitfield<BufferUsage> bufferUsage) { - using Underlying = typename std::underlying_type<BufferUsage>::type; - - Underlying usage = static_cast<Underlying>(bufferUsage); - - std::vector<std::string> usages; - if (usage & BufferUsage::CAMERA_INPUT) { - usage &= ~static_cast<Underlying>(BufferUsage::CAMERA_INPUT); - usages.push_back("BufferUsage::CAMERA_INPUT"); - } - if (usage & BufferUsage::CAMERA_OUTPUT) { - usage &= ~static_cast<Underlying>(BufferUsage::CAMERA_OUTPUT); - usages.push_back("BufferUsage::CAMERA_OUTPUT"); - } - if (usage & BufferUsage::COMPOSER_CURSOR) { - usage &= ~static_cast<Underlying>(BufferUsage::COMPOSER_CURSOR); - usages.push_back("BufferUsage::COMPOSER_CURSOR"); - } - if (usage & BufferUsage::COMPOSER_OVERLAY) { - usage &= ~static_cast<Underlying>(BufferUsage::COMPOSER_OVERLAY); - usages.push_back("BufferUsage::COMPOSER_OVERLAY"); - } - if (usage & BufferUsage::CPU_READ_OFTEN) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_READ_OFTEN); - usages.push_back("BufferUsage::CPU_READ_OFTEN"); - } - if (usage & BufferUsage::CPU_READ_NEVER) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_READ_NEVER); - usages.push_back("BufferUsage::CPU_READ_NEVER"); - } - if (usage & BufferUsage::CPU_READ_RARELY) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_READ_RARELY); - usages.push_back("BufferUsage::CPU_READ_RARELY"); - } - if (usage & BufferUsage::CPU_WRITE_NEVER) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_WRITE_NEVER); - usages.push_back("BufferUsage::CPU_WRITE_NEVER"); - } - if (usage & BufferUsage::CPU_WRITE_OFTEN) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_WRITE_OFTEN); - usages.push_back("BufferUsage::CPU_WRITE_OFTEN"); - } - if (usage & BufferUsage::CPU_WRITE_RARELY) { - usage &= ~static_cast<Underlying>(BufferUsage::CPU_WRITE_RARELY); - usages.push_back("BufferUsage::CPU_WRITE_RARELY"); - } - if (usage & BufferUsage::GPU_RENDER_TARGET) { - usage &= ~static_cast<Underlying>(BufferUsage::GPU_RENDER_TARGET); - usages.push_back("BufferUsage::GPU_RENDER_TARGET"); - } - if (usage & BufferUsage::GPU_TEXTURE) { - usage &= ~static_cast<Underlying>(BufferUsage::GPU_TEXTURE); - usages.push_back("BufferUsage::GPU_TEXTURE"); - } - if (usage & BufferUsage::PROTECTED) { - usage &= ~static_cast<Underlying>(BufferUsage::PROTECTED); - usages.push_back("BufferUsage::PROTECTED"); - } - if (usage & BufferUsage::RENDERSCRIPT) { - usage &= ~static_cast<Underlying>(BufferUsage::RENDERSCRIPT); - usages.push_back("BufferUsage::RENDERSCRIPT"); - } - if (usage & BufferUsage::VIDEO_DECODER) { - usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_DECODER); - usages.push_back("BufferUsage::VIDEO_DECODER"); - } - if (usage & BufferUsage::VIDEO_ENCODER) { - usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_ENCODER); - usages.push_back("BufferUsage::VIDEO_ENCODER"); - } - - if (usage) { - usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage)); - } + static_assert(std::is_same<std::underlying_type<BufferUsage>::type, uint64_t>::value); - return android::base::Join(usages, '|'); + const uint64_t usage = static_cast<uint64_t>(bufferUsage); + return android::hardware::graphics::common::V1_2::toString<BufferUsage>(usage); } int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) { - switch (format) { - case PixelFormat::BGRA_8888: - *outDrmFormat = DRM_FORMAT_ARGB8888; - return 0; - /** - * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers - * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width - * equal to their size in bytes. - */ - case PixelFormat::BLOB: - *outDrmFormat = DRM_FORMAT_R8; - return 0; - case PixelFormat::DEPTH_16: - return -EINVAL; - case PixelFormat::DEPTH_24: - return -EINVAL; - case PixelFormat::DEPTH_24_STENCIL_8: - return -EINVAL; - case PixelFormat::DEPTH_32F: - return -EINVAL; - case PixelFormat::DEPTH_32F_STENCIL_8: - return -EINVAL; - case PixelFormat::HSV_888: - return -EINVAL; - case PixelFormat::IMPLEMENTATION_DEFINED: - *outDrmFormat = DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; - return 0; - case PixelFormat::RAW10: - return -EINVAL; - case PixelFormat::RAW12: - return -EINVAL; - case PixelFormat::RAW16: - *outDrmFormat = DRM_FORMAT_R16; - return 0; - /* TODO use blob */ - case PixelFormat::RAW_OPAQUE: - return -EINVAL; - case PixelFormat::RGBA_1010102: - *outDrmFormat = DRM_FORMAT_ABGR2101010; - return 0; - case PixelFormat::RGBA_8888: - *outDrmFormat = DRM_FORMAT_ABGR8888; - return 0; - case PixelFormat::RGBA_FP16: - *outDrmFormat = DRM_FORMAT_ABGR16161616F; - return 0; - case PixelFormat::RGBX_8888: - *outDrmFormat = DRM_FORMAT_XBGR8888; - return 0; - case PixelFormat::RGB_565: - *outDrmFormat = DRM_FORMAT_RGB565; - return 0; - case PixelFormat::RGB_888: - *outDrmFormat = DRM_FORMAT_RGB888; - return 0; - case PixelFormat::STENCIL_8: - return -EINVAL; - case PixelFormat::Y16: - *outDrmFormat = DRM_FORMAT_R16; - return 0; - case PixelFormat::Y8: - *outDrmFormat = DRM_FORMAT_R8; - return 0; - case PixelFormat::YCBCR_420_888: - *outDrmFormat = DRM_FORMAT_FLEX_YCbCr_420_888; - return 0; - case PixelFormat::YCBCR_422_SP: - return -EINVAL; - case PixelFormat::YCBCR_422_I: - return -EINVAL; - case PixelFormat::YCBCR_P010: - *outDrmFormat = DRM_FORMAT_P010; - return 0; - case PixelFormat::YCRCB_420_SP: - *outDrmFormat = DRM_FORMAT_NV21; - return 0; - case PixelFormat::YV12: - *outDrmFormat = DRM_FORMAT_YVU420_ANDROID; - return 0; - }; - return -EINVAL; -} + static_assert(std::is_same<std::underlying_type<PixelFormat>::type, int32_t>::value); -int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) { - uint64_t bufferUsage = BO_USE_NONE; + const uint32_t drmFormat = cros_gralloc_convert_format(static_cast<int32_t>(format)); + if (drmFormat == DRM_FORMAT_NONE) return -EINVAL; - if ((grallocUsage & BufferUsage::CPU_READ_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) { - bufferUsage |= BO_USE_SW_READ_RARELY; - } - if ((grallocUsage & BufferUsage::CPU_READ_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN)) { - bufferUsage |= BO_USE_SW_READ_OFTEN; - } - if ((grallocUsage & BufferUsage::CPU_WRITE_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) { - bufferUsage |= BO_USE_SW_WRITE_RARELY; - } - if ((grallocUsage & BufferUsage::CPU_WRITE_MASK) == - static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN)) { - bufferUsage |= BO_USE_SW_WRITE_OFTEN; - } - if (grallocUsage & BufferUsage::GPU_TEXTURE) { - bufferUsage |= BO_USE_TEXTURE; - } - if (grallocUsage & BufferUsage::GPU_RENDER_TARGET) { - bufferUsage |= BO_USE_RENDERING; - } - if (grallocUsage & BufferUsage::COMPOSER_OVERLAY) { - /* HWC wants to use display hardware, but can defer to OpenGL. */ - bufferUsage |= BO_USE_SCANOUT | BO_USE_TEXTURE; - } - /* Map this flag to linear until real HW protection is available on Android. */ - if (grallocUsage & BufferUsage::PROTECTED) { - bufferUsage |= BO_USE_LINEAR; - } - if (grallocUsage & BufferUsage::COMPOSER_CURSOR) { - bufferUsage |= BO_USE_NONE; - } - if (grallocUsage & BufferUsage::VIDEO_ENCODER) { - /*HACK: See b/30054495 */ - bufferUsage |= BO_USE_SW_READ_OFTEN; - } - if (grallocUsage & BufferUsage::CAMERA_OUTPUT) { - bufferUsage |= BO_USE_CAMERA_WRITE; - } - if (grallocUsage & BufferUsage::CAMERA_INPUT) { - bufferUsage |= BO_USE_CAMERA_READ; - } - if (grallocUsage & BufferUsage::RENDERSCRIPT) { - bufferUsage |= BO_USE_RENDERSCRIPT; - } - if (grallocUsage & BufferUsage::VIDEO_DECODER) { - bufferUsage |= BO_USE_HW_VIDEO_DECODER; - } + *outDrmFormat = drmFormat; + return 0; +} - *outBufferUsage = bufferUsage; +int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) { + *outBufferUsage = cros_gralloc_convert_usage(grallocUsage); return 0; } @@ -337,16 +82,7 @@ int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor, } 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; + *outMapUsage = cros_gralloc_convert_map_usage(grallocUsage); return 0; } @@ -547,13 +283,13 @@ const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap {DRM_FORMAT_RGB565, {{ - .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B, .offsetInBits = 0, .sizeInBits = 5}, {.type = android::gralloc4::PlaneLayoutComponentType_G, .offsetInBits = 5, .sizeInBits = 6}, - {.type = android::gralloc4::PlaneLayoutComponentType_B, + {.type = android::gralloc4::PlaneLayoutComponentType_R, .offsetInBits = 11, .sizeInBits = 5}}, .sampleIncrementInBits = 16, @@ -561,7 +297,7 @@ const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap .verticalSubsampling = 1, }}}, - {DRM_FORMAT_RGB888, + {DRM_FORMAT_BGR888, {{ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, .offsetInBits = 0, diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.h b/cros_gralloc/gralloc4/CrosGralloc4Utils.h index 370922c..fa096ef 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Utils.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.h @@ -11,7 +11,7 @@ #include <android/hardware/graphics/common/1.2/types.h> #include <android/hardware/graphics/mapper/4.0/IMapper.h> -#include "cros_gralloc/cros_gralloc_types.h" +struct cros_gralloc_buffer_descriptor; std::string getPixelFormatString(android::hardware::graphics::common::V1_2::PixelFormat format); diff --git a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc index a96a6e1..4f8680b 100644 --- a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc +++ b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc @@ -21,4 +21,4 @@ service vendor.graphics.allocator-4-0 /vendor/bin/hw/android.hardware.graphics.a group graphics drmrpc capabilities SYS_NICE onrestart restart surfaceflinger - writepid /dev/cpuset/system-background/tasks + task_profiles ServiceCapacityLow diff --git a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_arcvm.rc b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_arcvm.rc new file mode 100644 index 0000000..4e8818a --- /dev/null +++ b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_arcvm.rc @@ -0,0 +1,24 @@ +# +# Copyright 2021 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_arcvm + interface android.hardware.graphics.allocator@4.0::IAllocator default + class hal animation + user system + group graphics drmrpc + capabilities SYS_NICE + onrestart restart surfaceflinger + task_profiles ServiceCapacityLow diff --git a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_intel.rc b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_intel.rc new file mode 100644 index 0000000..9a3512f --- /dev/null +++ b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_intel.rc @@ -0,0 +1,24 @@ +# +# 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_intel + interface android.hardware.graphics.allocator@4.0::IAllocator default + class hal animation + user system + group graphics drmrpc + capabilities SYS_NICE + onrestart restart surfaceflinger + task_profiles ServiceCapacityLow diff --git a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc index dceb747..8ecc94b 100644 --- a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc +++ b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc @@ -21,4 +21,4 @@ service vendor.graphics.allocator-4-0 /vendor/bin/hw/android.hardware.graphics.a group graphics drmrpc capabilities SYS_NICE onrestart restart surfaceflinger - writepid /dev/cpuset/system-background/tasks + task_profiles ServiceCapacityLow @@ -18,8 +18,8 @@ #include <xf86drm.h> #include "dri.h" +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" static const struct { @@ -196,8 +196,12 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf const __DRIextension *loader_extensions[] = { NULL }; struct dri_driver *dri = drv->priv; + char *node_name = drmGetRenderDeviceNameFromFd(drv_get_fd(drv)); + if (!node_name) + return -ENODEV; - dri->fd = open(drmGetRenderDeviceNameFromFd(drv_get_fd(drv)), O_RDWR); + dri->fd = open(node_name, O_RDWR); + free(node_name); if (dri->fd < 0) return -ENODEV; @@ -385,13 +389,20 @@ int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data) return 0; } -int dri_bo_destroy(struct bo *bo) +int dri_bo_release(struct bo *bo) { struct dri_driver *dri = bo->drv->priv; assert(bo->priv); - close_gem_handle(bo->handles[0].u32, bo->drv->fd); dri->image_extension->destroyImage(bo->priv); + /* Not clearing bo->priv as we still use it to determine which destroy to call. */ + return 0; +} + +int dri_bo_destroy(struct bo *bo) +{ + assert(bo->priv); + close_gem_handle(bo->handles[0].u32, bo->drv->fd); bo->priv = NULL; return 0; } @@ -449,11 +460,22 @@ size_t dri_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_ uint64_t planes; GLboolean ret = dri->image_extension->queryDmaBufFormatModifierAttribs( - dri->device, format, modifier, __DRI_IMAGE_ATTRIB_NUM_PLANES, &planes); + dri->device, format, modifier, __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT, &planes); if (!ret) return 0; return planes; } +bool dri_query_modifiers(struct driver *drv, uint32_t format, int max, uint64_t *modifiers, + int *count) +{ + struct dri_driver *dri = drv->priv; + if (!dri->image_extension->queryDmaBufModifiers) + return false; + + return dri->image_extension->queryDmaBufModifiers(dri->device, format, max, modifiers, NULL, + count); +} + #endif @@ -33,9 +33,12 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma int dri_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, const uint64_t *modifiers, uint32_t modifier_count); int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data); +int dri_bo_release(struct bo *bo); int dri_bo_destroy(struct bo *bo); void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); int dri_bo_unmap(struct bo *bo, struct vma *vma); size_t dri_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier); +bool dri_query_modifiers(struct driver *drv, uint32_t format, int max, uint64_t *modifiers, + int *count); #endif @@ -9,7 +9,6 @@ #include <pthread.h> #include <stdint.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/types.h> @@ -21,16 +20,13 @@ #include <libgen.h> #endif +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" #ifdef DRV_AMDGPU extern const struct backend backend_amdgpu; #endif -#ifdef DRV_EXYNOS -extern const struct backend backend_exynos; -#endif #ifdef DRV_I915 extern const struct backend backend_i915; #endif @@ -73,9 +69,6 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_AMDGPU &backend_amdgpu, #endif -#ifdef DRV_EXYNOS - &backend_exynos, -#endif #ifdef DRV_I915 &backend_i915, #endif @@ -128,16 +121,19 @@ struct driver *drv_create(int fd) if (!drv->backend) goto free_driver; - if (pthread_mutex_init(&drv->driver_lock, NULL)) + if (pthread_mutex_init(&drv->buffer_table_lock, NULL)) goto free_driver; drv->buffer_table = drmHashCreate(); if (!drv->buffer_table) - goto free_lock; + goto free_buffer_table_lock; + + if (pthread_mutex_init(&drv->mappings_lock, NULL)) + goto free_buffer_table; drv->mappings = drv_array_init(sizeof(struct mapping)); if (!drv->mappings) - goto free_buffer_table; + goto free_mappings_lock; drv->combos = drv_array_init(sizeof(struct combination)); if (!drv->combos) @@ -155,10 +151,12 @@ struct driver *drv_create(int fd) free_mappings: drv_array_destroy(drv->mappings); +free_mappings_lock: + pthread_mutex_destroy(&drv->mappings_lock); free_buffer_table: drmHashDestroy(drv->buffer_table); -free_lock: - pthread_mutex_destroy(&drv->driver_lock); +free_buffer_table_lock: + pthread_mutex_destroy(&drv->buffer_table_lock); free_driver: free(drv); return NULL; @@ -166,17 +164,16 @@ free_driver: void drv_destroy(struct driver *drv) { - pthread_mutex_lock(&drv->driver_lock); - if (drv->backend->close) drv->backend->close(drv); - drmHashDestroy(drv->buffer_table); - drv_array_destroy(drv->mappings); drv_array_destroy(drv->combos); - pthread_mutex_unlock(&drv->driver_lock); - pthread_mutex_destroy(&drv->driver_lock); + drv_array_destroy(drv->mappings); + pthread_mutex_destroy(&drv->mappings_lock); + + drmHashDestroy(drv->buffer_table); + pthread_mutex_destroy(&drv->buffer_table_lock); free(drv); } @@ -230,17 +227,111 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 if (!bo->meta.num_planes) { free(bo); + errno = EINVAL; return NULL; } return bo; } +static void drv_bo_mapping_destroy(struct bo *bo) +{ + struct driver *drv = bo->drv; + uint32_t idx = 0; + + /* + * This function is called right before the buffer is destroyed. It will free any mappings + * associated with the buffer. + */ + pthread_mutex_lock(&drv->mappings_lock); + for (size_t plane = 0; plane < bo->meta.num_planes; plane++) { + while (idx < drv_array_size(drv->mappings)) { + struct mapping *mapping = + (struct mapping *)drv_array_at_idx(drv->mappings, idx); + if (mapping->vma->handle != bo->handles[plane].u32) { + idx++; + continue; + } + + if (!--mapping->vma->refcount) { + int ret = drv->backend->bo_unmap(bo, mapping->vma); + if (ret) { + pthread_mutex_unlock(&drv->mappings_lock); + assert(ret); + drv_log("munmap failed\n"); + return; + } + + free(mapping->vma); + } + + /* This shrinks and shifts the array, so don't increment idx. */ + drv_array_remove(drv->mappings, idx); + } + } + pthread_mutex_unlock(&drv->mappings_lock); +} + +/* + * Acquire a reference on plane buffers of the bo. + */ +static void drv_bo_acquire(struct bo *bo) +{ + struct driver *drv = bo->drv; + + pthread_mutex_lock(&drv->buffer_table_lock); + for (size_t plane = 0; plane < bo->meta.num_planes; plane++) { + uintptr_t num = 0; + + if (!drmHashLookup(drv->buffer_table, bo->handles[plane].u32, (void **)&num)) + drmHashDelete(drv->buffer_table, bo->handles[plane].u32); + + drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num + 1)); + } + pthread_mutex_unlock(&drv->buffer_table_lock); +} + +/* + * Release a reference on plane buffers of the bo. Return true when the bo has lost all its + * references. Otherwise, return false. + */ +static bool drv_bo_release(struct bo *bo) +{ + struct driver *drv = bo->drv; + uintptr_t num; + + if (drv->backend->bo_release) + drv->backend->bo_release(bo); + + pthread_mutex_lock(&drv->buffer_table_lock); + for (size_t plane = 0; plane < bo->meta.num_planes; plane++) { + if (!drmHashLookup(drv->buffer_table, bo->handles[plane].u32, (void **)&num)) { + drmHashDelete(drv->buffer_table, bo->handles[plane].u32); + + if (num > 1) { + drmHashInsert(drv->buffer_table, bo->handles[plane].u32, + (void *)(num - 1)); + } + } + } + + /* The same buffer can back multiple planes with different offsets. */ + for (size_t plane = 0; plane < bo->meta.num_planes; plane++) { + if (!drmHashLookup(drv->buffer_table, bo->handles[plane].u32, (void **)&num)) { + /* num is positive if found in the hashmap. */ + pthread_mutex_unlock(&drv->buffer_table_lock); + return false; + } + } + pthread_mutex_unlock(&drv->buffer_table_lock); + + return true; +} + struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { int ret; - size_t plane; struct bo *bo; bool is_test_alloc; @@ -263,20 +354,12 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui } if (ret) { + errno = -ret; free(bo); return NULL; } - pthread_mutex_lock(&drv->driver_lock); - - for (plane = 0; plane < bo->meta.num_planes; plane++) { - if (plane > 0) - assert(bo->meta.offsets[plane] >= bo->meta.offsets[plane - 1]); - - drv_increment_reference_count(drv, bo, plane); - } - - pthread_mutex_unlock(&drv->driver_lock); + drv_bo_acquire(bo); return bo; } @@ -285,7 +368,6 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint uint32_t format, const uint64_t *modifiers, uint32_t count) { int ret; - size_t plane; struct bo *bo; if (!drv->backend->bo_create_with_modifiers && !drv->backend->bo_compute_metadata) { @@ -314,43 +396,16 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint return NULL; } - pthread_mutex_lock(&drv->driver_lock); - - for (plane = 0; plane < bo->meta.num_planes; plane++) { - if (plane > 0) - assert(bo->meta.offsets[plane] >= bo->meta.offsets[plane - 1]); - - drv_increment_reference_count(drv, bo, plane); - } - - pthread_mutex_unlock(&drv->driver_lock); + drv_bo_acquire(bo); return bo; } void drv_bo_destroy(struct bo *bo) { - int ret; - size_t plane; - uintptr_t total = 0; - struct driver *drv = bo->drv; - - if (!bo->is_test_buffer) { - pthread_mutex_lock(&drv->driver_lock); - - for (plane = 0; plane < bo->meta.num_planes; plane++) - drv_decrement_reference_count(drv, bo, plane); - - for (plane = 0; plane < bo->meta.num_planes; plane++) - total += drv_get_reference_count(drv, bo, plane); - - pthread_mutex_unlock(&drv->driver_lock); - - if (total == 0) { - ret = drv_mapping_destroy(bo); - assert(ret == 0); - bo->drv->backend->bo_destroy(bo); - } + if (!bo->is_test_buffer && drv_bo_release(bo)) { + drv_bo_mapping_destroy(bo); + bo->drv->backend->bo_destroy(bo); } free(bo); @@ -374,11 +429,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) return NULL; } - for (plane = 0; plane < bo->meta.num_planes; plane++) { - pthread_mutex_lock(&bo->drv->driver_lock); - drv_increment_reference_count(bo->drv, bo, plane); - pthread_mutex_unlock(&bo->drv->driver_lock); - } + drv_bo_acquire(bo); bo->meta.format_modifier = data->format_modifier; for (plane = 0; plane < bo->meta.num_planes; plane++) { @@ -415,6 +466,7 @@ destroy_bo: void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags, struct mapping **map_data, size_t plane) { + struct driver *drv = bo->drv; uint32_t i; uint8_t *addr; struct mapping mapping = { 0 }; @@ -433,10 +485,10 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags mapping.rect = *rect; mapping.refcount = 1; - pthread_mutex_lock(&bo->drv->driver_lock); + pthread_mutex_lock(&drv->mappings_lock); - for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { - struct mapping *prior = (struct mapping *)drv_array_at_idx(bo->drv->mappings, i); + for (i = 0; i < drv_array_size(drv->mappings); i++) { + struct mapping *prior = (struct mapping *)drv_array_at_idx(drv->mappings, i); if (prior->vma->handle != bo->handles[plane].u32 || prior->vma->map_flags != map_flags) continue; @@ -450,8 +502,8 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags goto exact_match; } - for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { - struct mapping *prior = (struct mapping *)drv_array_at_idx(bo->drv->mappings, i); + for (i = 0; i < drv_array_size(drv->mappings); i++) { + struct mapping *prior = (struct mapping *)drv_array_at_idx(drv->mappings, i); if (prior->vma->handle != bo->handles[plane].u32 || prior->vma->map_flags != map_flags) continue; @@ -462,12 +514,18 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags } mapping.vma = calloc(1, sizeof(*mapping.vma)); + if (!mapping.vma) { + *map_data = NULL; + pthread_mutex_unlock(&drv->mappings_lock); + return MAP_FAILED; + } + memcpy(mapping.vma->map_strides, bo->meta.strides, sizeof(mapping.vma->map_strides)); - addr = bo->drv->backend->bo_map(bo, mapping.vma, plane, map_flags); + addr = drv->backend->bo_map(bo, mapping.vma, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; free(mapping.vma); - pthread_mutex_unlock(&bo->drv->driver_lock); + pthread_mutex_unlock(&drv->mappings_lock); return MAP_FAILED; } @@ -477,39 +535,40 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags mapping.vma->map_flags = map_flags; success: - *map_data = drv_array_append(bo->drv->mappings, &mapping); + *map_data = drv_array_append(drv->mappings, &mapping); exact_match: drv_bo_invalidate(bo, *map_data); addr = (uint8_t *)((*map_data)->vma->addr); addr += drv_bo_get_plane_offset(bo, plane); - pthread_mutex_unlock(&bo->drv->driver_lock); + pthread_mutex_unlock(&drv->mappings_lock); return (void *)addr; } int drv_bo_unmap(struct bo *bo, struct mapping *mapping) { + struct driver *drv = bo->drv; uint32_t i; int ret = 0; - pthread_mutex_lock(&bo->drv->driver_lock); + pthread_mutex_lock(&drv->mappings_lock); if (--mapping->refcount) goto out; if (!--mapping->vma->refcount) { - ret = bo->drv->backend->bo_unmap(bo, mapping->vma); + ret = drv->backend->bo_unmap(bo, mapping->vma); free(mapping->vma); } - for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { - if (mapping == (struct mapping *)drv_array_at_idx(bo->drv->mappings, i)) { - drv_array_remove(bo->drv->mappings, i); + for (i = 0; i < drv_array_size(drv->mappings); i++) { + if (mapping == (struct mapping *)drv_array_at_idx(drv->mappings, i)) { + drv_array_remove(drv->mappings, i); break; } } out: - pthread_mutex_unlock(&bo->drv->driver_lock); + pthread_mutex_unlock(&drv->mappings_lock); return ret; } @@ -634,17 +693,36 @@ uint32_t drv_bo_get_format(struct bo *bo) return bo->meta.format; } +uint32_t drv_bo_get_tiling(struct bo *bo) +{ + return bo->meta.tiling; +} + +uint64_t drv_bo_get_use_flags(struct bo *bo) +{ + return bo->meta.use_flags; +} + size_t drv_bo_get_total_size(struct bo *bo) { return bo->meta.total_size; } -uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) +/* + * Map internal fourcc codes back to standard fourcc codes. + */ +uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal) +{ + return (fourcc_internal == DRM_FORMAT_YVU420_ANDROID) ? DRM_FORMAT_YVU420 : fourcc_internal; +} + +void drv_resolve_format_and_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags, + uint32_t *out_format, uint64_t *out_use_flags) { - if (drv->backend->resolve_format) - return drv->backend->resolve_format(drv, format, use_flags); + assert(drv->backend->resolve_format_and_use_flags); - return format; + drv->backend->resolve_format_and_use_flags(drv, format, use_flags, out_format, + out_use_flags); } uint32_t drv_num_buffers_per_bo(struct bo *bo) @@ -696,3 +774,11 @@ int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], return 0; } + +uint32_t drv_get_max_texture_2d_size(struct driver *drv) +{ + if (drv->backend->get_max_texture_2d_size) + return drv->backend->get_max_texture_2d_size(drv); + + return UINT32_MAX; +} @@ -14,6 +14,7 @@ extern "C" { #include <drm_fourcc.h> #include <stdbool.h> #include <stdint.h> +#include <stdlib.h> #define DRV_MAX_PLANES 4 @@ -39,6 +40,7 @@ extern "C" { #define BO_USE_TEST_ALLOC (1ull << 15) #define BO_USE_FRONT_RENDERING (1ull << 16) #define BO_USE_RENDERSCRIPT (1ull << 17) +#define BO_USE_GPU_DATA_BUFFER (1ull << 18) /* Quirks for allocating a buffer. */ #define BO_QUIRK_NONE 0 @@ -69,6 +71,11 @@ extern "C" { #define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') #endif +//TODO: remove this defination once drm_fourcc.h contains it. +#ifndef I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS +#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6) +#endif + // clang-format on struct driver; struct bo; @@ -171,11 +178,22 @@ uint64_t drv_bo_get_format_modifier(struct bo *bo); uint32_t drv_bo_get_format(struct bo *bo); +uint32_t drv_bo_get_tiling(struct bo *bo); + +uint64_t drv_bo_get_use_flags(struct bo *bo); + +size_t drv_bo_get_total_size(struct bo *bo); + +uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal); + uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane); uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); -uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags); +void drv_resolve_format_and_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags, + uint32_t *out_format, uint64_t *out_use_flags); + +uint64_t drv_resolve_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags); size_t drv_num_planes_from_format(uint32_t format); @@ -186,6 +204,8 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo); int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier); +uint32_t drv_get_max_texture_2d_size(struct driver *drv); + #define drv_log(format, ...) \ do { \ drv_log_prefix("minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \ diff --git a/helpers_array.c b/drv_array_helpers.c index 20b43e2..b4e7750 100644 --- a/helpers_array.c +++ b/drv_array_helpers.c @@ -3,6 +3,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "drv_array_helpers.h" #include <assert.h> #include <stdint.h> @@ -23,10 +24,17 @@ struct drv_array *drv_array_init(uint32_t item_size) struct drv_array *array; array = calloc(1, sizeof(*array)); + if (!array) + return NULL; /* Start with a power of 2 number of allocations. */ array->allocations = 2; array->items = calloc(array->allocations, sizeof(*array->items)); + if (!array->items) { + free(array); + return NULL; + } + array->item_size = item_size; return array; } diff --git a/helpers_array.h b/drv_array_helpers.h index 2893976..77544d3 100644 --- a/helpers_array.h +++ b/drv_array_helpers.h @@ -4,6 +4,11 @@ * found in the LICENSE file. */ +#ifndef DRV_ARRAY_HELPERS_H +#define DRV_ARRAY_HELPERS_H + +#include <stdint.h> + struct drv_array; struct drv_array *drv_array_init(uint32_t item_size); @@ -20,3 +25,5 @@ uint32_t drv_array_size(struct drv_array *array); /* The array and all associated data will be freed. */ void drv_array_destroy(struct drv_array *array); + +#endif diff --git a/helpers.c b/drv_helpers.c index a182347..6ea4b8e 100644 --- a/helpers.c +++ b/drv_helpers.c @@ -4,6 +4,8 @@ * found in the LICENSE file. */ +#include "drv_helpers.h" + #include <assert.h> #include <errno.h> #include <stdio.h> @@ -15,7 +17,6 @@ #include <xf86drm.h> #include "drv_priv.h" -#include "helpers.h" #include "util.h" struct planar_layout { @@ -483,80 +484,11 @@ int drv_bo_munmap(struct bo *bo, struct vma *vma) return munmap(vma->addr, vma->length); } -int drv_mapping_destroy(struct bo *bo) -{ - int ret; - size_t plane; - struct mapping *mapping; - uint32_t idx; - - /* - * This function is called right before the buffer is destroyed. It will free any mappings - * associated with the buffer. - */ - - idx = 0; - for (plane = 0; plane < bo->meta.num_planes; plane++) { - while (idx < drv_array_size(bo->drv->mappings)) { - mapping = (struct mapping *)drv_array_at_idx(bo->drv->mappings, idx); - if (mapping->vma->handle != bo->handles[plane].u32) { - idx++; - continue; - } - - if (!--mapping->vma->refcount) { - ret = bo->drv->backend->bo_unmap(bo, mapping->vma); - if (ret) { - drv_log("munmap failed\n"); - return ret; - } - - free(mapping->vma); - } - - /* This shrinks and shifts the array, so don't increment idx. */ - drv_array_remove(bo->drv->mappings, idx); - } - } - - return 0; -} - int drv_get_prot(uint32_t map_flags) { return (BO_MAP_WRITE & map_flags) ? PROT_WRITE | PROT_READ : PROT_READ; } -uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, size_t plane) -{ - void *count; - uintptr_t num = 0; - - if (!drmHashLookup(drv->buffer_table, bo->handles[plane].u32, &count)) - num = (uintptr_t)(count); - - return num; -} - -void drv_increment_reference_count(struct driver *drv, struct bo *bo, size_t plane) -{ - uintptr_t num = drv_get_reference_count(drv, bo, plane); - - /* If a value isn't in the table, drmHashDelete is a no-op */ - drmHashDelete(drv->buffer_table, bo->handles[plane].u32); - drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num + 1)); -} - -void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t plane) -{ - uintptr_t num = drv_get_reference_count(drv, bo, plane); - - drmHashDelete(drv->buffer_table, bo->handles[plane].u32); - - if (num > 0) - drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num - 1)); -} - void drv_add_combination(struct driver *drv, const uint32_t format, struct format_metadata *metadata, uint64_t use_flags) { @@ -641,27 +573,31 @@ bool drv_has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier) return false; } -/* - * Map internal fourcc codes back to standard fourcc codes. - */ -uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal) -{ - return (fourcc_internal == DRM_FORMAT_YVU420_ANDROID) ? DRM_FORMAT_YVU420 : fourcc_internal; -} - -uint32_t drv_resolve_format_helper(struct driver *drv, uint32_t format, uint64_t use_flags) +void drv_resolve_format_and_use_flags_helper(struct driver *drv, uint32_t format, + uint64_t use_flags, uint32_t *out_format, + uint64_t *out_use_flags) { + *out_format = format; + *out_use_flags = use_flags; switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: /* Common camera implementation defined format. */ - if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) - return DRM_FORMAT_NV12; - /* A common hack: See b/28671744 */ - return DRM_FORMAT_XBGR8888; + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) { + *out_format = DRM_FORMAT_NV12; + } else { + /* HACK: See b/28671744 */ + *out_format = DRM_FORMAT_XBGR8888; + *out_use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + } + break; case DRM_FORMAT_FLEX_YCbCr_420_888: /* Common flexible video format. */ - return DRM_FORMAT_NV12; + *out_format = DRM_FORMAT_NV12; + break; + case DRM_FORMAT_YVU420_ANDROID: + *out_use_flags &= ~BO_USE_SCANOUT; + break; default: - return format; + break; } } diff --git a/helpers.h b/drv_helpers.h index d906dcf..edb69bf 100644 --- a/helpers.h +++ b/drv_helpers.h @@ -4,22 +4,20 @@ * found in the LICENSE file. */ -#ifndef HELPERS_H -#define HELPERS_H - -#ifdef __cplusplus -extern "C" { -#endif +#ifndef DRV_HELPERS_H +#define DRV_HELPERS_H #include <stdbool.h> #include "drv.h" -#include "helpers_array.h" +#include "drv_array_helpers.h" #ifndef PAGE_SIZE #define PAGE_SIZE 0x1000 #endif +struct format_metadata; + uint32_t drv_height_from_format(uint32_t format, uint32_t height, size_t plane); uint32_t drv_vertical_subsampling_from_format(uint32_t format, size_t plane); uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane); @@ -35,11 +33,7 @@ int drv_gem_bo_destroy(struct bo *bo); int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data); void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); int drv_bo_munmap(struct bo *bo, struct vma *vma); -int drv_mapping_destroy(struct bo *bo); int drv_get_prot(uint32_t map_flags); -uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, size_t plane); -void drv_increment_reference_count(struct driver *drv, struct bo *bo, size_t plane); -void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t plane); void drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, uint64_t usage); void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, @@ -50,11 +44,8 @@ int drv_modify_linear_combinations(struct driver *drv); uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count, const uint64_t *modifier_order, uint32_t order_count); bool drv_has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier); -uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal); -uint32_t drv_resolve_format_helper(struct driver *drv, uint32_t format, uint64_t use_flags); - -#ifdef __cplusplus -} -#endif +void drv_resolve_format_and_use_flags_helper(struct driver *drv, uint32_t format, + uint64_t use_flags, uint32_t *out_format, + uint64_t *out_use_flags); #endif @@ -34,7 +34,7 @@ struct bo_metadata { * specific metadata. It's easiest just to stuff all the metadata here rather than * having two metadata structs. */ - uint64_t blob_id; + uint32_t blob_id; uint32_t map_info; int32_t memory_idx; int32_t physical_device_idx; @@ -64,10 +64,11 @@ struct driver { int fd; const struct backend *backend; void *priv; + pthread_mutex_t buffer_table_lock; void *buffer_table; + pthread_mutex_t mappings_lock; struct drv_array *mappings; struct drv_array *combos; - pthread_mutex_t driver_lock; bool compression; }; @@ -84,16 +85,22 @@ struct backend { int (*bo_compute_metadata)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags, const uint64_t *modifiers, uint32_t count); int (*bo_create_from_metadata)(struct bo *bo); + /* Called for every non-test-buffer BO on free */ + int (*bo_release)(struct bo *bo); + /* Called on free if this bo is the last object referencing the contained GEM BOs */ int (*bo_destroy)(struct bo *bo); int (*bo_import)(struct bo *bo, struct drv_import_fd_data *data); void *(*bo_map)(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); int (*bo_unmap)(struct bo *bo, struct vma *vma); int (*bo_invalidate)(struct bo *bo, struct mapping *mapping); int (*bo_flush)(struct bo *bo, struct mapping *mapping); - uint32_t (*resolve_format)(struct driver *drv, uint32_t format, uint64_t use_flags); + void (*resolve_format_and_use_flags)(struct driver *drv, uint32_t format, + uint64_t use_flags, uint32_t *out_format, + uint64_t *out_use_flags); size_t (*num_planes_from_modifier)(struct driver *drv, uint32_t format, uint64_t modifier); int (*resource_info)(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier); + uint32_t (*get_max_texture_2d_size)(struct driver *drv); }; // clang-format off diff --git a/dumb_driver.c b/dumb_driver.c index f5a62aa..ef7dd36 100644 --- a/dumb_driver.c +++ b/dumb_driver.c @@ -4,8 +4,10 @@ * found in the LICENSE file. */ +#include <errno.h> + +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" #define INIT_DUMB_DRIVER(driver) \ @@ -13,15 +15,17 @@ .name = #driver, \ .init = dumb_driver_init, \ .bo_create = drv_dumb_bo_create, \ + .bo_create_with_modifiers = dumb_bo_create_with_modifiers, \ .bo_destroy = drv_dumb_bo_destroy, \ .bo_import = drv_prime_bo_import, \ .bo_map = drv_dumb_bo_map, \ .bo_unmap = drv_bo_munmap, \ + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, \ }; static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888, DRM_FORMAT_ABGR8888, DRM_FORMAT_XBGR8888, - DRM_FORMAT_BGR888, DRM_FORMAT_BGR565 }; + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565 }; static const uint32_t texture_only_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; @@ -42,6 +46,18 @@ static int dumb_driver_init(struct driver *drv) return drv_modify_linear_combinations(drv); } +static int dumb_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) { + if (modifiers[i] == DRM_FORMAT_MOD_LINEAR) { + return drv_dumb_bo_create(bo, width, height, format, 0); + } + } + + return -EINVAL; +} + INIT_DUMB_DRIVER(evdi) INIT_DUMB_DRIVER(komeda) INIT_DUMB_DRIVER(marvell) diff --git a/external/i915_drm.h b/external/i915_drm.h index f5991a8..e301c5f 100644 --- a/external/i915_drm.h +++ b/external/i915_drm.h @@ -359,7 +359,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_QUERY 0x39 #define DRM_I915_GEM_VM_CREATE 0x3a #define DRM_I915_GEM_VM_DESTROY 0x3b -#define DRM_I915_PXP_OPS 0x3c +#define DRM_I915_GEM_CREATE_EXT 0x3c /* Must be kept compact -- no holes */ #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) @@ -392,7 +392,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) #define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) -#define DRM_IOCTL_I915_GEM_CREATE_EXT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create_ext) +#define DRM_IOCTL_I915_GEM_CREATE_EXT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE_EXT, struct drm_i915_gem_create_ext) #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) #define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) @@ -424,7 +424,6 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query) #define DRM_IOCTL_I915_GEM_VM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control) #define DRM_IOCTL_I915_GEM_VM_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control) -#define DRM_IOCTL_I915_PXP_OPS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_PXP_OPS, struct drm_i915_pxp_ops) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -725,27 +724,6 @@ struct drm_i915_gem_create { __u32 pad; }; -struct drm_i915_gem_create_ext { - /** - * Requested size for the object. - * - * The (page-aligned) allocated size for the object will be returned. - */ - __u64 size; - /** - * Returned handle for the object. - * - * Object handles are nonzero. - */ - __u32 handle; - __u32 pad; -#define I915_GEM_CREATE_EXT_SETPARAM (1u << 0) -#define I915_GEM_CREATE_EXT_FLAGS_UNKNOWN \ - (-(I915_GEM_CREATE_EXT_SETPARAM << 1)) - __u64 extensions; - -}; - struct drm_i915_gem_pread { /** Handle for the object being read. */ __u32 handle; @@ -1645,51 +1623,28 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_PARAM_PERSISTENCE 0xb /* - * I915_CONTEXT_PARAM_PROTECTED_CONTENT: + * I915_CONTEXT_PARAM_RINGSIZE: * - * If set to true (1) PAVP content protection is enabled. - * When enabled, the context is marked unrecoverable and may - * become invalid due to PAVP teardown event or other error. - */ -#define I915_CONTEXT_PARAM_PROTECTED_CONTENT 0xd -/* Must be kept compact -- no holes and well documented */ - - __u64 value; -}; - -struct drm_i915_gem_object_param { - /* Object handle (0 for I915_GEM_CREATE_EXT_SETPARAM) */ - __u32 handle; - - /* Data pointer size */ - __u32 size; - -/* - * I915_OBJECT_PARAM: + * Sets the size of the CS ringbuffer to use for logical ring contexts. This + * applies a limit of how many batches can be queued to HW before the caller + * is blocked due to lack of space for more commands. * - * Select object namespace for the param. - */ -#define I915_OBJECT_PARAM (1ull<<32) - -/* - * I915_PARAM_PROTECTED_CONTENT: + * Only reliably possible to be set prior to first use, i.e. during + * construction. At any later point, the current execution must be flushed as + * the ring can only be changed while the context is idle. Note, the ringsize + * can be specified as a constructor property, see + * I915_CONTEXT_CREATE_EXT_SETPARAM, but can also be set later if required. + * + * Only applies to the current set of engine and lost when those engines + * are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES). * - * If set to true (1) buffer contents is expected to be protected by - * PAVP encryption and requires decryption for scan out and processing. - * Protected buffers can only be used in PAVP protected contexts. - * A protected buffer may become invalid as a result of PAVP teardown. + * Must be between 4 - 512 KiB, in intervals of page size [4 KiB]. + * Default is 16 KiB. */ -#define I915_PARAM_PROTECTED_CONTENT 0x1 - - __u64 param; - - /* Data value or pointer */ - __u64 data; -}; +#define I915_CONTEXT_PARAM_RINGSIZE 0xc +/* Must be kept compact -- no holes and well documented */ -struct drm_i915_gem_create_ext_setparam { - struct i915_user_extension base; - struct drm_i915_gem_object_param param; + __u64 value; }; /** @@ -1892,76 +1847,6 @@ struct drm_i915_gem_vm_control { __u32 vm_id; }; -/* - * struct pxp_sm_query_pxp_tag - Params to query the PXP tag of specified - * session id and whether the session is alive from PXP state machine. - */ -struct pxp_sm_query_pxp_tag { - __u32 session_is_alive; - __u32 pxp_tag; /* in - Session ID, out pxp tag */ -}; - -/* - * struct pxp_set_session_status_params - Params to reserved, set or destroy - * the session from the PXP state machine. - */ -struct pxp_set_session_status_params { - __u32 pxp_tag; /* in [optional], for Arbitrator session, out pxp tag */ - __u32 session_type; /* in, session type */ - __u32 session_mode; /* in, session mode */ - __u32 req_session_state; /* in, new session state */ -}; - -/* - * struct pxp_tee_io_message_params - Params to send/receive message to/from TEE. - */ -struct pxp_tee_io_message_params { - __u8 *msg_in; /* in - message input */ - __u32 msg_in_size; /* in - message input size */ - __u8 *msg_out; /* in - message output buffer */ - __u32 msg_out_size; /* out- message output size from TEE */ - __u32 msg_out_buf_size; /* in - message output buffer size */ -}; - -/* - * struct pxp_info - Params for PXP operation. - */ -struct pxp_info { - __u32 action; /* in - specified action of this operation */ - __u32 sm_status; /* out - status output for this operation */ - - union { - /* in - action params to query PXP tag */ - struct pxp_sm_query_pxp_tag query_pxp_tag; - /* in - action params to set the PXP session state */ - struct pxp_set_session_status_params set_session_status; - /* in - action params to send TEE commands */ - struct pxp_tee_io_message_params tee_io_message; - - /* in - action params to set user space context */ - __u32 set_user_ctx; - }; -} __attribute__((packed)); - -/* - * DRM_I915_PXP_OPS - - * - * PXP is an i915 componment, that helps user space to establish the hardware - * protected session and manage the status of each alive software session, - * as well as the life cycle of each session. - * - * This ioctl is to allow user space driver to create, set, and destroy each - * session. It also provides the communication chanel to TEE (Trusted - * Execution Environment) for the protected hardware session creation. - */ -struct drm_i915_pxp_ops { - /* in - user space pointer to struct pxp_info */ - struct pxp_info *info_ptr; - - /* in - memory size that info_ptr points to */ - __u32 info_size; -}; - struct drm_i915_reg_read { /* * Register offset. @@ -2086,6 +1971,17 @@ enum drm_i915_perf_property_id { */ DRM_I915_PERF_PROP_HOLD_PREEMPTION, + /** + * Specifying this pins all contexts to the specified SSEU power + * configuration for the duration of the recording. + * + * This parameter's value is a pointer to a struct + * drm_i915_gem_context_param_sseu. + * + * This property is available in perf revision 4. + */ + DRM_I915_PERF_PROP_GLOBAL_SSEU, + DRM_I915_PERF_PROP_MAX /* non-ABI */ }; @@ -2415,6 +2311,77 @@ struct drm_i915_query_perf_config { __u8 data[]; }; +/** + * struct drm_i915_gem_create_ext - Existing gem_create behaviour, with added + * extension support using struct i915_user_extension. + * + * Note that in the future we want to have our buffer flags here, at least for + * the stuff that is immutable. Previously we would have two ioctls, one to + * create the object with gem_create, and another to apply various parameters, + * however this creates some ambiguity for the params which are considered + * immutable. Also in general we're phasing out the various SET/GET ioctls. + */ +struct drm_i915_gem_create_ext { + /** + * @size: Requested size for the object. + * + * The (page-aligned) allocated size for the object will be returned. + * + */ + __u64 size; + /** + * @handle: Returned handle for the object. + * + * Object handles are nonzero. + */ + __u32 handle; + /** @flags: MBZ */ + __u32 flags; + /** + * @extensions: The chain of extensions to apply to this object. + * + * This will be useful in the future when we need to support several + * different extensions, and we need to apply more than one when + * creating the object. See struct i915_user_extension. + * + * If we don't supply any extensions then we get the same old gem_create + * behaviour. + * + * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see + * struct drm_i915_gem_create_ext_protected_content. + */ +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1 + __u64 extensions; +}; + +/** + * struct drm_i915_gem_create_ext_protected_content - The + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension. + * + * If this extension is provided, buffer contents are expected to be protected + * by PXP encryption and require decryption for scan out and processing. This + * is only possible on platforms that have PXP enabled, on all other scenarios + * using this extension will cause the ioctl to fail and return -ENODEV. The + * flags parameter is reserved for future expansion and must currently be set + * to zero. + * + * The buffer contents are considered invalid after a PXP session teardown. + * + * The encryption is guaranteed to be processed correctly only if the object + * is submitted with a context created using the + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks + * at submission time on the validity of the objects involved. + */ +struct drm_i915_gem_create_ext_protected_content { + /** @base: Extension link. See struct i915_user_extension. */ + struct i915_user_extension base; + /** @flags: reserved for future usage, currently MBZ */ + __u32 flags; +}; + +/* ID of the protected content session managed by i915 when PXP is active */ +#define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf + #if defined(__cplusplus) } #endif diff --git a/external/virtgpu_cross_domain_protocol.h b/external/virtgpu_cross_domain_protocol.h index eaeebd3..afae541 100644 --- a/external/virtgpu_cross_domain_protocol.h +++ b/external/virtgpu_cross_domain_protocol.h @@ -10,11 +10,43 @@ // Cross-domain commands (only a maximum of 255 supported) #define CROSS_DOMAIN_CMD_INIT 1 #define CROSS_DOMAIN_CMD_GET_IMAGE_REQUIREMENTS 2 +#define CROSS_DOMAIN_CMD_POLL 3 +#define CROSS_DOMAIN_CMD_SEND 4 +#define CROSS_DOMAIN_CMD_RECEIVE 5 +#define CROSS_DOMAIN_CMD_READ 6 +#define CROSS_DOMAIN_CMD_WRITE 7 // Channel types (must match rutabaga channel types) #define CROSS_DOMAIN_CHANNEL_TYPE_WAYLAND 0x0001 #define CROSS_DOMAIN_CHANNEL_TYPE_CAMERA 0x0002 +// The maximum number of identifiers (value based on wp_linux_dmabuf) +#define CROSS_DOMAIN_MAX_IDENTIFIERS 4 + +// virtgpu memory resource ID. Also works with non-blob memory resources, +// despite the name. +#define CROSS_DOMAIN_ID_TYPE_VIRTGPU_BLOB 1 + +// virtgpu synchronization resource id. +#define CROSS_DOMAIN_ID_TYPE_VIRTGPU_SYNC 2 + +// ID for Wayland pipe used for reading. The reading is done by the guest proxy +// and the host proxy. The host sends the write end of the proxied pipe over +// the host Wayland socket. +#define CROSS_DOMAIN_ID_TYPE_READ_PIPE 3 + +// ID for Wayland pipe used for writing. The writing is done by the guest and +// the host proxy. The host receives the write end of the pipe over the host +// Wayland socket. +#define CROSS_DOMAIN_ID_TYPE_WRITE_PIPE 4 + +// No ring used +#define CROSS_DOMAIN_RING_NONE 0xffffffff +// A ring for metadata queries. +#define CROSS_DOMAIN_QUERY_RING 0 +// A ring based on this particular context's channel. +#define CROSS_DOMAIN_CHANNEL_RING 1 + struct CrossDomainCapabilities { uint32_t version; uint32_t supported_channels; @@ -27,9 +59,8 @@ struct CrossDomainImageRequirements { uint32_t offsets[4]; uint64_t modifier; uint64_t size; - uint64_t blob_id; + uint32_t blob_id; uint32_t map_info; - uint32_t pad; int32_t memory_idx; int32_t physical_device_idx; }; @@ -55,4 +86,26 @@ struct CrossDomainGetImageRequirements { uint32_t flags; }; +struct CrossDomainPoll { + struct CrossDomainHeader hdr; + uint64_t pad; +}; + +struct CrossDomainSendReceive { + struct CrossDomainHeader hdr; + uint32_t num_identifiers; + uint32_t opaque_data_size; + uint32_t identifiers[CROSS_DOMAIN_MAX_IDENTIFIERS]; + uint32_t identifier_types[CROSS_DOMAIN_MAX_IDENTIFIERS]; + uint32_t identifier_sizes[CROSS_DOMAIN_MAX_IDENTIFIERS]; +}; + +struct CrossDomainReadWrite { + struct CrossDomainHeader hdr; + uint32_t identifier; + uint32_t hang_up; + uint32_t opaque_data_size; + uint32_t pad; +}; + #endif diff --git a/external/virtgpu_drm.h b/external/virtgpu_drm.h index 9b46138..7720900 100644 --- a/external/virtgpu_drm.h +++ b/external/virtgpu_drm.h @@ -51,11 +51,11 @@ extern "C" { #define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01 #define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02 -#define VIRTGPU_EXECBUF_FENCE_CONTEXT 0x04 +#define VIRTGPU_EXECBUF_RING_IDX 0x04 #define VIRTGPU_EXECBUF_FLAGS (\ VIRTGPU_EXECBUF_FENCE_FD_IN |\ VIRTGPU_EXECBUF_FENCE_FD_OUT |\ - VIRTGPU_EXECBUF_FENCE_CONTEXT |\ + VIRTGPU_EXECBUF_RING_IDX |\ 0) struct drm_virtgpu_map { @@ -208,8 +208,9 @@ struct drm_virtgpu_resource_create_blob { __u64 blob_id; }; -#define VIRTGPU_CONTEXT_PARAM_CAPSET_ID 0x0001 -#define VIRTGPU_CONTEXT_PARAM_NUM_FENCE_CONTEXTS 0x0002 +#define VIRTGPU_CONTEXT_PARAM_CAPSET_ID 0x0001 +#define VIRTGPU_CONTEXT_PARAM_NUM_RINGS 0x0002 +#define VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK 0x0003 struct drm_virtgpu_context_set_param { __u64 param; __u64 value; diff --git a/exynos.c b/exynos.c deleted file mode 100644 index 5862643..0000000 --- a/exynos.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2014 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. - */ - -#ifdef DRV_EXYNOS - -// clang-format off -#include <assert.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <xf86drm.h> -#include <exynos_drm.h> -// clang-format on - -#include "drv_priv.h" -#include "helpers.h" -#include "util.h" - -static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; - -static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12 }; - -static int exynos_init(struct driver *drv) -{ - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - - drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - - return drv_modify_linear_combinations(drv); -} - -static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) -{ - size_t plane; - - if (format == DRM_FORMAT_NV12) { - uint32_t chroma_height; - /* V4L2 s5p-mfc requires width to be 16 byte aligned and height 32. */ - width = ALIGN(width, 16); - height = ALIGN(height, 32); - chroma_height = ALIGN(height / 2, 32); - bo->meta.strides[0] = bo->meta.strides[1] = width; - /* MFC v8+ requires 64 byte padding in the end of luma and chroma buffers. */ - bo->meta.sizes[0] = bo->meta.strides[0] * height + 64; - bo->meta.sizes[1] = bo->meta.strides[1] * chroma_height + 64; - bo->meta.offsets[0] = bo->meta.offsets[1] = 0; - bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1]; - } else if (format == DRM_FORMAT_XRGB8888 || format == DRM_FORMAT_ARGB8888) { - bo->meta.strides[0] = drv_stride_from_format(format, width, 0); - bo->meta.total_size = bo->meta.sizes[0] = height * bo->meta.strides[0]; - bo->meta.offsets[0] = 0; - } else { - drv_log("unsupported format %X\n", format); - assert(0); - return -EINVAL; - } - - int ret; - for (plane = 0; plane < bo->meta.num_planes; plane++) { - size_t size = bo->meta.sizes[plane]; - struct drm_exynos_gem_create gem_create = { 0 }; - - gem_create.size = size; - gem_create.flags = EXYNOS_BO_NONCONTIG; - - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create); - if (ret) { - drv_log("DRM_IOCTL_EXYNOS_GEM_CREATE failed (size=%zu)\n", size); - ret = -errno; - goto cleanup_planes; - } - - bo->handles[plane].u32 = gem_create.handle; - } - - return 0; - -cleanup_planes: - for (; plane != 0; plane--) { - struct drm_gem_close gem_close = { 0 }; - - gem_close.handle = bo->handles[plane - 1].u32; - int gem_close_ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); - if (gem_close_ret) { - drv_log("DRM_IOCTL_GEM_CLOSE failed: %d\n", gem_close_ret); - } - } - - return ret; -} - -/* - * Use dumb mapping with exynos even though a GEM buffer is created. - * libdrm does the same thing in exynos_drm.c - */ -const struct backend backend_exynos = { - .name = "exynos", - .init = exynos_init, - .bo_create = exynos_bo_create, - .bo_destroy = drv_gem_bo_destroy, - .bo_import = drv_prime_bo_import, - .bo_map = drv_dumb_bo_map, - .bo_unmap = drv_bo_munmap, -}; - -#endif @@ -140,9 +140,9 @@ PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint return NULL; /* - * HACK: This is for HAL_PIXEL_FORMAT_YV12 buffers allocated by arcvm. None of - * our platforms can display YV12, so we can treat as a SW buffer. Remove once - * this can be intelligently resolved in the guest. Also see compute_virgl_bind_flags. + * HACK: See b/132939420. This is for HAL_PIXEL_FORMAT_YV12 buffers allocated by arcvm. None + * of our platforms can display YV12, so we can treat as a SW buffer. Remove once this can + * be intelligently resolved in the guest. Also see virgl_resolve_use_flags. */ if (format == GBM_FORMAT_YVU420 && (usage & GBM_BO_USE_LINEAR)) format = DRM_FORMAT_YVU420_ANDROID; @@ -15,9 +15,9 @@ #include <unistd.h> #include <xf86drm.h> +#include "drv_helpers.h" #include "drv_priv.h" #include "external/i915_drm.h" -#include "helpers.h" #include "util.h" #define I915_CACHELINE_SIZE 64 @@ -37,7 +37,8 @@ static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR }; -static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, +static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, + I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR }; struct modifier_support_t { @@ -58,13 +59,50 @@ static void i915_info_from_device_id(struct i915_device *i915) { const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE, 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 }; - const uint16_t gen11_ids[] = { 0x4E71, 0x4E61, 0x4E51, 0x4E55, 0x4E57 }; - const uint16_t gen12_ids[] = { 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68, 0x9A70, - 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8 }; - const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, - 0x46A8, 0x46AA, 0x462A, 0x4626, 0x4628, - 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46C0, - 0x46C1, 0x46C2, 0x46C3 }; + const uint16_t gen4_ids[] = { 0x29A2, 0x2992, 0x2982, 0x2972, 0x2A02, 0x2A12, 0x2A42, + 0x2E02, 0x2E12, 0x2E22, 0x2E32, 0x2E42, 0x2E92 }; + const uint16_t gen5_ids[] = { 0x0042, 0x0046 }; + const uint16_t gen6_ids[] = { 0x0102, 0x0112, 0x0122, 0x0106, 0x0116, 0x0126, 0x010A }; + const uint16_t gen7_ids[] = { + 0x0152, 0x0162, 0x0156, 0x0166, 0x015a, 0x016a, 0x0402, 0x0412, 0x0422, + 0x0406, 0x0416, 0x0426, 0x040A, 0x041A, 0x042A, 0x040B, 0x041B, 0x042B, + 0x040E, 0x041E, 0x042E, 0x0C02, 0x0C12, 0x0C22, 0x0C06, 0x0C16, 0x0C26, + 0x0C0A, 0x0C1A, 0x0C2A, 0x0C0B, 0x0C1B, 0x0C2B, 0x0C0E, 0x0C1E, 0x0C2E, + 0x0A02, 0x0A12, 0x0A22, 0x0A06, 0x0A16, 0x0A26, 0x0A0A, 0x0A1A, 0x0A2A, + 0x0A0B, 0x0A1B, 0x0A2B, 0x0A0E, 0x0A1E, 0x0A2E, 0x0D02, 0x0D12, 0x0D22, + 0x0D06, 0x0D16, 0x0D26, 0x0D0A, 0x0D1A, 0x0D2A, 0x0D0B, 0x0D1B, 0x0D2B, + 0x0D0E, 0x0D1E, 0x0D2E, 0x0F31, 0x0F32, 0x0F33, 0x0157, 0x0155 + }; + const uint16_t gen8_ids[] = { 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x1602, 0x1606, + 0x160A, 0x160B, 0x160D, 0x160E, 0x1612, 0x1616, + 0x161A, 0x161B, 0x161D, 0x161E, 0x1622, 0x1626, + 0x162A, 0x162B, 0x162D, 0x162E }; + const uint16_t gen9_ids[] = { + 0x1902, 0x1906, 0x190A, 0x190B, 0x190E, 0x1912, 0x1913, 0x1915, 0x1916, 0x1917, + 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, 0x1923, 0x1926, 0x1927, 0x192A, 0x192B, + 0x192D, 0x1932, 0x193A, 0x193B, 0x193D, 0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85, + 0x3184, 0x3185, 0x5902, 0x5906, 0x590A, 0x5908, 0x590B, 0x590E, 0x5913, 0x5915, + 0x5917, 0x5912, 0x5916, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921, 0x5923, 0x5926, + 0x5927, 0x593B, 0x591C, 0x87C0, 0x87CA, 0x3E90, 0x3E93, 0x3E99, 0x3E9C, 0x3E91, + 0x3E92, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3E94, 0x3EA9, 0x3EA5, 0x3EA6, 0x3EA7, + 0x3EA8, 0x3EA1, 0x3EA4, 0x3EA0, 0x3EA3, 0x3EA2, 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4, + 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC, 0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5, + 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC, 0x9BE6, 0x9BF6 + }; + const uint16_t gen11_ids[] = { 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A56, 0x8A57, + 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A71, + 0x4500, 0x4541, 0x4551, 0x4555, 0x4557, 0x4571, 0x4E51, + 0x4E55, 0x4E57, 0x4E61, 0x4E71 }; + const uint16_t gen12_ids[] = { + 0x4c8a, 0x4c8b, 0x4c8c, 0x4c90, 0x4c9a, 0x4680, 0x4681, 0x4682, 0x4683, 0x4688, + 0x4689, 0x4690, 0x4691, 0x4692, 0x4693, 0x4698, 0x4699, 0x4626, 0x4628, 0x462a, + 0x46a0, 0x46a1, 0x46a2, 0x46a3, 0x46a6, 0x46a8, 0x46aa, 0x46b0, 0x46b1, 0x46b2, + 0x46b3, 0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68, + 0x9A70, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, 0x4905, 0x4906, 0x4907, 0x4908 + }; + const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, + 0x46AA, 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1, + 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3 }; unsigned i; i915->gen = 4; i915->is_adlp = false; @@ -73,6 +111,36 @@ static void i915_info_from_device_id(struct i915_device *i915) if (gen3_ids[i] == i915->device_id) i915->gen = 3; + /* Gen 4 */ + for (i = 0; i < ARRAY_SIZE(gen4_ids); i++) + if (gen4_ids[i] == i915->device_id) + i915->gen = 4; + + /* Gen 5 */ + for (i = 0; i < ARRAY_SIZE(gen5_ids); i++) + if (gen5_ids[i] == i915->device_id) + i915->gen = 5; + + /* Gen 6 */ + for (i = 0; i < ARRAY_SIZE(gen6_ids); i++) + if (gen6_ids[i] == i915->device_id) + i915->gen = 6; + + /* Gen 7 */ + for (i = 0; i < ARRAY_SIZE(gen7_ids); i++) + if (gen7_ids[i] == i915->device_id) + i915->gen = 7; + + /* Gen 8 */ + for (i = 0; i < ARRAY_SIZE(gen8_ids); i++) + if (gen8_ids[i] == i915->device_id) + i915->gen = 8; + + /* Gen 9 */ + for (i = 0; i < ARRAY_SIZE(gen9_ids); i++) + if (gen9_ids[i] == i915->device_id) + i915->gen = 9; + /* Gen 11 */ for (i = 0; i < ARRAY_SIZE(gen11_ids); i++) if (gen11_ids[i] == i915->device_id) @@ -92,9 +160,9 @@ static void i915_info_from_device_id(struct i915_device *i915) static void i915_get_modifier_order(struct i915_device *i915) { - if (i915->gen == 11) { - i915->modifier.order = gen11_modifier_order; - i915->modifier.count = ARRAY_SIZE(gen11_modifier_order); + if (i915->gen == 12) { + i915->modifier.order = gen12_modifier_order; + i915->modifier.count = ARRAY_SIZE(gen12_modifier_order); } else { i915->modifier.order = gen_modifier_order; i915->modifier.count = ARRAY_SIZE(gen_modifier_order); @@ -249,10 +317,6 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid *stride = horizontal_alignment; } - /* stride must be power-of-two aligned for ADL-P tiled buffers*/ - if (i915->is_adlp && (*stride > 1) && (tiling != I915_TILING_NONE)) - *stride = 1 << (32 - __builtin_clz(*stride -1)); - if (i915->gen <= 3 && *stride > 8192) return -EINVAL; @@ -316,7 +380,8 @@ static int i915_init(struct driver *drv) * to the largest coded unit (LCU) assuming that it will be used for video. This * is based on gmmlib's GmmIsYUVFormatLCUAligned(). */ -static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane, const struct i915_device* i915) +static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane, + const struct i915_device *i915) { switch (format) { case DRM_FORMAT_NV12: @@ -418,6 +483,11 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig modifier = I915_FORMAT_MOD_Y_TILED; } + /* Prevent gen 8 and earlier from trying to use a tiling modifier */ + if (i915->gen <= 8 && format == DRM_FORMAT_ARGB8888) { + modifier = DRM_FORMAT_MOD_LINEAR; + } + switch (modifier) { case DRM_FORMAT_MOD_LINEAR: bo->meta.tiling = I915_TILING_NONE; @@ -427,6 +497,10 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig break; case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Y_TILED_CCS: + /* For now support only I915_TILING_Y as this works with all + * IPs(render/media/display) + */ + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: bo->meta.tiling = I915_TILING_Y; break; } @@ -485,6 +559,41 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig bo->meta.num_planes = 2; bo->meta.total_size = offset; + } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) { + + /* + * considering only 128 byte compression and one cache line of + * aux buffer(64B) contains compression status of 4-Y tiles. + * Which is 4 * (128B * 32L). + * line stride(bytes) is 4 * 128B + * and tile stride(lines) is 32L + */ + uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512); + + height = ALIGN(drv_height_from_format(format, height, 0), 32); + + if (i915->is_adlp && (stride > 1)) { + stride = 1 << (32 - __builtin_clz(stride - 1)); + height = ALIGN(drv_height_from_format(format, height, 0), 128); + } + + bo->meta.strides[0] = stride; + /* size calculation and alignment are 64KB aligned + * size as per spec + */ + bo->meta.sizes[0] = ALIGN(stride * height, 65536); + bo->meta.offsets[0] = 0; + + /* Aux buffer is linear and page aligned. It is placed after + * other planes and aligned to main buffer stride. + */ + bo->meta.strides[1] = bo->meta.strides[0] / 8; + /* Aligned to page size */ + bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize()); + bo->meta.offsets[1] = bo->meta.sizes[0]; + /* Total number of planes & sizes */ + bo->meta.num_planes = 2; + bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1]; } else { i915_bo_from_format(bo, width, height, format); } @@ -500,25 +609,20 @@ static int i915_bo_create_from_metadata(struct bo *bo) struct i915_device *i915 = bo->drv->priv; if (i915->has_hw_protection && (bo->meta.use_flags & BO_USE_PROTECTED)) { - struct drm_i915_gem_object_param protected_param = { - .param = I915_OBJECT_PARAM | I915_PARAM_PROTECTED_CONTENT, - .data = 1, - }; - - struct drm_i915_gem_create_ext_setparam setparam_protected = { - .base = { .name = I915_GEM_CREATE_EXT_SETPARAM }, - .param = protected_param, + struct drm_i915_gem_create_ext_protected_content protected_content = { + .base = { .name = I915_GEM_CREATE_EXT_PROTECTED_CONTENT }, + .flags = 0, }; struct drm_i915_gem_create_ext create_ext = { .size = bo->meta.total_size, - .extensions = (uintptr_t)&setparam_protected, + .extensions = (uintptr_t)&protected_content, }; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext); if (ret) { - drv_log("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu)\n", - create_ext.size); + drv_log("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n", + create_ext.size, ret); return -errno; } @@ -592,6 +696,9 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) return MAP_FAILED; + if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) + return MAP_FAILED; + if (bo->meta.tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map = { 0 }; /* TODO(b/118799155): We don't seem to have a good way to @@ -692,7 +799,7 @@ const struct backend backend_i915 = { .bo_unmap = drv_bo_munmap, .bo_invalidate = i915_bo_invalidate, .bo_flush = i915_bo_flush, - .resolve_format = drv_resolve_format_helper, + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, }; #endif @@ -19,8 +19,8 @@ #include <mediatek_drm.h> // clang-format on +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" #define TILE_TYPE_LINEAR 0 @@ -36,9 +36,11 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; #ifdef MTK_MT8183 -static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV21, DRM_FORMAT_NV12, - DRM_FORMAT_YUYV, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { + DRM_FORMAT_NV21, DRM_FORMAT_NV12, DRM_FORMAT_YUYV, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_ABGR2101010, + DRM_FORMAT_ABGR16161616F +}; #else static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_NV12 }; @@ -172,6 +174,7 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 int ret, prime_fd; struct drm_mtk_gem_map_off gem_map = { 0 }; struct mediatek_private_map_data *priv; + void *addr = NULL; gem_map.handle = bo->handles[0].u32; @@ -187,22 +190,38 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 return MAP_FAILED; } - void *addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, - gem_map.offset); + addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); + if (addr == MAP_FAILED) + goto out_close_prime_fd; vma->length = bo->meta.total_size; priv = calloc(1, sizeof(*priv)); - priv->prime_fd = prime_fd; - vma->priv = priv; + if (!priv) + goto out_unmap_addr; if (bo->meta.use_flags & BO_USE_RENDERSCRIPT) { priv->cached_addr = calloc(1, bo->meta.total_size); + if (!priv->cached_addr) + goto out_free_priv; + priv->gem_addr = addr; addr = priv->cached_addr; } + priv->prime_fd = prime_fd; + vma->priv = priv; + return addr; + +out_free_priv: + free(priv); +out_unmap_addr: + munmap(addr, bo->meta.total_size); +out_close_prime_fd: + close(prime_fd); + return MAP_FAILED; } static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) @@ -258,36 +277,55 @@ static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) +static void mediatek_resolve_format_and_use_flags(struct driver *drv, uint32_t format, + uint64_t use_flags, uint32_t *out_format, + uint64_t *out_use_flags) { + *out_format = format; + *out_use_flags = use_flags; switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: #ifdef MTK_MT8183 /* Only MT8183 Camera subsystem offers private reprocessing * capability. CAMERA_READ indicates the buffer is intended for * reprocessing and hence given the private format for MTK. */ - if (use_flags & BO_USE_CAMERA_READ) - return DRM_FORMAT_MTISP_SXYZW10; + if (use_flags & BO_USE_CAMERA_READ) { + *out_format = DRM_FORMAT_MTISP_SXYZW10; + break; + } #endif - if (use_flags & BO_USE_CAMERA_WRITE) - return DRM_FORMAT_NV12; + if (use_flags & BO_USE_CAMERA_WRITE) { + *out_format = DRM_FORMAT_NV12; + break; + } - /*HACK: See b/28671744 */ - return DRM_FORMAT_XBGR8888; + /* HACK: See b/28671744 */ + *out_format = DRM_FORMAT_XBGR8888; + *out_use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + break; case DRM_FORMAT_FLEX_YCbCr_420_888: #if defined(MTK_MT8183) || defined(MTK_MT8192) || defined(MTK_MT8195) // TODO(hiroh): Switch to use NV12 for video decoder on MT8173 as well. if (use_flags & (BO_USE_HW_VIDEO_DECODER)) { - return DRM_FORMAT_NV12; + *out_format = DRM_FORMAT_NV12; + break; } #endif if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_ENCODER)) { - return DRM_FORMAT_NV12; + *out_format = DRM_FORMAT_NV12; + break; } - return DRM_FORMAT_YVU420; + + /* HACK: See b/139714614 */ + *out_format = DRM_FORMAT_YVU420; + *out_use_flags &= ~BO_USE_SCANOUT; + break; + case DRM_FORMAT_YVU420_ANDROID: + *out_use_flags &= ~BO_USE_SCANOUT; + break; default: - return format; + break; } } @@ -302,7 +340,7 @@ const struct backend backend_mediatek = { .bo_unmap = mediatek_bo_unmap, .bo_invalidate = mediatek_bo_invalidate, .bo_flush = mediatek_bo_flush, - .resolve_format = mediatek_resolve_format, + .resolve_format_and_use_flags = mediatek_resolve_format_and_use_flags, }; #endif diff --git a/minigbm_helpers.c b/minigbm_helpers.c index 137e5a1..cea0b48 100644 --- a/minigbm_helpers.c +++ b/minigbm_helpers.c @@ -273,6 +273,9 @@ PUBLIC int gbm_get_default_device_fd(void) break; } } + + closedir(dir); + if (dfd >= 0) return dfd; @@ -18,8 +18,8 @@ #include <sys/mman.h> #include <xf86drm.h> +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" /* Alignment values are based on SDM845 Gfx IP */ @@ -41,7 +41,8 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, - DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_P010 }; /* * Each macrotile consists of m x n (mostly 4 x 4) tiles. @@ -94,10 +95,15 @@ static void msm_calculate_layout(struct bo *bo) /* NV12 format requires extra padding with platform * specific alignments for venus driver */ - if (bo->meta.format == DRM_FORMAT_NV12) { + if (bo->meta.format == DRM_FORMAT_NV12 || bo->meta.format == DRM_FORMAT_P010) { uint32_t y_stride, uv_stride, y_scanline, uv_scanline, y_plane, uv_plane, size, extra_padding; + // P010 has the same layout as NV12. The difference is that each + // pixel in P010 takes 2 bytes, while in NV12 each pixel takes 1 byte. + if (bo->meta.format == DRM_FORMAT_P010) + width *= 2; + y_stride = ALIGN(width, VENUS_STRIDE_ALIGN); uv_stride = ALIGN(width, VENUS_STRIDE_ALIGN); y_scanline = ALIGN(height, VENUS_SCANLINE_ALIGN * 2); @@ -158,7 +164,9 @@ static bool is_ubwc_fmt(uint32_t format) case DRM_FORMAT_ABGR8888: case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ARGB8888: +#ifndef QCOM_DISABLE_COMPRESSED_NV12 case DRM_FORMAT_NV12: +#endif return 1; default: return 0; @@ -252,9 +260,21 @@ static int msm_init(struct driver *drv) BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER); + /* + * Android also frequently requests YV12 formats for some camera implementations + * (including the external provider implmenetation). + */ + drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &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); +#ifdef SC_7280 + drv_modify_combination(drv, DRM_FORMAT_P010, &LINEAR_METADATA, + BO_USE_SCANOUT | BO_USE_HW_VIDEO_ENCODER); +#endif + drv_modify_linear_combinations(drv); if (should_avoid_ubwc() || !drv->compression) @@ -366,6 +386,6 @@ const struct backend backend_msm = { .bo_import = drv_prime_bo_import, .bo_map = msm_bo_map, .bo_unmap = drv_bo_munmap, - .resolve_format = drv_resolve_format_helper, + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, }; #endif /* DRV_MSM */ @@ -14,8 +14,8 @@ #include <sys/mman.h> #include <xf86drm.h> +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" struct rockchip_private_map_data { @@ -184,6 +184,7 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 int ret; struct rockchip_private_map_data *priv; struct drm_rockchip_gem_map_off gem_map = { 0 }; + void *addr = NULL; /* We can only map buffers created with SW access flags, which should * have no modifiers (ie, not AFBC). */ @@ -197,20 +198,34 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 return MAP_FAILED; } - void *addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, - gem_map.offset); + addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); + if (addr == MAP_FAILED) + return MAP_FAILED; vma->length = bo->meta.total_size; if (bo->meta.use_flags & BO_USE_RENDERSCRIPT) { priv = calloc(1, sizeof(*priv)); + if (!priv) + goto out_unmap_addr; + priv->cached_addr = calloc(1, bo->meta.total_size); + if (!priv->cached_addr) + goto out_free_priv; + priv->gem_addr = addr; vma->priv = priv; addr = priv->cached_addr; } return addr; + +out_free_priv: + free(priv); +out_unmap_addr: + munmap(addr, bo->meta.total_size); + return MAP_FAILED; } static int rockchip_bo_unmap(struct bo *bo, struct vma *vma) @@ -256,7 +271,7 @@ const struct backend backend_rockchip = { .bo_unmap = rockchip_bo_unmap, .bo_invalidate = rockchip_bo_invalidate, .bo_flush = rockchip_bo_flush, - .resolve_format = drv_resolve_format_helper, + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, }; #endif @@ -13,8 +13,8 @@ #include <vc4_drm.h> #include <xf86drm.h> +#include "drv_helpers.h" #include "drv_priv.h" -#include "helpers.h" #include "util.h" static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, @@ -131,6 +131,7 @@ const struct backend backend_vc4 = { .bo_destroy = drv_gem_bo_destroy, .bo_map = vc4_bo_map, .bo_unmap = drv_bo_munmap, + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, }; #endif @@ -13,7 +13,6 @@ #include "drv_priv.h" #include "external/virtgpu_drm.h" -#include "helpers.h" #include "util.h" #include "virtgpu.h" @@ -49,7 +48,7 @@ static int virtgpu_init(struct driver *drv) get_param.value = (uint64_t)(uintptr_t)¶ms[i].value; int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &get_param); if (ret) - drv_log("DRM_IOCTL_VIRTGPU_GET_PARAM failed with %s\n", strerror(errno)); + drv_log("virtgpu backend not enabling %s\n", params[i].name); } for (uint32_t i = 0; i < ARRAY_SIZE(virtgpu_backends); i++) { diff --git a/virtgpu_cross_domain.c b/virtgpu_cross_domain.c index b02a949..85ea1a3 100644 --- a/virtgpu_cross_domain.c +++ b/virtgpu_cross_domain.c @@ -9,10 +9,10 @@ #include <sys/mman.h> #include <xf86drm.h> +#include "drv_helpers.h" #include "drv_priv.h" #include "external/virtgpu_cross_domain_protocol.h" #include "external/virtgpu_drm.h" -#include "helpers.h" #include "util.h" #include "virtgpu.h" @@ -36,6 +36,7 @@ struct cross_domain_private { uint32_t ring_handle; void *ring_addr; struct drv_array *metadata_cache; + pthread_mutex_t metadata_cache_lock; }; static void cross_domain_release_private(struct driver *drv) @@ -57,7 +58,11 @@ static void cross_domain_release_private(struct driver *drv) } } - drv_array_destroy(priv->metadata_cache); + if (priv->metadata_cache) + drv_array_destroy(priv->metadata_cache); + + pthread_mutex_destroy(&priv->metadata_cache_lock); + free(priv); } @@ -107,7 +112,7 @@ static int cross_domain_submit_cmd(struct driver *drv, uint32_t *cmd, uint32_t c exec.command = (uint64_t)&cmd[0]; exec.size = cmd_size; if (wait) { - exec.flags = VIRTGPU_EXECBUF_FENCE_CONTEXT; + exec.flags = VIRTGPU_EXECBUF_RING_IDX; exec.bo_handles = (uint64_t)&priv->ring_handle; exec.num_bo_handles = 1; } @@ -150,7 +155,7 @@ static int cross_domain_metadata_query(struct driver *drv, struct bo_metadata *m uint32_t plane, remaining_size; memset(&cmd_get_reqs, 0, sizeof(cmd_get_reqs)); - pthread_mutex_lock(&drv->driver_lock); + pthread_mutex_lock(&priv->metadata_cache_lock); for (uint32_t i = 0; i < drv_array_size(priv->metadata_cache); i++) { cached_data = (struct bo_metadata *)drv_array_at_idx(priv->metadata_cache, i); if (!metadata_equal(metadata, cached_data)) @@ -185,11 +190,11 @@ static int cross_domain_metadata_query(struct driver *drv, struct bo_metadata *m memcpy(&metadata->offsets, &addr[4], 4 * sizeof(uint32_t)); memcpy(&metadata->format_modifier, &addr[8], sizeof(uint64_t)); memcpy(&metadata->total_size, &addr[10], sizeof(uint64_t)); - memcpy(&metadata->blob_id, &addr[12], sizeof(uint64_t)); + memcpy(&metadata->blob_id, &addr[12], sizeof(uint32_t)); - metadata->map_info = addr[14]; - metadata->memory_idx = addr[16]; - metadata->physical_device_idx = addr[17]; + metadata->map_info = addr[13]; + metadata->memory_idx = addr[14]; + metadata->physical_device_idx = addr[15]; remaining_size = metadata->total_size; for (plane = 0; plane < metadata->num_planes; plane++) { @@ -203,7 +208,7 @@ static int cross_domain_metadata_query(struct driver *drv, struct bo_metadata *m drv_array_append(priv->metadata_cache, metadata); out_unlock: - pthread_mutex_unlock(&drv->driver_lock); + pthread_mutex_unlock(&priv->metadata_cache_lock); return ret; } @@ -243,7 +248,21 @@ static int cross_domain_init(struct driver *drv) return -ENOTSUP; priv = calloc(1, sizeof(*priv)); + if (!priv) + return -ENOMEM; + + ret = pthread_mutex_init(&priv->metadata_cache_lock, NULL); + if (ret) { + free(priv); + return ret; + } + priv->metadata_cache = drv_array_init(sizeof(struct bo_metadata)); + if (!priv->metadata_cache) { + ret = -ENOMEM; + goto free_private; + } + priv->ring_addr = MAP_FAILED; drv->priv = priv; @@ -269,7 +288,7 @@ static int cross_domain_init(struct driver *drv) // queries. ctx_set_params[0].param = VIRTGPU_CONTEXT_PARAM_CAPSET_ID; ctx_set_params[0].value = CAPSET_CROSS_DOMAIN; - ctx_set_params[1].param = VIRTGPU_CONTEXT_PARAM_NUM_FENCE_CONTEXTS; + ctx_set_params[1].param = VIRTGPU_CONTEXT_PARAM_NUM_RINGS; ctx_set_params[1].value = 1; init.ctx_set_params = (unsigned long long)&ctx_set_params[0]; @@ -363,7 +382,7 @@ static int cross_domain_bo_create(struct bo *bo, uint32_t width, uint32_t height drm_rc_blob.size = bo->meta.total_size; drm_rc_blob.blob_flags = blob_flags; - drm_rc_blob.blob_id = bo->meta.blob_id; + drm_rc_blob.blob_id = (uint64_t)bo->meta.blob_id; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob); if (ret < 0) { @@ -403,5 +422,5 @@ const struct backend virtgpu_cross_domain = { .bo_destroy = drv_gem_bo_destroy, .bo_map = cross_domain_bo_map, .bo_unmap = drv_bo_munmap, - .resolve_format = drv_resolve_format_helper, + .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper, }; diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c index 32ca6a1..c159c21 100644 --- a/virtgpu_virgl.c +++ b/virtgpu_virgl.c @@ -12,31 +12,45 @@ #include <sys/mman.h> #include <xf86drm.h> +#include "drv_helpers.h" #include "drv_priv.h" #include "external/virgl_hw.h" #include "external/virgl_protocol.h" #include "external/virtgpu_drm.h" -#include "helpers.h" #include "util.h" #include "virtgpu.h" #define PIPE_TEXTURE_2D 2 +#define MESA_LLVMPIPE_MAX_TEXTURE_2D_LEVELS 15 +#define MESA_LLVMPIPE_MAX_TEXTURE_2D_SIZE (1 << (MESA_LLVMPIPE_MAX_TEXTURE_2D_LEVELS - 1)) #define MESA_LLVMPIPE_TILE_ORDER 6 #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) +// This comes from a combination of SwiftShader's VkPhysicalDeviceLimits::maxFramebufferWidth and +// VkPhysicalDeviceLimits::maxImageDimension2D (see https://crrev.com/c/1917130). +#define ANGLE_ON_SWIFTSHADER_MAX_TEXTURE_2D_SIZE 8192 + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#define VIRGL_2D_MAX_TEXTURE_2D_SIZE \ + MIN(ANGLE_ON_SWIFTSHADER_MAX_TEXTURE_2D_SIZE, MESA_LLVMPIPE_MAX_TEXTURE_2D_SIZE) + static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { - DRM_FORMAT_R8, DRM_FORMAT_R16, DRM_FORMAT_YVU420, - DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_YVU420_ANDROID + DRM_FORMAT_R8, DRM_FORMAT_R16, DRM_FORMAT_YVU420, + DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR16161616F }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_NV21, - DRM_FORMAT_R8, DRM_FORMAT_R16, - DRM_FORMAT_RG88, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { + DRM_FORMAT_NV21, DRM_FORMAT_R8, DRM_FORMAT_R16, DRM_FORMAT_RG88, + DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR16161616F +}; extern struct virtgpu_param params[]; @@ -63,6 +77,8 @@ static uint32_t translate_format(uint32_t drm_fourcc) return VIRGL_FORMAT_R8G8B8A8_UNORM; case DRM_FORMAT_ABGR16161616F: return VIRGL_FORMAT_R16G16B16A16_FLOAT; + case DRM_FORMAT_ABGR2101010: + return VIRGL_FORMAT_R10G10B10A2_UNORM; case DRM_FORMAT_RGB565: return VIRGL_FORMAT_B5G6R5_UNORM; case DRM_FORMAT_R8: @@ -330,12 +346,10 @@ static bool virgl_supports_combination_through_emulation(struct driver *drv, uin static void virgl_add_combination(struct driver *drv, uint32_t drm_format, struct format_metadata *metadata, uint64_t use_flags) { - struct virgl_priv *priv = (struct virgl_priv *)drv->priv; - - if (params[param_3d].value && priv->caps.max_version >= 1) { - if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 && - !virgl_supports_combination_natively(drv, drm_format, use_flags)) { - drv_log("Scanout format: %d\n", drm_format); + if (params[param_3d].value) { + if ((use_flags & BO_USE_SCANOUT) && + !virgl_supports_combination_natively(drv, drm_format, BO_USE_SCANOUT)) { + drv_log("Strip scanout on format: %d\n", drm_format); use_flags &= ~BO_USE_SCANOUT; } @@ -361,8 +375,8 @@ static void virgl_add_combinations(struct driver *drv, const uint32_t *drm_forma virgl_add_combination(drv, drm_formats[i], metadata, use_flags); } -static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) +static int virgl_2d_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) { if (bo->meta.format != DRM_FORMAT_R8) { width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); @@ -391,6 +405,8 @@ static uint32_t compute_virgl_bind_flags(uint64_t use_flags, uint32_t format) handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT); handle_flag(&use_flags, BO_USE_CURSOR, &bind, VIRGL_BIND_CURSOR); handle_flag(&use_flags, BO_USE_LINEAR, &bind, VIRGL_BIND_LINEAR); + handle_flag(&use_flags, BO_USE_GPU_DATA_BUFFER, &bind, VIRGL_BIND_LINEAR); + handle_flag(&use_flags, BO_USE_FRONT_RENDERING, &bind, VIRGL_BIND_LINEAR); if (use_flags & BO_USE_PROTECTED) { handle_flag(&use_flags, BO_USE_PROTECTED, &bind, VIRGL_BIND_MINIGBM_PROTECTED); @@ -420,14 +436,6 @@ static uint32_t compute_virgl_bind_flags(uint64_t use_flags, uint32_t format) handle_flag(&use_flags, BO_USE_HW_VIDEO_ENCODER, &bind, VIRGL_BIND_MINIGBM_HW_VIDEO_ENCODER); - /* - * HACK: This is for HAL_PIXEL_FORMAT_YV12 buffers allocated by arcvm. None of - * our platforms can display YV12, so we can treat as a SW buffer. Remove once - * this can be intelligently resolved in the guest. Also see gbm_bo_create. - */ - if (format == DRM_FORMAT_YVU420_ANDROID) - bind |= VIRGL_BIND_LINEAR; - if (use_flags) drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags); @@ -512,6 +520,16 @@ static void *virgl_3d_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 gem_map.offset); } +static uint32_t virgl_3d_get_max_texture_2d_size(struct driver *drv) +{ + struct virgl_priv *priv = (struct virgl_priv *)drv->priv; + + if (priv->caps.v2.max_texture_2d_size) + return priv->caps.v2.max_texture_2d_size; + + return UINT32_MAX; +} + static int virgl_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_is_v2) { int ret; @@ -569,6 +587,9 @@ static int virgl_init(struct driver *drv) struct virgl_priv *priv; priv = calloc(1, sizeof(*priv)); + if (!priv) + return -ENOMEM; + drv->priv = priv; virgl_init_params_and_caps(drv); @@ -582,6 +603,12 @@ static int virgl_init(struct driver *drv) virgl_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + /* NV12 with scanout must flow through virgl_add_combination, so that the native + * support is checked and scanout use_flag can be conditionally stripped. */ + virgl_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_TEXTURE_MASK | BO_USE_CAMERA_READ | + BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER | BO_USE_SCANOUT); } else { /* Virtio primary plane only allows this format. */ virgl_add_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA, @@ -598,28 +625,19 @@ static int virgl_init(struct driver *drv) virgl_add_combinations(drv, dumb_texture_source_formats, ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - virgl_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_SW_MASK | BO_USE_LINEAR); - virgl_add_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA, - BO_USE_SW_MASK | BO_USE_LINEAR); + 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); } /* Android CTS tests require this. */ virgl_add_combination(drv, DRM_FORMAT_RGB888, &LINEAR_METADATA, BO_USE_SW_MASK); virgl_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); - virgl_add_combination(drv, DRM_FORMAT_ABGR16161616F, &LINEAR_METADATA, - BO_USE_SW_MASK | BO_USE_TEXTURE_MASK); - virgl_add_combination(drv, DRM_FORMAT_ABGR2101010, &LINEAR_METADATA, - BO_USE_SW_MASK | BO_USE_TEXTURE_MASK); virgl_add_combination(drv, DRM_FORMAT_P010, &LINEAR_METADATA, - BO_USE_SW_MASK | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); - - 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); + BO_USE_SW_MASK | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | - BO_USE_HW_VIDEO_ENCODER); + BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER); if (!priv->host_gbm_enabled) { drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA, @@ -663,8 +681,10 @@ static int virgl_bo_create_blob(struct driver *drv, struct bo *bo) uint32_t blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE; if (bo->meta.use_flags & BO_USE_SW_MASK) blob_flags |= VIRTGPU_BLOB_FLAG_USE_MAPPABLE; - if (bo->meta.use_flags & BO_USE_NON_GPU_HW) - blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE; + + // For now, all blob use cases are cross device. When we add wider + // support for blobs, we can revisit making this unconditional. + blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE; cur_blob_id = atomic_fetch_add(&priv->next_blob_id, 1); stride = drv_stride_from_format(bo->meta.format, bo->meta.width, 0); @@ -714,16 +734,17 @@ static bool should_use_blob(struct driver *drv, uint32_t format, uint64_t use_fl if (!priv->host_gbm_enabled) return false; - // Use regular resources if only the GPU needs efficient access - if (!(use_flags & - (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_LINEAR | BO_USE_NON_GPU_HW))) + // Use regular resources if only the GPU needs efficient access. Blob resource is a better + // fit for BO_USE_GPU_DATA_BUFFER which is mapped to VIRGL_BIND_LINEAR. + if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_LINEAR | + BO_USE_NON_GPU_HW | BO_USE_GPU_DATA_BUFFER))) return false; switch (format) { - case DRM_FORMAT_YVU420_ANDROID: case DRM_FORMAT_R8: // Formats with strictly defined strides are supported return true; + case DRM_FORMAT_YVU420_ANDROID: case DRM_FORMAT_NV12: // Knowing buffer metadata at buffer creation isn't yet supported, so buffers // can't be properly mapped into the guest. @@ -743,7 +764,7 @@ static int virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3 if (params[param_3d].value) return virgl_3d_bo_create(bo, width, height, format, use_flags); else - return virtio_dumb_bo_create(bo, width, height, format, use_flags); + return virgl_2d_dumb_bo_create(bo, width, height, format, use_flags); } static int virgl_bo_destroy(struct bo *bo) @@ -934,28 +955,97 @@ static int virgl_bo_flush(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t virgl_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) +static void virgl_3d_resolve_format_and_use_flags(struct driver *drv, uint32_t format, + uint64_t use_flags, uint32_t *out_format, + uint64_t *out_use_flags) { + *out_format = format; + *out_use_flags = 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; + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) { + *out_format = DRM_FORMAT_NV12; + } else { + /* HACK: See b/28671744 */ + *out_format = DRM_FORMAT_XBGR8888; + *out_use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + } + break; case DRM_FORMAT_FLEX_YCbCr_420_888: - /* - * All of our host drivers prefer NV12 as their flexible media format. - * If that changes, this will need to be modified. - */ - if (params[param_3d].value) - return DRM_FORMAT_NV12; - else - return DRM_FORMAT_YVU420_ANDROID; + /* All of our host drivers prefer NV12 as their flexible media format. + * If that changes, this will need to be modified. */ + *out_format = DRM_FORMAT_NV12; + /* fallthrough */ + case DRM_FORMAT_NV12: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_XRGB8888: + /* These are the scanout capable formats to the guest. Strip scanout use_flag if the + * host does not natively support scanout on the requested format. */ + if ((use_flags & BO_USE_SCANOUT) && + !virgl_supports_combination_natively(drv, format, BO_USE_SCANOUT)) + *out_use_flags &= ~BO_USE_SCANOUT; + break; + case DRM_FORMAT_YVU420_ANDROID: + *out_use_flags &= ~BO_USE_SCANOUT; + /* HACK: See b/172389166. Also see gbm_bo_create. */ + *out_use_flags |= BO_USE_LINEAR; + break; + default: + break; + } +} + +static void virgl_2d_resolve_format_and_use_flags(uint32_t format, uint64_t use_flags, + uint32_t *out_format, uint64_t *out_use_flags) +{ + *out_format = format; + *out_use_flags = use_flags; + + /* HACK: See crrev/c/1849773 */ + if (format != DRM_FORMAT_XRGB8888) + *out_use_flags &= ~BO_USE_SCANOUT; + + switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /* Camera subsystem requires NV12. */ + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) { + *out_format = DRM_FORMAT_NV12; + } else { + /* HACK: See b/28671744 */ + *out_format = DRM_FORMAT_XBGR8888; + *out_use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + } + break; + case DRM_FORMAT_FLEX_YCbCr_420_888: + *out_format = DRM_FORMAT_YVU420_ANDROID; + /* fallthrough */ + case DRM_FORMAT_YVU420_ANDROID: + *out_use_flags &= ~BO_USE_SCANOUT; + /* HACK: See b/172389166. Also see gbm_bo_create. */ + *out_use_flags |= BO_USE_LINEAR; + break; default: - return format; + break; + } +} + +static void virgl_resolve_format_and_use_flags(struct driver *drv, uint32_t format, + uint64_t use_flags, uint32_t *out_format, + uint64_t *out_use_flags) +{ + if (params[param_3d].value) { + return virgl_3d_resolve_format_and_use_flags(drv, format, use_flags, out_format, + out_use_flags); + } else { + return virgl_2d_resolve_format_and_use_flags(format, use_flags, out_format, + out_use_flags); } } + static int virgl_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier) { @@ -973,21 +1063,30 @@ static int virgl_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], return ret; } - for (uint32_t plane = 0; plane < bo->meta.num_planes; plane++) { + for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) { /* * Currently, kernel v4.14 (Betty) doesn't have the extended resource info * ioctl. */ - if (res_info.strides[plane]) { - strides[plane] = res_info.strides[plane]; - offsets[plane] = res_info.offsets[plane]; - } + if (!res_info.strides[plane]) + break; + + strides[plane] = res_info.strides[plane]; + offsets[plane] = res_info.offsets[plane]; } *format_modifier = res_info.format_modifier; return 0; } +static uint32_t virgl_get_max_texture_2d_size(struct driver *drv) +{ + if (params[param_3d].value) + return virgl_3d_get_max_texture_2d_size(drv); + else + return VIRGL_2D_MAX_TEXTURE_2D_SIZE; +} + const struct backend virtgpu_virgl = { .name = "virtgpu_virgl", .init = virgl_init, .close = virgl_close, @@ -998,5 +1097,7 @@ const struct backend virtgpu_virgl = { .name = "virtgpu_virgl", .bo_unmap = drv_bo_munmap, .bo_invalidate = virgl_bo_invalidate, .bo_flush = virgl_bo_flush, - .resolve_format = virgl_resolve_format, - .resource_info = virgl_resource_info }; + .resolve_format_and_use_flags = + virgl_resolve_format_and_use_flags, + .resource_info = virgl_resource_info, + .get_max_texture_2d_size = virgl_get_max_texture_2d_size }; |