summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Macnak <natsu@google.com>2023-12-20 19:48:58 +0000
committerJason Macnak <natsu@google.com>2023-12-20 19:51:35 +0000
commit31b7dab231a66074e4c22d05c809cba62d19fcb9 (patch)
tree2e67969f3176fbf88e2855c0acca37afc3ae1ce9
parentb5db10cf57040470d521cd05bcb292da1f238108 (diff)
parent6897f2aa86c67198812320c7ad54c9e73e0a87ae (diff)
downloadminigbm-android12-gsi.tar.gz
Merge remote-tracking branch 'aosp/android13-gsi' into 'aosp/android12-gsi'android12-gsi
... to pull in http://crrev.com/c/3265944 to disable GPU_MIPMAP_COMPLETE. Bug: b/303050016 Test: cts -m CtsNativeHardwareTestCases Change-Id: I0aaf6930443ce55f907d765703a0ebd1b87cc2c7
-rw-r--r--Android.bp172
-rw-r--r--Android.gralloc.mk11
-rw-r--r--Makefile4
-rw-r--r--OWNERS20
-rw-r--r--amdgpu.c151
-rw-r--r--common.mk2
-rw-r--r--cros_gralloc/OWNERS3
-rw-r--r--cros_gralloc/cros_gralloc_buffer.cc118
-rw-r--r--cros_gralloc/cros_gralloc_buffer.h35
-rw-r--r--cros_gralloc/cros_gralloc_driver.cc329
-rw-r--r--cros_gralloc/cros_gralloc_driver.h54
-rw-r--r--cros_gralloc/cros_gralloc_handle.h4
-rw-r--r--cros_gralloc/cros_gralloc_helpers.cc129
-rw-r--r--cros_gralloc/cros_gralloc_helpers.h23
-rw-r--r--cros_gralloc/cros_gralloc_types.h23
-rw-r--r--cros_gralloc/gralloc0/gralloc0.cc156
-rw-r--r--cros_gralloc/gralloc0/tests/gralloctest.c2
-rw-r--r--cros_gralloc/gralloc3/.clang-format19
-rw-r--r--cros_gralloc/gralloc3/Android.bp88
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3Allocator.cc128
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3Allocator.h29
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc30
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3Mapper.cc490
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3Mapper.h64
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3Utils.cc402
-rw-r--r--cros_gralloc/gralloc3/CrosGralloc3Utils.h39
-rw-r--r--cros_gralloc/gralloc3/android.hardware.graphics.allocator@3.0-service.minigbm.rc14
-rw-r--r--cros_gralloc/gralloc4/Android.bp170
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Allocator.cc61
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Allocator.h12
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc15
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Mapper.cc364
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Mapper.h32
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Metadata.h37
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Utils.cc300
-rw-r--r--cros_gralloc/gralloc4/CrosGralloc4Utils.h2
-rw-r--r--cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc2
-rw-r--r--cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_arcvm.rc24
-rw-r--r--cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_intel.rc24
-rw-r--r--cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc2
-rw-r--r--dri.c51
-rw-r--r--dri.h3
-rw-r--r--drv.c258
-rw-r--r--drv.h23
-rw-r--r--drv_array_helpers.c (renamed from helpers_array.c)8
-rw-r--r--drv_array_helpers.h (renamed from helpers_array.h)7
-rw-r--r--drv_helpers.c (renamed from helpers.c)106
-rw-r--r--drv_helpers.h (renamed from helpers.h)25
-rw-r--r--drv_priv.h15
-rw-r--r--dumb_driver.c25
-rw-r--r--external/i915_drm.h235
-rw-r--r--external/virgl_hw.h6
-rw-r--r--external/virtgpu_cross_domain_protocol.h57
-rw-r--r--external/virtgpu_drm.h9
-rw-r--r--exynos.c112
-rw-r--r--gbm.c6
-rw-r--r--i915.c186
-rw-r--r--mediatek.c140
-rw-r--r--minigbm_helpers.c3
-rw-r--r--msm.c50
-rw-r--r--rockchip.c50
-rw-r--r--vc4.c3
-rw-r--r--virtgpu.c3
-rw-r--r--virtgpu_cross_domain.c53
-rw-r--r--virtgpu_virgl.c241
65 files changed, 2363 insertions, 2896 deletions
diff --git a/Android.bp b/Android.bp
index e7dfff8..e2d74d2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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,58 +103,54 @@ 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: [
"libcutils",
+ "libdmabufheap",
"libdrm",
"libnativewindow",
"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 +170,43 @@ 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"],
+ cflags: ["-DHAS_DMABUF_SYSTEM_HEAP"],
}
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 +216,47 @@ 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",
+ "-DHAS_DMABUF_SYSTEM_HEAP",
],
}
-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
diff --git a/Makefile b/Makefile
index 8238026..987708f 100644
--- a/Makefile
+++ b/Makefile
@@ -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))
diff --git a/OWNERS b/OWNERS
index 6a69a37..6d49c2d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -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
-stevensd@chromium.org
+mcasas@chromium.org
+olv@google.com
+robdclark@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, hsinyi@chromium.org, tzungbi@chromium.org
+per-file msm.c = robdclark@chromium.org, hoegsberg@chromium.org
+per-file rockchip.c = tfiga@chromium.org
+per-file virtgpu* = jbates@chromium.org, natsu@google.com, olv@google.com, zzyiwei@chromium.org
diff --git a/amdgpu.c b/amdgpu.c
index f987f6f..7ff61a4 100644
--- a/amdgpu.c
+++ b/amdgpu.c
@@ -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).
+ * This only applies to the Android YUV (multiplane) format.
* */
- if (priv->dev_info.family == AMDGPU_FAMILY_RV && num_planes > 1)
+ if (format == DRM_FORMAT_YVU420_ANDROID &&
+ (priv->dev_info.family == AMDGPU_FAMILY_RV || priv->dev_info.family == AMDGPU_FAMILY_CZ))
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,15 +622,26 @@ 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;
}
+ bo->meta.num_planes = dri_num_planes_from_modifier(bo->drv, data->format,
+ data->format_modifier);
+
if (dri_tiling)
return dri_bo_import(bo, data);
else
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 +791,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/common.mk b/common.mk
index 3d7e7d4..a06728b 100644
--- a/common.mk
+++ b/common.mk
@@ -7,7 +7,7 @@
#
# NOTE NOTE NOTE
# The authoritative common.mk is located in:
-# https://chromium.googlesource.com/chromiumos/platform2/+/master/common-mk
+# https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/common-mk
# Please make all changes there, then copy into place in other repos.
# NOTE NOTE NOTE
#
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.cc b/cros_gralloc/cros_gralloc_buffer.cc
index 2f4ceb0..e1af7a4 100644
--- a/cros_gralloc/cros_gralloc_buffer.cc
+++ b/cros_gralloc/cros_gralloc_buffer.cc
@@ -9,34 +9,110 @@
#include <assert.h>
#include <sys/mman.h>
-cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
- struct cros_gralloc_handle *acquire_handle,
- int32_t reserved_region_fd, uint64_t reserved_region_size)
- : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0),
- reserved_region_fd_(reserved_region_fd), reserved_region_size_(reserved_region_size),
- reserved_region_addr_(nullptr)
+#include <cutils/native_handle.h>
+
+/*static*/
+std::unique_ptr<cros_gralloc_buffer>
+cros_gralloc_buffer::create(struct bo *acquire_bo,
+ const struct cros_gralloc_handle *borrowed_handle)
+{
+ auto acquire_hnd =
+ reinterpret_cast<struct cros_gralloc_handle *>(native_handle_clone(borrowed_handle));
+ if (!acquire_hnd) {
+ drv_log("Failed to create cros_gralloc_buffer: failed to clone handle.\n");
+ return {};
+ }
+
+ std::unique_ptr<cros_gralloc_buffer> buffer(
+ new cros_gralloc_buffer(acquire_bo, acquire_hnd));
+ if (!buffer) {
+ drv_log("Failed to create cros_gralloc_buffer: failed to allocate.\n");
+ native_handle_close(acquire_hnd);
+ native_handle_delete(acquire_hnd);
+ return {};
+ }
+
+ return buffer;
+}
+
+cros_gralloc_buffer::cros_gralloc_buffer(struct bo *acquire_bo,
+ struct cros_gralloc_handle *acquire_handle)
+ : bo_(acquire_bo), hnd_(acquire_handle)
{
assert(bo_);
- num_planes_ = drv_bo_get_num_planes(bo_);
- for (uint32_t plane = 0; plane < num_planes_; plane++)
+ assert(hnd_);
+ for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++)
lock_data_[plane] = nullptr;
}
cros_gralloc_buffer::~cros_gralloc_buffer()
{
drv_bo_destroy(bo_);
- if (hnd_) {
- native_handle_close(hnd_);
- native_handle_delete(hnd_);
- }
if (reserved_region_addr_) {
- munmap(reserved_region_addr_, reserved_region_size_);
+ munmap(reserved_region_addr_, hnd_->reserved_region_size);
}
+ native_handle_close(hnd_);
+ native_handle_delete(hnd_);
}
uint32_t cros_gralloc_buffer::get_id() const
{
- return id_;
+ return hnd_->id;
+}
+
+uint32_t cros_gralloc_buffer::get_width() const
+{
+ return hnd_->width;
+}
+
+uint32_t cros_gralloc_buffer::get_height() const
+{
+ return hnd_->height;
+}
+
+uint32_t cros_gralloc_buffer::get_format() const
+{
+ return hnd_->format;
+}
+
+uint64_t cros_gralloc_buffer::get_format_modifier() const
+{
+ return hnd_->format_modifier;
+}
+
+uint64_t cros_gralloc_buffer::get_total_size() const
+{
+ return hnd_->total_size;
+}
+
+uint32_t cros_gralloc_buffer::get_num_planes() const
+{
+ return hnd_->num_planes;
+}
+
+uint32_t cros_gralloc_buffer::get_plane_offset(uint32_t plane) const
+{
+ return hnd_->offsets[plane];
+}
+
+uint32_t cros_gralloc_buffer::get_plane_stride(uint32_t plane) const
+{
+ return hnd_->strides[plane];
+}
+
+uint32_t cros_gralloc_buffer::get_plane_size(uint32_t plane) const
+{
+ return hnd_->sizes[plane];
+}
+
+int32_t cros_gralloc_buffer::get_android_format() const
+{
+ return hnd_->droid_format;
+}
+
+uint64_t cros_gralloc_buffer::get_android_usage() const
+{
+ return static_cast<uint64_t>(hnd_->usage);
}
int32_t cros_gralloc_buffer::increase_refcount()
@@ -91,7 +167,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla
}
}
- for (uint32_t plane = 0; plane < num_planes_; plane++)
+ for (uint32_t plane = 0; plane < hnd_->num_planes; plane++)
addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane);
lockcount_++;
@@ -148,16 +224,18 @@ int32_t cros_gralloc_buffer::flush()
return 0;
}
-int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size)
+int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) const
{
- if (reserved_region_fd_ <= 0) {
+ int32_t reserved_region_fd = hnd_->fds[hnd_->num_planes];
+ if (reserved_region_fd < 0) {
drv_log("Buffer does not have reserved region.\n");
return -EINVAL;
}
if (!reserved_region_addr_) {
- reserved_region_addr_ = mmap(nullptr, reserved_region_size_, PROT_WRITE | PROT_READ,
- MAP_SHARED, reserved_region_fd_, 0);
+ reserved_region_addr_ =
+ mmap(nullptr, hnd_->reserved_region_size, PROT_WRITE | PROT_READ, MAP_SHARED,
+ reserved_region_fd, 0);
if (reserved_region_addr_ == MAP_FAILED) {
drv_log("Failed to mmap reserved region: %s.\n", strerror(errno));
return -errno;
@@ -165,6 +243,6 @@ int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size)
}
*addr = reserved_region_addr_;
- *size = reserved_region_size_;
+ *size = hnd_->reserved_region_size;
return 0;
}
diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h
index 9bc0ef0..21f8306 100644
--- a/cros_gralloc/cros_gralloc_buffer.h
+++ b/cros_gralloc/cros_gralloc_buffer.h
@@ -7,18 +7,30 @@
#ifndef CROS_GRALLOC_BUFFER_H
#define CROS_GRALLOC_BUFFER_H
-#include "../drv.h"
+#include <memory>
+
#include "cros_gralloc_helpers.h"
class cros_gralloc_buffer
{
public:
- cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
- struct cros_gralloc_handle *acquire_handle, int32_t reserved_region_fd,
- uint64_t reserved_region_size);
+ static std::unique_ptr<cros_gralloc_buffer>
+ create(struct bo *acquire_bo, const struct cros_gralloc_handle *borrowed_handle);
+
~cros_gralloc_buffer();
uint32_t get_id() const;
+ uint32_t get_width() const;
+ uint32_t get_height() const;
+ uint32_t get_format() const;
+ uint64_t get_format_modifier() const;
+ uint64_t get_total_size() const;
+ uint32_t get_num_planes() const;
+ uint32_t get_plane_offset(uint32_t plane) const;
+ uint32_t get_plane_stride(uint32_t plane) const;
+ uint32_t get_plane_size(uint32_t plane) const;
+ int32_t get_android_format() const;
+ uint64_t get_android_usage() const;
/* The new reference count is returned by both these functions. */
int32_t increase_refcount();
@@ -33,28 +45,27 @@ class cros_gralloc_buffer
int32_t invalidate();
int32_t flush();
- int32_t get_reserved_region(void **reserved_region_addr, uint64_t *reserved_region_size);
+ int32_t get_reserved_region(void **reserved_region_addr,
+ uint64_t *reserved_region_size) const;
private:
+ cros_gralloc_buffer(struct bo *acquire_bo, struct cros_gralloc_handle *acquire_handle);
+
cros_gralloc_buffer(cros_gralloc_buffer const &);
cros_gralloc_buffer operator=(cros_gralloc_buffer const &);
- uint32_t id_;
struct bo *bo_;
/* Note: this will be nullptr for imported/retained buffers. */
struct cros_gralloc_handle *hnd_;
- int32_t refcount_;
- int32_t lockcount_;
- uint32_t num_planes_;
+ int32_t refcount_ = 1;
+ int32_t lockcount_ = 0;
struct mapping *lock_data_[DRV_MAX_PLANES];
/* Optional additional shared memory region attached to some gralloc buffers. */
- int32_t reserved_region_fd_;
- uint64_t reserved_region_size_;
- void *reserved_region_addr_;
+ mutable void *reserved_region_addr_ = nullptr;
};
#endif
diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc
index f0c0392..46de30d 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,32 @@ int memfd_create_wrapper(const char *name, unsigned int flags)
return fd;
}
-cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr)
+int memfd_create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size)
{
+ const std::string reserved_region_name = buffer_name + " reserved region";
+
+ int reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC);
+ if (reserved_region_fd == -1)
+ return -errno;
+
+ if (ftruncate(reserved_region_fd, reserved_region_size)) {
+ drv_log("Failed to set reserved region size: %s.\n", strerror(errno));
+ return -errno;
+ }
+
+ return reserved_region_fd;
}
-cros_gralloc_driver::~cros_gralloc_driver()
+cros_gralloc_driver *cros_gralloc_driver::get_instance()
{
- 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 +94,7 @@ static struct driver *init_try_node(int idx, char const *str)
return drv;
}
-int32_t cros_gralloc_driver::init()
+static struct driver *init_try_nodes()
{
/*
* Create a driver from render nodes first, then try card
@@ -93,6 +103,7 @@ int32_t cros_gralloc_driver::init()
* TODO(gsingh): Enable render nodes on udl/evdi.
*/
+ struct driver *drv;
char const *render_nodes_fmt = "%s/renderD%d";
char const *card_nodes_fmt = "%s/card%d";
uint32_t num_nodes = DRM_NUM_NODES;
@@ -103,84 +114,132 @@ int32_t cros_gralloc_driver::init()
// Try render nodes...
for (uint32_t i = min_render_node; i < max_render_node; i++) {
- drv_ = init_try_node(i, render_nodes_fmt);
- if (drv_)
- return 0;
+ drv = init_try_node(i, render_nodes_fmt);
+ if (drv)
+ return drv;
}
// Try card nodes... for vkms mostly.
for (uint32_t i = min_card_node; i < max_card_node; i++) {
- drv_ = init_try_node(i, card_nodes_fmt);
- if (drv_)
- return 0;
+ drv = init_try_node(i, card_nodes_fmt);
+ if (drv)
+ return drv;
}
- return -ENODEV;
+ return nullptr;
}
-bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor)
+static void drv_destroy_and_close(struct driver *drv)
+{
+ int fd = drv_get_fd(drv);
+ drv_destroy(drv);
+ close(fd);
+}
+
+cros_gralloc_driver::cros_gralloc_driver() : drv_(init_try_nodes(), drv_destroy_and_close)
{
- struct combination *combo;
- 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);
}
-int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size)
+cros_gralloc_driver::~cros_gralloc_driver()
{
- std::string reserved_region_name = buffer_name + " reserved region";
+ buffers_.clear();
+ handles_.clear();
+}
- int32_t reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC);
- if (reserved_region_fd == -1)
- return -errno;
+bool cros_gralloc_driver::is_initialized()
+{
+ return drv_ != nullptr;
+}
- if (ftruncate(reserved_region_fd, reserved_region_size)) {
- drv_log("Failed to set reserved region size: %s.\n", strerror(errno));
- return -errno;
+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_.get(), descriptor->drm_format, descriptor->use_flags,
+ &resolved_format, &resolved_use_flags);
+
+ combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
+ if (!combo && (descriptor->droid_usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
+ descriptor->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ // Unmask BO_USE_HW_VIDEO_ENCODER for other formats. They are mostly
+ // 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_.get(), resolved_format, resolved_use_flags);
+ }
+ if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING)) {
+ resolved_use_flags &= ~BO_USE_FRONT_RENDERING;
+ resolved_use_flags |= BO_USE_LINEAR;
+ combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
}
+ if (!combo)
+ return false;
- return reserved_region_fd;
+ *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;
+ uint64_t resolved_use_flags;
+ uint32_t max_texture_size = drv_get_max_texture_2d_size(drv_.get());
+ if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags))
+ return false;
+
+ // 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;
}
-void cros_gralloc_driver::emplace_buffer(struct bo *bo, struct cros_gralloc_handle *hnd)
+int cros_gralloc_driver::create_reserved_region(const std::string &buffer_name,
+ uint64_t reserved_region_size)
{
- auto buffer = new cros_gralloc_buffer(hnd->id, bo, hnd, hnd->fds[hnd->num_planes],
- hnd->reserved_region_size);
+ int ret;
- std::lock_guard<std::mutex> lock(mutex_);
- buffers_.emplace(hnd->id, buffer);
- handles_.emplace(hnd, std::make_pair(buffer, 1));
+#if ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP)
+ ret = allocator_.Alloc(kDmabufSystemHeapName, reserved_region_size);
+ if (ret >= 0)
+ return ret;
+#endif
+
+ ret = memfd_create_reserved_region(buffer_name, reserved_region_size);
+ if (ret >= 0)
+ return ret;
+
+ drv_log("Failed to create_reserved_region.\n");
+ return -1;
}
int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor,
- buffer_handle_t *out_handle)
+ native_handle_t **out_handle)
{
int ret = 0;
size_t num_planes;
size_t num_fds;
size_t num_ints;
- size_t num_bytes;
uint32_t resolved_format;
uint32_t bytes_per_pixel;
- uint64_t use_flags;
- char *name;
+ uint64_t resolved_use_flags;
struct bo *bo;
struct cros_gralloc_handle *hnd;
+ std::unique_ptr<cros_gralloc_buffer> buffer;
- 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_.get(), descriptor->width, descriptor->height, resolved_format,
+ resolved_use_flags);
if (!bo) {
drv_log("Failed to create bo.\n");
return -errno;
@@ -202,14 +261,8 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
if (descriptor->reserved_region_size > 0)
num_fds += 1;
- num_bytes = sizeof(struct cros_gralloc_handle);
- num_bytes += (descriptor->name.size() + 1);
- /*
- * Ensure that the total number of bytes is a multiple of sizeof(int) as
- * native_handle_clone() copies data based on hnd->base.numInts.
- */
- num_bytes = ALIGN(num_bytes, sizeof(int));
- num_ints = ((num_bytes - sizeof(native_handle_t)) / sizeof(int)) - num_fds;
+ num_ints = ((sizeof(struct cros_gralloc_handle) - sizeof(native_handle_t)) / sizeof(int)) -
+ num_fds;
hnd =
reinterpret_cast<struct cros_gralloc_handle *>(native_handle_create(num_fds, num_ints));
@@ -243,23 +296,35 @@ 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->name_offset = handle_data_size;
+ hnd->total_size = descriptor->reserved_region_size + drv_bo_get_total_size(bo);
+
+ buffer = cros_gralloc_buffer::create(bo, hnd);
+ if (!buffer) {
+ drv_log("Failed to allocate: failed to create cros_gralloc_buffer.\n");
+ ret = -1;
+ goto destroy_hnd;
+ }
- name = (char *)(&hnd->data[hnd->name_offset]);
- snprintf(name, descriptor->name.size() + 1, "%s", descriptor->name.c_str());
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
- emplace_buffer(bo, hnd);
+ struct cros_gralloc_imported_handle_info hnd_info = {
+ .buffer = buffer.get(),
+ .refcount = 1,
+ };
+ handles_.emplace(hnd, hnd_info);
+ buffers_.emplace(hnd->id, std::move(buffer));
+ }
- *out_handle = reinterpret_cast<buffer_handle_t>(hnd);
+ *out_handle = hnd;
return 0;
destroy_hnd:
@@ -273,7 +338,6 @@ destroy_bo:
int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
{
- uint32_t id;
std::lock_guard<std::mutex> lock(mutex_);
auto hnd = cros_gralloc_convert_handle(handle);
@@ -282,43 +346,65 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
return -EINVAL;
}
- auto buffer = get_buffer(hnd);
- if (buffer) {
- handles_[hnd].second++;
- buffer->increase_refcount();
+ auto hnd_it = handles_.find(hnd);
+ if (hnd_it != handles_.end()) {
+ // The underlying buffer (as multiple handles can refer to the same buffer)
+ // has already been imported into this process and the given handle has
+ // already been registered in this process. Increase both the buffer and
+ // handle reference count.
+ auto &hnd_info = hnd_it->second;
+
+ hnd_info.buffer->increase_refcount();
+ hnd_info.refcount++;
+
return 0;
}
- id = hnd->id;
+ uint32_t id = hnd->id;
+
+ cros_gralloc_buffer *buffer = nullptr;
- if (buffers_.count(id)) {
- buffer = buffers_[id];
+ auto buffer_it = buffers_.find(id);
+ if (buffer_it != buffers_.end()) {
+ // The underlying buffer (as multiple handles can refer to the same buffer)
+ // has already been imported into this process but the given handle has not
+ // yet been registered. Increase the buffer reference count (here) and start
+ // to track the handle (below).
+ buffer = buffer_it->second.get();
buffer->increase_refcount();
} else {
- struct bo *bo;
- struct drv_import_fd_data data;
- data.format = hnd->format;
- data.tiling = hnd->tiling;
-
- data.width = hnd->width;
- data.height = hnd->height;
- data.use_flags = hnd->use_flags;
-
+ // The underlying buffer has not yet been imported into this process. Import
+ // and start to track the buffer (here) and start to track the handle (below).
+ struct drv_import_fd_data data = {
+ .format_modifier = hnd->format_modifier,
+ .width = hnd->width,
+ .height = hnd->height,
+ .format = hnd->format,
+ .tiling = hnd->tiling,
+ .use_flags = hnd->use_flags,
+ };
memcpy(data.fds, hnd->fds, sizeof(data.fds));
memcpy(data.strides, hnd->strides, sizeof(data.strides));
memcpy(data.offsets, hnd->offsets, sizeof(data.offsets));
- data.format_modifier = hnd->format_modifier;
- bo = drv_bo_import(drv_, &data);
+ struct bo *bo = drv_bo_import(drv_.get(), &data);
if (!bo)
return -EFAULT;
- buffer = new cros_gralloc_buffer(id, bo, nullptr, hnd->fds[hnd->num_planes],
- hnd->reserved_region_size);
- buffers_.emplace(id, buffer);
+ auto scoped_buffer = cros_gralloc_buffer::create(bo, hnd);
+ if (!scoped_buffer) {
+ drv_log("Failed to import: failed to create cros_gralloc_buffer.\n");
+ return -1;
+ }
+ buffer = scoped_buffer.get();
+ buffers_.emplace(id, std::move(scoped_buffer));
}
- handles_.emplace(hnd, std::make_pair(buffer, 1));
+ struct cros_gralloc_imported_handle_info hnd_info = {
+ .buffer = buffer,
+ .refcount = 1,
+ };
+ handles_.emplace(hnd, hnd_info);
return 0;
}
@@ -334,16 +420,15 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle)
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (release() called on unregistered handle).\n");
return -EINVAL;
}
- if (!--handles_[hnd].second)
+ if (!--handles_[hnd].refcount)
handles_.erase(hnd);
if (buffer->decrease_refcount() == 0) {
buffers_.erase(buffer->get_id());
- delete buffer;
}
return 0;
@@ -358,6 +443,7 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
return ret;
std::lock_guard<std::mutex> lock(mutex_);
+
auto hnd = cros_gralloc_convert_handle(handle);
if (!hnd) {
drv_log("Invalid handle.\n");
@@ -366,7 +452,7 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (lock() called on unregistered handle).\n");
return -EINVAL;
}
@@ -385,7 +471,7 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fen
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (unlock() called on unregistered handle).\n");
return -EINVAL;
}
@@ -411,7 +497,7 @@ int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle)
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (invalidate() called on unregistered handle).\n");
return -EINVAL;
}
@@ -430,7 +516,7 @@ int32_t cros_gralloc_driver::flush(buffer_handle_t handle, int32_t *release_fenc
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (flush() called on unregistered handle).\n");
return -EINVAL;
}
@@ -456,7 +542,7 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (get_backing_store() called on unregistered handle).\n");
return -EINVAL;
}
@@ -478,7 +564,7 @@ int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t stri
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log("Invalid reference (resource_info() called on unregistered handle).\n");
return -EINVAL;
}
@@ -499,32 +585,53 @@ int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle,
auto buffer = get_buffer(hnd);
if (!buffer) {
- drv_log("Invalid Reference.\n");
+ drv_log(
+ "Invalid reference (get_reserved_region() called on unregistered handle).\n");
return -EINVAL;
}
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_.get(), 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)
{
/* Assumes driver mutex is held. */
if (handles_.count(hnd))
- return handles_[hnd].first;
+ return handles_[hnd].buffer;
return nullptr;
}
-void cros_gralloc_driver::for_each_handle(
- const std::function<void(cros_gralloc_handle_t)> &function)
+void cros_gralloc_driver::with_buffer(cros_gralloc_handle_t hnd,
+ const std::function<void(cros_gralloc_buffer *)> &function)
+{
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ auto buffer = get_buffer(hnd);
+ if (!buffer) {
+ drv_log("Invalid reference (with_buffer() called on unregistered handle).\n");
+ return;
+ }
+
+ function(buffer);
+}
+
+void cros_gralloc_driver::with_each_buffer(
+ const std::function<void(cros_gralloc_buffer *)> &function)
{
std::lock_guard<std::mutex> lock(mutex_);
- for (const auto &pair : handles_)
- function(pair.first);
+ for (const auto &pair : buffers_)
+ function(pair.second.get());
}
diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h
index ef9e21f..5678b76 100644
--- a/cros_gralloc/cros_gralloc_driver.h
+++ b/cros_gralloc/cros_gralloc_driver.h
@@ -10,19 +10,22 @@
#include "cros_gralloc_buffer.h"
#include <functional>
+#include <memory>
#include <mutex>
+#include <string>
#include <unordered_map>
+#if ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP)
+#include <BufferAllocator/BufferAllocator.h>
+#endif
+
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);
+ native_handle_t **out_handle);
int32_t retain(buffer_handle_t handle);
int32_t release(buffer_handle_t handle);
@@ -42,21 +45,44 @@ 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);
+ void with_buffer(cros_gralloc_handle_t hnd,
+ const std::function<void(cros_gralloc_buffer *)> &function);
+ void with_each_buffer(const std::function<void(cros_gralloc_buffer *)> &function);
private:
- cros_gralloc_driver(cros_gralloc_driver 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);
+
+ int create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size);
+
+#if ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP)
+ /* For allocating cros_gralloc_buffer reserved regions for metadata. */
+ BufferAllocator allocator_;
+#endif
+
+ std::unique_ptr<struct driver, void (*)(struct driver *)> drv_;
+
+ struct cros_gralloc_imported_handle_info {
+ /*
+ * The underlying buffer for referred to by this handle (as multiple handles can
+ * refer to the same buffer).
+ */
+ cros_gralloc_buffer *buffer = nullptr;
+
+ /* The handle's refcount as a handle can be imported multiple times.*/
+ int32_t refcount = 1;
+ };
- struct driver *drv_;
std::mutex mutex_;
- std::unordered_map<uint32_t, cros_gralloc_buffer *> buffers_;
- std::unordered_map<cros_gralloc_handle_t, std::pair<cros_gralloc_buffer *, int32_t>>
- handles_;
+ std::unordered_map<uint32_t, std::unique_ptr<cros_gralloc_buffer>> buffers_;
+ std::unordered_map<cros_gralloc_handle_t, cros_gralloc_imported_handle_info> handles_;
};
#endif
diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h
index 2b70d4b..2d0e1ac 100644
--- a/cros_gralloc/cros_gralloc_handle.h
+++ b/cros_gralloc/cros_gralloc_handle.h
@@ -40,10 +40,6 @@ struct cros_gralloc_handle : public native_handle_t {
uint32_t num_planes;
uint64_t reserved_region_size;
uint64_t total_size; /* Total allocation size */
- /*
- * Name is a null terminated char array located at handle->base.data[handle->name_offset].
- */
- uint32_t name_offset;
} __attribute__((packed));
typedef const struct cros_gralloc_handle *cros_gralloc_handle_t;
diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc
index 4319936..90cd5c4 100644
--- a/cros_gralloc/cros_gralloc_helpers.cc
+++ b/cros_gralloc/cros_gralloc_helpers.cc
@@ -6,8 +6,18 @@
#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::SENSOR_DIRECT_DATA. */
+#define BUFFER_USAGE_SENSOR_DIRECT_DATA (1 << 23)
+
+/* 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 +26,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 +54,99 @@ 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_SENSOR_DIRECT_DATA, &use_flags,
+ BO_USE_SENSOR_DIRECT_DATA);
+ 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..ce62521 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -4,18 +4,18 @@
* found in the LICENSE file.
*/
-#include "../../helpers.h"
#include "../../util.h"
#include "../cros_gralloc_driver.h"
#include <cassert>
+#include <cutils/native_handle.h>
#include <hardware/gralloc.h>
#include <memory.h>
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,93 +61,17 @@ 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);
}
static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage,
- buffer_handle_t *handle, int *stride)
+ buffer_handle_t *out_handle, int *out_stride)
{
int32_t ret;
- bool supported;
+ native_handle_t *handle;
struct cros_gralloc_buffer_descriptor descriptor;
auto mod = (struct gralloc0_module const *)dev->common.module;
@@ -156,31 +80,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),
@@ -188,20 +91,31 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa
return -EINVAL;
}
- ret = mod->driver->allocate(&descriptor, handle);
+ ret = mod->driver->allocate(&descriptor, &handle);
if (ret)
return ret;
- auto hnd = cros_gralloc_convert_handle(*handle);
- *stride = hnd->pixel_stride;
+ auto hnd = cros_gralloc_convert_handle(handle);
+ *out_handle = handle;
+ *out_stride = hnd->pixel_stride;
return 0;
}
static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle)
{
+ int32_t ret;
auto mod = (struct gralloc0_module const *)dev->common.module;
- return mod->driver->release(handle);
+
+ ret = mod->driver->release(handle);
+ if (ret)
+ return ret;
+
+ auto hnd = const_cast<native_handle_t *>(handle);
+ native_handle_close(hnd);
+ native_handle_delete(hnd);
+
+ return 0;
}
static int gralloc0_close(struct hw_device_t *dev)
@@ -217,11 +131,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 +293,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 +365,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 +417,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..fb6aca9 100644
--- a/cros_gralloc/gralloc4/Android.bp
+++ b/cros_gralloc/gralloc4/Android.bp
@@ -23,108 +23,140 @@ package {
default_applicable_licenses: ["external_minigbm_license"],
}
-cc_defaults {
- name: "service_minigbm_defaults",
- relative_install_path: "hw",
- vendor: true,
+filegroup {
+ name: "minigbm_gralloc4_allocator_files",
+ srcs: [
+ "CrosGralloc4Allocator.cc",
+ "CrosGralloc4AllocatorService.cc",
+ "CrosGralloc4Utils.cc",
+ ],
+}
- vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"],
+filegroup {
+ name: "minigbm_gralloc4_mapper_files",
+ srcs: [
+ "CrosGralloc4Mapper.cc",
+ "CrosGralloc4Utils.cc",
+ ],
+}
- cflags: [
- "-Wall",
- "-Werror",
+cc_library {
+ name: "libminigbm_gralloc4_utils",
+ defaults: ["minigbm_cros_gralloc_defaults"],
+ vendor: true,
+ srcs: [
+ "CrosGralloc4Utils.cc",
+ ],
+ shared_libs: [
+ "android.hardware.graphics.mapper@4.0",
+ "libgralloctypes",
+ "libhidlbase",
+ "libminigbm_gralloc",
],
+}
+
+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..43c0b0c 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
@@ -10,8 +10,11 @@
#include <gralloctypes/Gralloc4.h>
#include "cros_gralloc/cros_gralloc_helpers.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Dataspace;
using android::hardware::hidl_handle;
using android::hardware::hidl_vec;
using android::hardware::Return;
@@ -23,11 +26,40 @@ 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::initializeMetadata(
+ cros_gralloc_handle_t crosHandle,
+ const struct cros_gralloc_buffer_descriptor& crosDescriptor) {
+ if (!mDriver) {
+ drv_log("Failed to initializeMetadata. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ if (!crosHandle) {
+ drv_log("Failed to initializeMetadata. Invalid handle.\n");
+ return Error::BAD_BUFFER;
}
+
+ void* addr;
+ uint64_t size;
+ int ret = mDriver->get_reserved_region(crosHandle, &addr, &size);
+ if (ret) {
+ drv_log("Failed to getReservedRegion.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ CrosGralloc4Metadata* crosMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
+
+ snprintf(crosMetadata->name, CROS_GRALLOC4_METADATA_MAX_NAME_SIZE, "%s",
+ crosDescriptor.name.c_str());
+ crosMetadata->dataspace = Dataspace::UNKNOWN;
+ crosMetadata->blendMode = BlendMode::INVALID;
+
+ return Error::NONE;
}
Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
@@ -46,13 +78,9 @@ 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);
- }
+ crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata);
- 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);
@@ -61,18 +89,23 @@ Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, ui
return Error::UNSUPPORTED;
}
- buffer_handle_t handle;
+ native_handle_t* handle;
int ret = mDriver->allocate(&crosDescriptor, &handle);
if (ret) {
return Error::NO_RESOURCES;
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle);
- if (!crosHandle) {
- return Error::NO_RESOURCES;
+
+ Error error = initializeMetadata(crosHandle, crosDescriptor);
+ if (error != Error::NONE) {
+ mDriver->release(handle);
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ return error;
}
- *outHandle = handle;
+ outHandle->setTo(handle, /*shouldOwn=*/true);
*outStride = crosHandle->pixel_stride;
return Error::NONE;
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h
index 21ad7ad..9c1c783 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h
+++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h
@@ -8,19 +8,27 @@
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
#include "cros_gralloc/cros_gralloc_driver.h"
+#include "cros_gralloc/cros_gralloc_helpers.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_0::IAllocator {
public:
- 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 initializeMetadata(
+ cros_gralloc_handle_t crosHandle,
+ const struct cros_gralloc_buffer_descriptor& crosDescriptor);
+
android::hardware::graphics::mapper::V4_0::Error allocate(
const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo&
description,
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..cc2c4d5 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();
}
@@ -482,11 +418,13 @@ Return<void> CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metada
return Void();
}
- get(crosHandle, metadataType, hidlCb);
+ mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
+ get(crosBuffer, metadataType, hidlCb);
+ });
return Void();
}
-Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle,
+Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer,
const MetadataType& metadataType, get_cb hidlCb) {
hidl_vec<uint8_t> encodedMetadata;
@@ -496,40 +434,54 @@ Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle,
return Void();
}
- if (!crosHandle) {
- drv_log("Failed to get. Invalid handle.\n");
+ if (!crosBuffer) {
+ drv_log("Failed to get. Invalid buffer.\n");
hidlCb(Error::BAD_BUFFER, encodedMetadata);
return Void();
}
+ const CrosGralloc4Metadata* crosMetadata = nullptr;
+ if (metadataType == android::gralloc4::MetadataType_BlendMode ||
+ metadataType == android::gralloc4::MetadataType_Cta861_3 ||
+ metadataType == android::gralloc4::MetadataType_Dataspace ||
+ metadataType == android::gralloc4::MetadataType_Name ||
+ metadataType == android::gralloc4::MetadataType_Smpte2086) {
+ Error error = getMetadata(crosBuffer, &crosMetadata);
+ if (error != Error::NONE) {
+ drv_log("Failed to get. Failed to get buffer metadata.\n");
+ hidlCb(Error::NO_RESOURCES, encodedMetadata);
+ return Void();
+ }
+ }
+
android::status_t status = android::NO_ERROR;
if (metadataType == android::gralloc4::MetadataType_BufferId) {
- status = android::gralloc4::encodeBufferId(crosHandle->id, &encodedMetadata);
+ status = android::gralloc4::encodeBufferId(crosBuffer->get_id(), &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Name) {
- const char* name = (const char*)(&crosHandle->data[crosHandle->name_offset]);
- status = android::gralloc4::encodeName(name, &encodedMetadata);
+ status = android::gralloc4::encodeName(crosMetadata->name, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Width) {
- status = android::gralloc4::encodeWidth(crosHandle->width, &encodedMetadata);
+ status = android::gralloc4::encodeWidth(crosBuffer->get_width(), &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Height) {
- status = android::gralloc4::encodeHeight(crosHandle->height, &encodedMetadata);
+ status = android::gralloc4::encodeHeight(crosBuffer->get_height(), &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
status = android::gralloc4::encodeLayerCount(1, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
- PixelFormat pixelFormat = static_cast<PixelFormat>(crosHandle->droid_format);
+ PixelFormat pixelFormat = static_cast<PixelFormat>(crosBuffer->get_android_format());
status = android::gralloc4::encodePixelFormatRequested(pixelFormat, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
status = android::gralloc4::encodePixelFormatFourCC(
- drv_get_standard_fourcc(crosHandle->format), &encodedMetadata);
+ drv_get_standard_fourcc(crosBuffer->get_format()), &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_PixelFormatModifier) {
- status = android::gralloc4::encodePixelFormatModifier(crosHandle->format_modifier,
+ status = android::gralloc4::encodePixelFormatModifier(crosBuffer->get_format_modifier(),
&encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Usage) {
- uint64_t usage = static_cast<uint64_t>(crosHandle->usage);
- status = android::gralloc4::encodeUsage(usage, &encodedMetadata);
+ status = android::gralloc4::encodeUsage(crosBuffer->get_android_usage(), &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_AllocationSize) {
- status = android::gralloc4::encodeAllocationSize(crosHandle->total_size, &encodedMetadata);
+ status = android::gralloc4::encodeAllocationSize(crosBuffer->get_total_size(),
+ &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
- uint64_t hasProtectedContent = crosHandle->usage & BufferUsage::PROTECTED ? 1 : 0;
+ uint64_t hasProtectedContent =
+ crosBuffer->get_android_usage() & BufferUsage::PROTECTED ? 1 : 0;
status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Compression) {
status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None,
@@ -542,38 +494,43 @@ Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle,
&encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_PlaneLayouts) {
std::vector<PlaneLayout> planeLayouts;
- getPlaneLayouts(crosHandle->format, &planeLayouts);
+ getPlaneLayouts(crosBuffer->get_format(), &planeLayouts);
for (size_t plane = 0; plane < planeLayouts.size(); plane++) {
PlaneLayout& planeLayout = planeLayouts[plane];
- planeLayout.offsetInBytes = crosHandle->offsets[plane];
- planeLayout.strideInBytes = crosHandle->strides[plane];
- planeLayout.totalSizeInBytes = crosHandle->sizes[plane];
- planeLayout.widthInSamples = crosHandle->width / planeLayout.horizontalSubsampling;
- planeLayout.heightInSamples = crosHandle->height / planeLayout.verticalSubsampling;
+ planeLayout.offsetInBytes = crosBuffer->get_plane_offset(plane);
+ planeLayout.strideInBytes = crosBuffer->get_plane_stride(plane);
+ planeLayout.totalSizeInBytes = crosBuffer->get_plane_size(plane);
+ planeLayout.widthInSamples =
+ crosBuffer->get_width() / planeLayout.horizontalSubsampling;
+ planeLayout.heightInSamples =
+ crosBuffer->get_height() / planeLayout.verticalSubsampling;
}
status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Crop) {
+ const uint32_t numPlanes = crosBuffer->get_num_planes();
+ const uint32_t w = crosBuffer->get_width();
+ const uint32_t h = crosBuffer->get_height();
std::vector<aidl::android::hardware::graphics::common::Rect> crops;
- for (size_t plane = 0; plane < crosHandle->num_planes; plane++) {
+ for (uint32_t plane = 0; plane < numPlanes; plane++) {
aidl::android::hardware::graphics::common::Rect crop;
crop.left = 0;
crop.top = 0;
- crop.right = crosHandle->width;
- crop.bottom = crosHandle->height;
+ crop.right = w;
+ crop.bottom = h;
crops.push_back(crop);
}
status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
- status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata);
+ status = android::gralloc4::encodeDataspace(crosMetadata->dataspace, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
- status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata);
+ status = android::gralloc4::encodeBlendMode(crosMetadata->blendMode, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
- status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata);
+ status = android::gralloc4::encodeSmpte2086(crosMetadata->smpte2086, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
- status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata);
+ status = android::gralloc4::encodeCta861_3(crosMetadata->cta861_3, &encodedMetadata);
} else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
} else {
@@ -592,7 +549,7 @@ Return<void> CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle,
}
Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType,
- const hidl_vec<uint8_t>& /*metadata*/) {
+ const hidl_vec<uint8_t>& encodedMetadata) {
if (!mDriver) {
drv_log("Failed to set. Driver is uninitialized.\n");
return Error::NO_RESOURCES;
@@ -626,7 +583,68 @@ Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metad
return Error::BAD_VALUE;
}
- return Error::UNSUPPORTED;
+ if (metadataType != android::gralloc4::MetadataType_BlendMode &&
+ metadataType != android::gralloc4::MetadataType_Cta861_3 &&
+ metadataType != android::gralloc4::MetadataType_Dataspace &&
+ metadataType != android::gralloc4::MetadataType_Smpte2086) {
+ return Error::UNSUPPORTED;
+ }
+
+ Error error = Error::NONE;
+ mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
+ error = set(crosBuffer, metadataType, encodedMetadata);
+ });
+
+ return error;
+}
+
+Error CrosGralloc4Mapper::set(cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& encodedMetadata) {
+ if (!mDriver) {
+ drv_log("Failed to set. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ if (!crosBuffer) {
+ drv_log("Failed to set. Invalid buffer.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ CrosGralloc4Metadata* crosMetadata = nullptr;
+
+ Error error = getMutableMetadata(crosBuffer, &crosMetadata);
+ if (error != Error::NONE) {
+ drv_log("Failed to set. Failed to get buffer metadata.\n");
+ return Error::UNSUPPORTED;
+ }
+
+ if (metadataType == android::gralloc4::MetadataType_BlendMode) {
+ auto status = android::gralloc4::decodeBlendMode(encodedMetadata, &crosMetadata->blendMode);
+ if (status != android::NO_ERROR) {
+ drv_log("Failed to set. Failed to decode blend mode.\n");
+ return Error::UNSUPPORTED;
+ }
+ } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
+ auto status = android::gralloc4::decodeCta861_3(encodedMetadata, &crosMetadata->cta861_3);
+ if (status != android::NO_ERROR) {
+ drv_log("Failed to set. Failed to decode cta861_3.\n");
+ return Error::UNSUPPORTED;
+ }
+ } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
+ auto status = android::gralloc4::decodeDataspace(encodedMetadata, &crosMetadata->dataspace);
+ if (status != android::NO_ERROR) {
+ drv_log("Failed to set. Failed to decode dataspace.\n");
+ return Error::UNSUPPORTED;
+ }
+ } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
+ auto status = android::gralloc4::decodeSmpte2086(encodedMetadata, &crosMetadata->smpte2086);
+ if (status != android::NO_ERROR) {
+ drv_log("Failed to set. Failed to decode smpte2086.\n");
+ return Error::UNSUPPORTED;
+ }
+ }
+
+ return Error::NONE;
}
int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage,
@@ -851,25 +869,25 @@ Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadat
android::gralloc4::MetadataType_Dataspace,
"",
/*isGettable=*/true,
- /*isSettable=*/false,
+ /*isSettable=*/true,
},
{
android::gralloc4::MetadataType_BlendMode,
"",
/*isGettable=*/true,
- /*isSettable=*/false,
+ /*isSettable=*/true,
},
{
android::gralloc4::MetadataType_Smpte2086,
"",
/*isGettable=*/true,
- /*isSettable=*/false,
+ /*isSettable=*/true,
},
{
android::gralloc4::MetadataType_Cta861_3,
"",
/*isGettable=*/true,
- /*isSettable=*/false,
+ /*isSettable=*/true,
},
{
android::gralloc4::MetadataType_Smpte2094_40,
@@ -906,10 +924,13 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlC
return Void();
}
- return dumpBuffer(crosHandle, hidlCb);
+ mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
+ dumpBuffer(crosBuffer, hidlCb);
+ });
+ return Void();
}
-Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle,
+Return<void> CrosGralloc4Mapper::dumpBuffer(const cros_gralloc_buffer* crosBuffer,
dumpBuffer_cb hidlCb) {
BufferDump bufferDump;
@@ -919,12 +940,6 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle,
return Void();
}
- if (!crosHandle) {
- drv_log("Failed to dumpBuffer. Invalid handle.\n");
- hidlCb(Error::BAD_BUFFER, bufferDump);
- return Void();
- }
-
std::vector<MetadataDump> metadataDumps;
MetadataType metadataType = android::gralloc4::MetadataType_BufferId;
@@ -936,55 +951,55 @@ Return<void> CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle,
};
metadataType = android::gralloc4::MetadataType_BufferId;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Name;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Width;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Height;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_LayerCount;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_PixelFormatRequested;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_PixelFormatFourCC;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_PixelFormatModifier;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Usage;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_AllocationSize;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_ProtectedContent;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Compression;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Interlaced;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_ChromaSiting;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_PlaneLayouts;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_Dataspace;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
metadataType = android::gralloc4::MetadataType_BlendMode;
- get(crosHandle, metadataType, metadata_get_callback);
+ get(crosBuffer, metadataType, metadata_get_callback);
bufferDump.metadataDump = metadataDumps;
hidlCb(Error::NONE, bufferDump);
@@ -1002,22 +1017,89 @@ Return<void> CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) {
Error error = Error::NONE;
- auto handleCallback = [&](cros_gralloc_handle_t crosHandle) {
- auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) {
- error = err;
- if (error == Error::NONE) {
- bufferDumps.push_back(bufferDump);
- }
- };
-
- dumpBuffer(crosHandle, dumpBufferCallback);
+ const auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) {
+ error = err;
+ if (error == Error::NONE) {
+ bufferDumps.push_back(bufferDump);
+ }
};
- mDriver->for_each_handle(handleCallback);
+
+ mDriver->with_each_buffer(
+ [&](cros_gralloc_buffer* crosBuffer) { dumpBuffer(crosBuffer, dumpBufferCallback); });
hidlCb(error, bufferDumps);
return Void();
}
+Error CrosGralloc4Mapper::getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
+ ReservedRegionArea area, void** outAddr,
+ uint64_t* outSize) {
+ if (!mDriver) {
+ drv_log("Failed to getReservedRegionArea. Driver is uninitialized.\n");
+ return Error::NO_RESOURCES;
+ }
+
+ if (!crosBuffer) {
+ drv_log("Failed to getReservedRegionArea. Invalid buffer.\n");
+ return Error::BAD_BUFFER;
+ }
+
+ int ret = crosBuffer->get_reserved_region(outAddr, outSize);
+ if (ret) {
+ drv_log("Failed to getReservedRegionArea.\n");
+ *outAddr = nullptr;
+ *outSize = 0;
+ return Error::NO_RESOURCES;
+ }
+
+ switch (area) {
+ case ReservedRegionArea::MAPPER4_METADATA: {
+ // CrosGralloc4Metadata resides at the beginning reserved region.
+ *outSize = sizeof(CrosGralloc4Metadata);
+ break;
+ }
+ case ReservedRegionArea::USER_METADATA: {
+ // User metadata resides after the CrosGralloc4Metadata.
+ *outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(*outAddr) +
+ sizeof(CrosGralloc4Metadata));
+ *outSize = *outSize - sizeof(CrosGralloc4Metadata);
+ break;
+ }
+ }
+
+ return Error::NONE;
+}
+
+Error CrosGralloc4Mapper::getMetadata(const cros_gralloc_buffer* crosBuffer,
+ const CrosGralloc4Metadata** outMetadata) {
+ void* addr = nullptr;
+ uint64_t size;
+
+ Error error =
+ getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ *outMetadata = reinterpret_cast<const CrosGralloc4Metadata*>(addr);
+ return Error::NONE;
+}
+
+Error CrosGralloc4Mapper::getMutableMetadata(cros_gralloc_buffer* crosBuffer,
+ CrosGralloc4Metadata** outMetadata) {
+ void* addr = nullptr;
+ uint64_t size;
+
+ Error error =
+ getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ *outMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
+ return Error::NONE;
+}
+
Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) {
if (!mDriver) {
drv_log("Failed to getReservedRegion. Driver is uninitialized.\n");
@@ -1041,9 +1123,15 @@ Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedR
void* reservedRegionAddr = nullptr;
uint64_t reservedRegionSize = 0;
- int ret = mDriver->get_reserved_region(bufferHandle, &reservedRegionAddr, &reservedRegionSize);
- if (ret) {
- drv_log("Failed to getReservedRegion.\n");
+
+ Error error = Error::NONE;
+ mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
+ error = getReservedRegionArea(crosBuffer, ReservedRegionArea::USER_METADATA,
+ &reservedRegionAddr, &reservedRegionSize);
+ });
+
+ if (error != Error::NONE) {
+ drv_log("Failed to getReservedRegion. Failed to getReservedRegionArea.\n");
hidlCb(Error::BAD_BUFFER, nullptr, 0);
return Void();
}
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h
index 3c159a2..1734feb 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h
+++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h
@@ -8,11 +8,11 @@
#include "cros_gralloc/cros_gralloc_driver.h"
#include "cros_gralloc/cros_gralloc_handle.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMapper {
public:
- CrosGralloc4Mapper();
- ~CrosGralloc4Mapper();
+ CrosGralloc4Mapper() = default;
android::hardware::Return<void> createDescriptor(const BufferDescriptorInfo& description,
createDescriptor_cb hidlCb) override;
@@ -66,16 +66,38 @@ class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMa
getReservedRegion_cb hidlCb) override;
private:
- android::hardware::Return<void> get(cros_gralloc_handle_t crosHandle,
+ enum class ReservedRegionArea {
+ /* CrosGralloc4Metadata */
+ MAPPER4_METADATA,
+
+ /* External user metadata */
+ USER_METADATA,
+ };
+
+ android::hardware::graphics::mapper::V4_0::Error getReservedRegionArea(
+ const cros_gralloc_buffer* crosBuffer, ReservedRegionArea area, void** outAddr,
+ uint64_t* outSize);
+
+ android::hardware::graphics::mapper::V4_0::Error getMetadata(
+ const cros_gralloc_buffer* crosBuffer, const CrosGralloc4Metadata** outMetadata);
+
+ android::hardware::graphics::mapper::V4_0::Error getMutableMetadata(
+ cros_gralloc_buffer* crosBuffer, CrosGralloc4Metadata** outMetadata);
+
+ android::hardware::Return<void> get(const cros_gralloc_buffer* crosBuffer,
const MetadataType& metadataType, get_cb hidlCb);
- android::hardware::Return<void> dumpBuffer(cros_gralloc_handle_t crosHandle,
+ android::hardware::graphics::mapper::V4_0::Error set(
+ cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& metadata);
+
+ android::hardware::Return<void> dumpBuffer(const cros_gralloc_buffer* crosBuffer,
dumpBuffer_cb hidlCb);
int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat,
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/CrosGralloc4Metadata.h b/cros_gralloc/gralloc4/CrosGralloc4Metadata.h
new file mode 100644
index 0000000..c908e35
--- /dev/null
+++ b/cros_gralloc/gralloc4/CrosGralloc4Metadata.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef CROSGRALLOC4METADATA_H
+#define CROSGRALLOC4METADATA_H
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/Cta861_3.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/common/Smpte2086.h>
+
+#define CROS_GRALLOC4_METADATA_MAX_NAME_SIZE 1024
+
+/*
+ * The metadata for cros_gralloc_buffer-s that should reside in a shared memory region
+ * instead of directly in cros_gralloc_handle-s.
+ *
+ * Any metadata that is mutable must be stored in this shared memory region as
+ * cros_gralloc_handle-s can not be tracked and updated across processes.
+ */
+struct CrosGralloc4Metadata {
+ /*
+ * Name is stored in the shared memory metadata to simplify cros_gralloc_handle
+ * creation. This allows us to keep handles small while avoiding variable sized
+ * handles.
+ */
+ char name[CROS_GRALLOC4_METADATA_MAX_NAME_SIZE];
+ aidl::android::hardware::graphics::common::BlendMode blendMode;
+ aidl::android::hardware::graphics::common::Dataspace dataspace;
+ std::optional<aidl::android::hardware::graphics::common::Cta861_3> cta861_3;
+ std::optional<aidl::android::hardware::graphics::common::Smpte2086> smpte2086;
+};
+
+#endif
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
index 9bc27cb..6c07189 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");
- }
+ static_assert(std::is_same<std::underlying_type<BufferUsage>::type, uint64_t>::value);
- if (usage) {
- usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage));
- }
-
- 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,
@@ -579,13 +315,13 @@ const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap
{DRM_FORMAT_XBGR8888,
{{
- .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
+ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
.offsetInBits = 0,
.sizeInBits = 8},
{.type = android::gralloc4::PlaneLayoutComponentType_G,
.offsetInBits = 8,
.sizeInBits = 8},
- {.type = android::gralloc4::PlaneLayoutComponentType_R,
+ {.type = android::gralloc4::PlaneLayoutComponentType_B,
.offsetInBits = 16,
.sizeInBits = 8}},
.sampleIncrementInBits = 32,
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
diff --git a/dri.c b/dri.c
index 13d4833..7257c31 100644
--- a/dri.c
+++ b/dri.c
@@ -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;
}
@@ -441,19 +452,29 @@ 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)
{
struct dri_driver *dri = drv->priv;
- if (!dri->image_extension->queryDmaBufFormatModifierAttribs) {
- /* We do not do any modifier checks here. The create will fail
- * later if the modifier is not supported. */
- return drv_num_planes_from_format(format);
- }
+ uint64_t planes = 0;
+
+ /* We do not do any modifier checks here. The create will fail later if the modifier is not
+ * supported.
+ */
+ if (dri->image_extension->queryDmaBufFormatModifierAttribs &&
+ dri->image_extension->queryDmaBufFormatModifierAttribs(
+ dri->device, format, modifier, __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT,
+ &planes))
+ return planes;
- uint64_t planes;
- GLboolean ret = dri->image_extension->queryDmaBufFormatModifierAttribs(
- dri->device, format, modifier, __DRI_IMAGE_ATTRIB_NUM_PLANES, &planes);
- if (!ret)
- return 0;
+ return drv_num_planes_from_format(format);
+}
+
+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 planes;
+ return dri->image_extension->queryDmaBufModifiers(dri->device, format, max, modifiers, NULL,
+ count);
}
#endif
diff --git a/dri.h b/dri.h
index 6218e82..daadf30 100644
--- a/dri.h
+++ b/dri.h
@@ -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
diff --git a/drv.c b/drv.c
index 9b43e9f..ada02ba 100644
--- a/drv.c
+++ b/drv.c
@@ -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;
+}
diff --git a/drv.h b/drv.h
index 4689558..6883f2d 100644
--- a/drv.h
+++ b/drv.h
@@ -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,8 @@ 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)
+#define BO_USE_SENSOR_DIRECT_DATA (1ull << 19)
/* Quirks for allocating a buffer. */
#define BO_QUIRK_NONE 0
@@ -69,6 +72,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 +179,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 +205,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
diff --git a/drv_priv.h b/drv_priv.h
index c720077..6703f4b 100644
--- a/drv_priv.h
+++ b/drv_priv.h
@@ -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
@@ -109,7 +116,7 @@ struct backend {
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_FRONT_RENDERING)
#define BO_USE_NON_GPU_HW (BO_USE_SCANOUT | BO_USE_CAMERA_WRITE | BO_USE_CAMERA_READ | \
- BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER)
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER | BO_USE_SENSOR_DIRECT_DATA)
#ifndef DRM_FORMAT_MOD_LINEAR
#define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE
diff --git a/dumb_driver.c b/dumb_driver.c
index f5a62aa..c667a51 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,17 +15,19 @@
.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,
+static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_NV21,
DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID };
static int dumb_driver_init(struct driver *drv)
@@ -34,6 +38,9 @@ static int dumb_driver_init(struct driver *drv)
drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats),
&LINEAR_METADATA, BO_USE_TEXTURE_MASK);
+ drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
+ BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER |
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER |
BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
@@ -42,6 +49,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/virgl_hw.h b/external/virgl_hw.h
index 7f4a63f..4527ced 100644
--- a/external/virgl_hw.h
+++ b/external/virgl_hw.h
@@ -222,6 +222,12 @@ enum virgl_formats {
VIRGL_FORMAT_A4B4G4R4_UNORM = 311,
VIRGL_FORMAT_R8_SRGB = 312,
+ VIRGL_FORMAT_R8G8_SRGB = 313,
+
+ VIRGL_FORMAT_P010 = 314,
+ VIRGL_FORMAT_P012 = 315,
+ VIRGL_FORMAT_P016 = 316,
+
VIRGL_FORMAT_MAX /* = PIPE_FORMAT_COUNT */,
/* Below formats must not be used in the guest. */
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
diff --git a/gbm.c b/gbm.c
index ecbfb88..190347e 100644
--- a/gbm.c
+++ b/gbm.c
@@ -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;
diff --git a/i915.c b/i915.c
index 9de38b2..35c45eb 100644
--- a/i915.c
+++ b/i915.c
@@ -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,6 +37,10 @@ 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 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 };
+
static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR };
@@ -58,13 +62,51 @@ 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,
+ 0x46D0, 0x46D1, 0x46D2 };
unsigned i;
i915->gen = 4;
i915->is_adlp = false;
@@ -73,6 +115,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,7 +164,11 @@ 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) {
+ if (i915->gen == 12) {
+ i915->modifier.order = gen12_modifier_order;
+ i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
+ }
+ else if (i915->gen == 11) {
i915->modifier.order = gen11_modifier_order;
i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
} else {
@@ -249,10 +325,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 +388,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:
@@ -368,6 +441,19 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u
return 0;
}
+static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format,
+ uint64_t modifier)
+{
+ size_t num_planes = drv_num_planes_from_format(format);
+ if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
+ assert(num_planes == 1);
+ return 2;
+ }
+
+ return num_planes;
+}
+
static int i915_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)
{
@@ -418,6 +504,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 +518,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;
}
@@ -483,8 +578,43 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
bo->meta.offsets[1] = offset;
offset += ccs_size;
- bo->meta.num_planes = 2;
+ bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
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 = i915_num_planes_from_modifier(bo->drv, format, modifier);
+ bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
} else {
i915_bo_from_format(bo, width, height, format);
}
@@ -500,25 +630,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;
}
@@ -566,6 +691,9 @@ static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
int ret;
struct drm_i915_gem_get_tiling gem_get_tiling = { 0 };
+ bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, data->format,
+ data->format_modifier);
+
ret = drv_prime_bo_import(bo, data);
if (ret)
return ret;
@@ -592,6 +720,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 +823,8 @@ 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,
+ .num_planes_from_modifier = i915_num_planes_from_modifier,
};
#endif
diff --git a/mediatek.c b/mediatek.c
index de492e2..562b1d1 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -19,12 +19,23 @@
#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
+#if defined(MTK_MT8183) || defined(MTK_MT8186)
+#define SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
+#endif
+
+// All platforms except MT8173 should USE_NV12_FOR_HW_VIDEO_DECODING.
+#if defined(MTK_MT8183) || defined(MTK_MT8186) || defined(MTK_MT8192) || defined(MTK_MT8195)
+#define USE_NV12_FOR_HW_VIDEO_DECODING
+#else
+#define DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS
+#endif
+
struct mediatek_private_map_data {
void *cached_addr;
void *gem_addr;
@@ -35,14 +46,36 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA
DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
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 };
-#else
-static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID,
- DRM_FORMAT_NV12 };
+// clang-format off
+static const uint32_t texture_source_formats[] = {
+#ifdef SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_ABGR2101010,
+ DRM_FORMAT_ABGR16161616F,
#endif
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU420_ANDROID
+};
+
+static const uint32_t video_yuv_formats[] = {
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU420_ANDROID
+};
+// clang-format on
+
+static bool is_video_yuv_format(uint32_t format)
+{
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(video_yuv_formats); ++i) {
+ if (format == video_yuv_formats[i])
+ return true;
+ }
+ return false;
+}
static int mediatek_init(struct driver *drv)
{
@@ -65,7 +98,7 @@ static int mediatek_init(struct driver *drv)
metadata.modifier = DRM_FORMAT_MOD_LINEAR;
drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_DECODER);
drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER);
-#if defined(MTK_MT8183) || defined(MTK_MT8192) || defined(MTK_MT8195)
+#ifdef USE_NV12_FOR_HW_VIDEO_DECODING
// TODO(hiroh): Switch to use NV12 for video decoder on MT8173 as well.
drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_DECODER);
#endif
@@ -107,6 +140,12 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
size_t plane;
uint32_t stride;
struct drm_mtk_gem_create gem_create = { 0 };
+ /*
+ * We identify the ChromeOS Camera App buffers via these two USE flags. Those buffers need
+ * the same alignment as the video hardware encoding.
+ */
+ const bool is_camera_preview =
+ (bo->meta.use_flags & BO_USE_SCANOUT) && (bo->meta.use_flags & BO_USE_CAMERA_WRITE);
if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) {
errno = EINVAL;
@@ -116,12 +155,19 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
/*
* Since the ARM L1 cache line size is 64 bytes, align to that as a
- * performance optimization.
+ * performance optimization, except for video buffers on certain platforms,
+ * these should only be accessed from the GPU and VCODEC subsystems (maybe
+ * also MDP), so it's better to align to macroblocks.
*/
stride = drv_stride_from_format(format, width, 0);
+#ifdef DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS
+ const uint32_t alignment = is_video_yuv_format(format) ? 16 : 64;
+ stride = ALIGN(stride, alignment);
+#else
stride = ALIGN(stride, 64);
+#endif
- if (bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER) {
+ if ((bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER) || is_camera_preview) {
uint32_t aligned_height = ALIGN(height, 32);
uint32_t padding[DRV_MAX_PLANES] = { 0 };
@@ -133,7 +179,7 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding);
} else {
-#ifdef MTK_MT8183
+#ifdef SUPPORTS_YUV422_AND_HIGH_BIT_DEPTH_TEXTURING
/*
* JPEG Encoder Accelerator requires 16x16 alignment. We want the buffer
* from camera can be put in JEA directly so align the height to 16
@@ -172,6 +218,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 +234,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,37 +321,56 @@ 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)
+#ifdef USE_NV12_FOR_HW_VIDEO_DECODING
// TODO(hiroh): Switch to use NV12 for video decoder on MT8173 as well.
if (use_flags & (BO_USE_HW_VIDEO_DECODER)) {
- 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;
default:
- return format;
+ break;
}
+ /* Mediatek doesn't support YUV overlays */
+ if (is_video_yuv_format(format))
+ *out_use_flags &= ~BO_USE_SCANOUT;
}
const struct backend backend_mediatek = {
@@ -302,7 +384,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;
diff --git a/msm.c b/msm.c
index 16e781f..5a2a73c 100644
--- a/msm.c
+++ b/msm.c
@@ -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 */
@@ -38,10 +38,12 @@
static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888,
- DRM_FORMAT_XRGB8888 };
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_ABGR2101010,
+ DRM_FORMAT_ABGR16161616F };
static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8,
- DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID };
+ DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID,
+ DRM_FORMAT_P010 };
/*
* Each macrotile consists of m x n (mostly 4 x 4) tiles.
@@ -94,10 +96,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 +165,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;
@@ -199,19 +208,18 @@ static bool should_avoid_ubwc(void)
return true;
}
- /* The video_decode_accelerator_tests needs to read back the frames
- * to verify they are correct. The frame verification relies on
- * computing the MD5 of the video frame. UBWC results in a different
- * MD5. This turns off UBWC for gtest until a proper frame
- * comparison can be made
- * Rely on the same mechanism that waffle is using, but this time check
- * for a dynamic library function that is present in chrome, but missing
- * in gtest. Cups is not loaded for video tests.
+ /* Sommelier relies on implicit modifier, which does not pass host modifier to
+ * zwp_linux_buffer_params_v1_add. Graphics will be broken if UBWC is enabled.
+ * Sommelier shall be fixed to mirror what arc wayland_service does, and then
+ * we can re-enable UBWC here.
+ *
+ * Inherit the trick from crrev/c/2523246 previously used for gtest. The side
+ * effect is all VM guests on msm will revert back to use linear modifier.
*
- * See b/171260705
+ * See b/229147702
*/
if (!dlsym(RTLD_DEFAULT, "cupsFilePrintf")) {
- drv_log("WARNING: gtest detected, disabling UBWC\n");
+ drv_log("WARNING: virtualization detected, disabling UBWC\n");
return true;
}
#endif
@@ -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 */
diff --git a/rockchip.c b/rockchip.c
index 4ef30bc..6d25e3a 100644
--- a/rockchip.c
+++ b/rockchip.c
@@ -6,6 +6,7 @@
#ifdef DRV_ROCKCHIP
+#include <drm_fourcc.h>
#include <errno.h>
#include <inttypes.h>
#include <rockchip_drm.h>
@@ -14,10 +15,14 @@
#include <sys/mman.h>
#include <xf86drm.h>
+#include "drv_helpers.h"
#include "drv_priv.h"
-#include "helpers.h"
#include "util.h"
+#define DRM_FORMAT_MOD_ROCKCHIP_AFBC \
+ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE | \
+ AFBC_FORMAT_MOD_YTR)
+
struct rockchip_private_map_data {
void *cached_addr;
void *gem_addr;
@@ -30,7 +35,8 @@ static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORM
static const uint32_t texture_only_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_YVU420,
DRM_FORMAT_YVU420_ANDROID };
-static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
+static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
+ uint64_t modifier)
{
/* We've restricted ourselves to four bytes per pixel. */
const uint32_t pixel_size = 4;
@@ -69,7 +75,7 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u
bo->meta.total_size = total_size;
- bo->meta.format_modifier = DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC;
+ bo->meta.format_modifier = modifier;
return 0;
}
@@ -113,6 +119,14 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
int ret;
size_t plane;
struct drm_rockchip_gem_create gem_create = { 0 };
+ uint64_t afbc_modifier;
+
+ if (drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_ROCKCHIP_AFBC))
+ afbc_modifier = DRM_FORMAT_MOD_ROCKCHIP_AFBC;
+ else if (drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC))
+ afbc_modifier = DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC;
+ else
+ afbc_modifier = 0;
if (format == DRM_FORMAT_NV12) {
uint32_t w_mbs = DIV_ROUND_UP(width, 16);
@@ -127,12 +141,10 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
* driver to store motion vectors.
*/
bo->meta.total_size += w_mbs * h_mbs * 128;
- } else if (width <= 2560 &&
- drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) &&
- bo->drv->compression) {
+ } else if (width <= 2560 && afbc_modifier && bo->drv->compression) {
/* If the caller has decided they can use AFBC, always
* pick that */
- afbc_bo_from_format(bo, width, height, format);
+ afbc_bo_from_format(bo, width, height, format, afbc_modifier);
} else {
if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) {
errno = EINVAL;
@@ -184,10 +196,12 @@ 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). */
- if (bo->meta.format_modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)
+ if (bo->meta.format_modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC ||
+ bo->meta.format_modifier == DRM_FORMAT_MOD_ROCKCHIP_AFBC)
return MAP_FAILED;
gem_map.handle = bo->handles[0].u32;
@@ -197,20 +211,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 +284,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
diff --git a/vc4.c b/vc4.c
index 5ea4bc3..820e4fe 100644
--- a/vc4.c
+++ b/vc4.c
@@ -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
diff --git a/virtgpu.c b/virtgpu.c
index 23e90b3..db50b46 100644
--- a/virtgpu.c
+++ b/virtgpu.c
@@ -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)&params[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..10930fc 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;
}
@@ -234,16 +239,22 @@ static int cross_domain_init(struct driver *drv)
if (!params[param_host_visible].value && !params[param_create_guest_handle].value)
return -ENOTSUP;
- /*
- * crosvm never reports the fake capset. This is just an extra check to make sure we
- * don't use the cross-domain context by accident. Developers may remove this for
- * testing purposes.
- */
- if ((params[param_supported_capset_ids].value & (1 << CAPSET_CROSS_FAKE)) == 0)
- 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 +280,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];
@@ -347,7 +358,7 @@ static int cross_domain_bo_create(struct bo *bo, uint32_t width, uint32_t height
if (use_flags & BO_USE_SW_MASK)
blob_flags |= VIRTGPU_BLOB_FLAG_USE_MAPPABLE;
- if (params[param_cross_device].value && (use_flags & BO_USE_NON_GPU_HW))
+ if (params[param_cross_device].value)
blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE;
/// It may be possible to have host3d blobs and handles from guest memory at the same time.
@@ -363,7 +374,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 +414,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..7194e42 100644
--- a/virtgpu_virgl.c
+++ b/virtgpu_virgl.c
@@ -12,31 +12,46 @@
#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_NV12, 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 +78,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:
@@ -75,6 +92,8 @@ static uint32_t translate_format(uint32_t drm_fourcc)
return VIRGL_FORMAT_NV12;
case DRM_FORMAT_NV21:
return VIRGL_FORMAT_NV21;
+ case DRM_FORMAT_P010:
+ return VIRGL_FORMAT_P010;
case DRM_FORMAT_YVU420:
case DRM_FORMAT_YVU420_ANDROID:
return VIRGL_FORMAT_YV12;
@@ -330,12 +349,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 +378,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 +408,9 @@ 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_SENSOR_DIRECT_DATA, &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 +440,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 +524,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 +591,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 +607,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 +629,25 @@ 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);
+ /* Android Camera CTS tests requires this. Additionally, the scanout usage is needed for
+ * Camera preview and is expected to be conditionally stripped by virgl_add_combination
+ * when not natively supported and instead handled by HWComposer. */
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_SCANOUT | BO_USE_TEXTURE | BO_USE_SW_MASK |
+ BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
+ /* Android VTS sensors hal tests require BO_USE_SENSOR_DIRECT_DATA. */
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_SENSOR_DIRECT_DATA |
+ BO_USE_GPU_DATA_BUFFER);
if (!priv->host_gbm_enabled) {
drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA,
@@ -663,8 +691,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 +744,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 +774,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)
@@ -778,7 +809,7 @@ static int virgl_bo_invalidate(struct bo *bo, struct mapping *mapping)
// Invalidate is only necessary if the host writes to the buffer. The encoder and
// decoder flags don't differentiate between input and output buffers, but we can
// use the format to determine whether this buffer could be encoder/decoder output.
- host_write_flags = BO_USE_RENDERING | BO_USE_CAMERA_WRITE;
+ host_write_flags = BO_USE_RENDERING | BO_USE_CAMERA_WRITE | BO_USE_GPU_DATA_BUFFER;
if (bo->meta.format == DRM_FORMAT_R8)
host_write_flags |= BO_USE_HW_VIDEO_ENCODER;
else
@@ -934,28 +965,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 +1073,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 +1107,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 };