Module: Mesa
Branch: main
Commit: 4afcd0c6d6246e21bf9a68a9949355ac68610231
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=4afcd0c6d6246e21bf9a68a9949355ac68610231

Author: Roman Stratiienko <r.stratiie...@gmail.com>
Date:   Mon Sep 25 21:39:34 2023 +0300

u_gralloc: Add support for gbm_gralloc

Although gbm_gralloc has not been maintained for a long time, it is still
used in android-x86, BlissOS and WayDroid. Let's add support so that
x86 drivers no longer need to request tiling flags from the kernel.

Acked-by: Chia-I Wu <olva...@gmail.com>
Acked-by: David Heidelberg <david.heidelb...@collabora.com>
Tested-by: HMTheBoy154 <buingo...@gmail.com>  # BlissOS 15 & Mesa 23.3.2
Tested-by: Mauro Rossi <issor.or...@gmail.com>  # android-x86 for mesa 
24.0.0-devel on Skylake GT2
Signed-off-by: Roman Stratiienko <r.stratiie...@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25380>

---

 src/util/u_gralloc/meson.build          |   1 +
 src/util/u_gralloc/u_gralloc.c          |   1 +
 src/util/u_gralloc/u_gralloc.h          |   1 +
 src/util/u_gralloc/u_gralloc_internal.h |   1 +
 src/util/u_gralloc/u_gralloc_libdrm.c   | 106 ++++++++++++++++++++++++++++++++
 src/util/u_gralloc/u_gralloc_libdrm.h   |  62 +++++++++++++++++++
 6 files changed, 172 insertions(+)

diff --git a/src/util/u_gralloc/meson.build b/src/util/u_gralloc/meson.build
index 39f181cae3f..913fc7c786d 100644
--- a/src/util/u_gralloc/meson.build
+++ b/src/util/u_gralloc/meson.build
@@ -12,6 +12,7 @@ files_u_gralloc = files(
   'u_gralloc_internal.c',
   'u_gralloc_fallback.c',
   'u_gralloc_cros_api.c',
+  'u_gralloc_libdrm.c',
   'u_gralloc_qcom.c',
 )
 
diff --git a/src/util/u_gralloc/u_gralloc.c b/src/util/u_gralloc/u_gralloc.c
index 1e694e4e66e..b92057c515d 100644
--- a/src/util/u_gralloc/u_gralloc.c
+++ b/src/util/u_gralloc/u_gralloc.c
@@ -28,6 +28,7 @@ static const struct u_grallocs {
 #ifdef USE_IMAPPER4_METADATA_API
    {.type = U_GRALLOC_TYPE_GRALLOC4, .create = u_gralloc_imapper_api_create},
 #endif /* USE_IMAPPER4_METADATA_API */
+   {.type = U_GRALLOC_TYPE_LIBDRM, .create = u_gralloc_libdrm_create},
    {.type = U_GRALLOC_TYPE_QCOM, .create = u_gralloc_qcom_create},
    {.type = U_GRALLOC_TYPE_FALLBACK, .create = u_gralloc_fallback_create},
 };
diff --git a/src/util/u_gralloc/u_gralloc.h b/src/util/u_gralloc/u_gralloc.h
index 9a56093fb41..a04a490d636 100644
--- a/src/util/u_gralloc/u_gralloc.h
+++ b/src/util/u_gralloc/u_gralloc.h
@@ -51,6 +51,7 @@ enum u_gralloc_type {
    U_GRALLOC_TYPE_AUTO,
    U_GRALLOC_TYPE_GRALLOC4,
    U_GRALLOC_TYPE_CROS,
+   U_GRALLOC_TYPE_LIBDRM,
    U_GRALLOC_TYPE_QCOM,
    U_GRALLOC_TYPE_FALLBACK,
    U_GRALLOC_TYPE_COUNT,
diff --git a/src/util/u_gralloc/u_gralloc_internal.h 
b/src/util/u_gralloc/u_gralloc_internal.h
index b9bceef46cd..80975607f44 100644
--- a/src/util/u_gralloc/u_gralloc_internal.h
+++ b/src/util/u_gralloc/u_gralloc_internal.h
@@ -36,6 +36,7 @@ extern struct u_gralloc *u_gralloc_cros_api_create(void);
 extern struct u_gralloc *u_gralloc_imapper_api_create(void);
 #endif
 extern struct u_gralloc *u_gralloc_qcom_create(void);
+extern struct u_gralloc *u_gralloc_libdrm_create(void);
 extern struct u_gralloc *u_gralloc_fallback_create(void);
 
 /* Helpers for legacy grallocs */
diff --git a/src/util/u_gralloc/u_gralloc_libdrm.c 
b/src/util/u_gralloc/u_gralloc_libdrm.c
new file mode 100644
index 00000000000..01c3c178abb
--- /dev/null
+++ b/src/util/u_gralloc/u_gralloc_libdrm.c
@@ -0,0 +1,106 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2023 Roman Stratiienko (r.stratiie...@gmail.com)
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "u_gralloc_libdrm.h"
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
+#include <hardware/gralloc.h>
+
+#include "util/log.h"
+#include "util/u_memory.h"
+
+#include "u_gralloc_internal.h"
+
+/* Despite minigbm becoming standard gralloc for many distributions, some
+ * users still rely on legacy grallocs, like gbm_gralloc that use a native
+ * handle header that is located at libdrm/android/gralloc_handle.h.
+ * Using this gralloc is not recommended for new distributions.
+ */
+
+struct libdrm_gralloc {
+   struct u_gralloc base;
+   gralloc_module_t *gralloc_module;
+   struct u_gralloc *fallback_gralloc;
+};
+
+static const char gbm_gralloc_module_name[] = "GBM Memory Allocator";
+
+static int
+get_buffer_info(struct u_gralloc *gralloc,
+                struct u_gralloc_buffer_handle *hnd,
+                struct u_gralloc_buffer_basic_info *out)
+{
+   struct libdrm_gralloc *gr = (struct libdrm_gralloc *)gralloc;
+   struct gralloc_handle_t *handle = (struct gralloc_handle_t *)hnd->handle;
+   assert(handle->base.numFds == GRALLOC_HANDLE_NUM_FDS);
+   assert(handle->base.numInts == GRALLOC_HANDLE_NUM_INTS);
+   assert(handle->magic == GRALLOC_HANDLE_MAGIC);
+
+   if (handle->version != GRALLOC_HANDLE_VERSION)
+      mesa_loge("Unexpected gralloc handle version %d", handle->version);
+
+   assert(handle->version == GRALLOC_HANDLE_VERSION);
+
+   /* Query basic information using fallback gralloc */
+   u_gralloc_get_buffer_basic_info(gr->fallback_gralloc, hnd, out);
+
+   /* Fill the known data using libdrm gralloc handle */
+   out->modifier = handle->modifier;
+   out->strides[0] = handle->stride;
+
+   return 0;
+}
+
+static int
+destroy(struct u_gralloc *gralloc)
+{
+   struct libdrm_gralloc *gr = (struct libdrm_gralloc *)gralloc;
+   if (gr->gralloc_module)
+      dlclose(gr->gralloc_module->common.dso);
+
+   if (gr->fallback_gralloc)
+      gr->fallback_gralloc->ops.destroy(gr->fallback_gralloc);
+
+   FREE(gr);
+
+   return 0;
+}
+
+struct u_gralloc *
+u_gralloc_libdrm_create()
+{
+   struct libdrm_gralloc *gr = CALLOC_STRUCT(libdrm_gralloc);
+   int err = 0;
+
+   err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+                       (const hw_module_t **)&gr->gralloc_module);
+
+   if (err)
+      goto fail;
+
+   if (strcmp(gr->gralloc_module->common.name, gbm_gralloc_module_name) != 0)
+      goto fail;
+
+   gr->base.ops.get_buffer_basic_info = get_buffer_info;
+   gr->base.ops.destroy = destroy;
+
+   mesa_logw("Using gralloc header from libdrm/android/gralloc_handle.h. "
+             " This is not recommended for new distributions. "
+             " Initializing a fallback gralloc as a helper:");
+
+   gr->fallback_gralloc = u_gralloc_fallback_create();
+
+   return &gr->base;
+
+fail:
+   destroy(&gr->base);
+
+   return NULL;
+}
diff --git a/src/util/u_gralloc/u_gralloc_libdrm.h 
b/src/util/u_gralloc/u_gralloc_libdrm.h
new file mode 100644
index 00000000000..e3e2be85a47
--- /dev/null
+++ b/src/util/u_gralloc/u_gralloc_libdrm.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010-2011 Chia-I Wu <olva...@gmail.com>
+ * Copyright (C) 2010-2011 LunarG Inc.
+ * Copyright (C) 2016 Linaro, Ltd., Rob Herring <r...@kernel.org>
+ * Copyright (C) 2018 Collabora, Robert Foss <robert.f...@collabora.com>
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copied from:
+ * 
https://gitlab.freedesktop.org/mesa/drm/-/blob/6abc164052e4902f67213baa279d743cf46227d4/android/gralloc_handle.h
+ */
+
+#ifndef __ANDROID_GRALLOC_HANDLE_H__
+#define __ANDROID_GRALLOC_HANDLE_H__
+
+#include <cutils/native_handle.h>
+#include <stdint.h>
+
+struct gralloc_handle_t {
+       native_handle_t base;
+
+       /* dma-buf file descriptor
+        * Must be located first since, native_handle_t is allocated
+        * using native_handle_create(), which allocates space for
+        * sizeof(native_handle_t) + sizeof(int) * (numFds + numInts)
+        * numFds = GRALLOC_HANDLE_NUM_FDS
+        * numInts = GRALLOC_HANDLE_NUM_INTS
+        * Where numFds represents the number of FDs and
+        * numInts represents the space needed for the
+        * remainder of this struct.
+        * And the FDs are expected to be found first following
+        * native_handle_t.
+        */
+       int prime_fd;
+
+       /* api variables */
+       uint32_t magic; /* differentiate between allocator impls */
+       uint32_t version; /* api version */
+
+       uint32_t width; /* width of buffer in pixels */
+       uint32_t height; /* height of buffer in pixels */
+       uint32_t format; /* pixel format (Android) */
+       uint32_t usage; /* android libhardware usage flags */
+
+       uint32_t stride; /* the stride in bytes */
+       int data_owner; /* owner of data (for validation) */
+       uint64_t modifier __attribute__((aligned(8))); /* buffer modifiers */
+
+       union {
+               void *data; /* pointer to struct gralloc_gbm_bo_t */
+               uint64_t reserved;
+       } __attribute__((aligned(8)));
+};
+
+#define GRALLOC_HANDLE_VERSION 4
+#define GRALLOC_HANDLE_MAGIC 0x60585350
+#define GRALLOC_HANDLE_NUM_FDS 1
+#define GRALLOC_HANDLE_NUM_INTS (      \
+       ((sizeof(struct gralloc_handle_t) - 
sizeof(native_handle_t))/sizeof(int))       \
+        - GRALLOC_HANDLE_NUM_FDS)
+
+#endif /* __ANDROID_GRALLOC_HANDLE_H__ */

Reply via email to