Mesa (main): egl: android: add IMapper at 4 metadata API buffer_info getter

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 30 17:09:17 UTC 2021


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

Author: Roman Stratiienko <r.stratiienko at gmail.com>
Date:   Tue Dec 15 16:50:19 2020 +0200

egl: android: add IMapper at 4 metadata API buffer_info getter

Starting from Android-11 Google introduces generalized API
to access buffer information. This API is a part of IMapper at 4 HAL.

Signed-off-by: Roman Stratiienko <r.stratiienko at gmail.com>
Reviewed-by: Yiwei Zhang <zzyiwei at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6045>

---

 android/Android.mk                               |  10 ++
 meson.build                                      |   4 +
 src/egl/drivers/dri2/platform_android.c          |  16 +-
 src/egl/drivers/dri2/platform_android.h          |  40 ++++-
 src/egl/drivers/dri2/platform_android_mapper.cpp | 211 +++++++++++++++++++++++
 src/egl/meson.build                              |   7 +
 6 files changed, 274 insertions(+), 14 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index d5d2c68272f..243da8493af 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -78,6 +78,16 @@ MESON_LLVM_IRBUILDER_PATH := external/llvm-project/llvm/include/llvm/IR/IRBuilde
 LOCAL_SHARED_LIBRARIES += libLLVM11
 endif
 
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 30; echo $$?), 0)
+LOCAL_SHARED_LIBRARIES += \
+    android.hardware.graphics.mapper at 4.0 \
+    libgralloctypes \
+    libhidlbase \
+    libutils
+
+MESON_GEN_PKGCONFIGS += android.hardware.graphics.mapper:4.0
+endif
+
 ifeq ($(TARGET_IS_64_BIT),true)
 LOCAL_MULTILIB := 64
 else
diff --git a/meson.build b/meson.build
index 8d74b96a27b..74dc4ad0743 100644
--- a/meson.build
+++ b/meson.build
@@ -899,6 +899,7 @@ if with_android_stub and not with_platform_android
 endif
 
 if with_platform_android
+  dep_android_mapper4 = null_dep
   if not with_android_stub
     dep_android = [
       dependency('cutils'),
@@ -909,6 +910,9 @@ if with_platform_android
     if get_option('platform-sdk-version') >= 26
       dep_android += dependency('nativewindow')
     endif
+    if get_option('platform-sdk-version') >= 30
+      dep_android_mapper4 = dependency('android.hardware.graphics.mapper', version : '>= 4.0', required : false)
+    endif
   endif
   pre_args += [
     '-DHAVE_ANDROID_PLATFORM',
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 988e0a3c181..d211fd5aa40 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -187,19 +187,6 @@ get_native_buffer_name(struct ANativeWindowBuffer *buf)
 }
 #endif /* HAVE_DRM_GRALLOC */
 
-struct buffer_info {
-   uint32_t drm_fourcc;
-   int num_planes;
-   int fds[4];
-   uint64_t modifier;
-   int offsets[4];
-   int pitches[4];
-   enum __DRIYUVColorSpace yuv_color_space;
-   enum __DRISampleRange sample_range;
-   enum __DRIChromaSiting horizontal_siting;
-   enum __DRIChromaSiting vertical_siting;
-};
-
 static int
 get_yuv_buffer_info(_EGLDisplay *disp,
                     struct ANativeWindowBuffer *buf,
@@ -404,6 +391,9 @@ droid_create_image_from_native_buffer(_EGLDisplay *disp,
    unsigned error;
 
    do {
+      if (!mapper_metadata_get_buffer_info(buf, &buf_info))
+         break;
+
       if (!cros_get_buffer_info(disp, buf, &buf_info))
          break;
 
diff --git a/src/egl/drivers/dri2/platform_android.h b/src/egl/drivers/dri2/platform_android.h
index fc72013510d..2bcf56fe90f 100644
--- a/src/egl/drivers/dri2/platform_android.h
+++ b/src/egl/drivers/dri2/platform_android.h
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2021, Google Inc.
+ * Copyright (C) 2021, GlobalLogic Ukraine
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -24,6 +25,12 @@
 #ifndef EGL_ANDROID_INCLUDED
 #define EGL_ANDROID_INCLUDED
 
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <GL/internal/dri_interface.h>
+
 #include "egl_dri2.h"
 
 #if ANDROID_API_LEVEL < 26
@@ -112,6 +119,37 @@ ANativeWindow_query(const struct ANativeWindow *window,
    }
    return window->query(window, (int)what, value);
 }
-#endif
+#endif // ANDROID_API_LEVEL < 26
+
+struct buffer_info {
+   uint32_t drm_fourcc;
+   int num_planes;
+   int fds[4];
+   uint64_t modifier;
+   int offsets[4];
+   int pitches[4];
+   enum __DRIYUVColorSpace yuv_color_space;
+   enum __DRISampleRange sample_range;
+   enum __DRIChromaSiting horizontal_siting;
+   enum __DRIChromaSiting vertical_siting;
+};
 
+#ifdef USE_IMAPPER4_METADATA_API
+#ifdef __cplusplus
+extern "C" {
 #endif
+extern int
+mapper_metadata_get_buffer_info(struct ANativeWindowBuffer *buf,
+                                struct buffer_info *out_buf_info);
+#ifdef __cplusplus
+}
+#endif
+#else
+static inline int
+mapper_metadata_get_buffer_info(struct ANativeWindowBuffer *buf,
+                                struct buffer_info *out_buf_info) {
+   return -ENOTSUP;
+}
+#endif /* USE_IMAPPER4_METADATA_API */
+
+#endif /* EGL_ANDROID_INCLUDED */
diff --git a/src/egl/drivers/dri2/platform_android_mapper.cpp b/src/egl/drivers/dri2/platform_android_mapper.cpp
new file mode 100644
index 00000000000..8c3496c2bbb
--- /dev/null
+++ b/src/egl/drivers/dri2/platform_android_mapper.cpp
@@ -0,0 +1,211 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2021 GlobalLogic Ukraine
+ * Copyright (C) 2021 Roman Stratiienko (r.stratiienko at gmail.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "platform_android.h"
+
+#include <system/window.h>
+#include <aidl/android/hardware/graphics/common/ChromaSiting.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/common/ExtendableType.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
+#include <gralloctypes/Gralloc4.h>
+
+using aidl::android::hardware::graphics::common::ChromaSiting;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::ExtendableType;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using android::hardware::graphics::common::V1_2::BufferUsage;
+using android::hardware::graphics::mapper::V4_0::Error;
+using android::hardware::graphics::mapper::V4_0::IMapper;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_vec;
+using MetadataType =
+   android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+
+Error
+GetMetadata(android::sp<IMapper> mapper, const native_handle_t *buffer,
+            MetadataType type, hidl_vec<uint8_t>* metadata)
+{
+   Error error = Error::NONE;
+
+   auto native_handle = const_cast<native_handle_t*>(buffer);
+
+   auto ret = mapper->get(native_handle, type,
+                          [&](const auto& get_error, const auto& get_metadata) {
+                              error = get_error;
+                              *metadata = get_metadata;
+                          });
+
+   if (!ret.isOk())
+      error = Error::NO_RESOURCES;
+
+   return error;
+}
+
+std::optional<std::vector<PlaneLayout>> GetPlaneLayouts(
+   android::sp<IMapper> mapper, const native_handle_t *buffer)
+{
+   hidl_vec<uint8_t> encoded_layouts;
+
+   Error error = GetMetadata(mapper, buffer,
+                            android::gralloc4::MetadataType_PlaneLayouts,
+                            &encoded_layouts);
+
+   if (error != Error::NONE)
+      return std::nullopt;
+
+   std::vector<PlaneLayout> plane_layouts;
+
+   auto status = android::gralloc4::decodePlaneLayouts(encoded_layouts, &plane_layouts);
+
+   if (status != android::OK)
+      return std::nullopt;
+
+   return plane_layouts;
+}
+
+extern "C"
+{
+
+int
+mapper_metadata_get_buffer_info(struct ANativeWindowBuffer *buf,
+                                struct buffer_info *out_buf_info)
+{
+   static android::sp<IMapper> mapper = IMapper::getService();
+   struct buffer_info buf_info = *out_buf_info;
+   if (mapper == nullptr)
+      return -EINVAL;
+
+   if (!buf->handle)
+      return -EINVAL;
+
+   hidl_vec<uint8_t> encoded_format;
+   auto err = GetMetadata(mapper, buf->handle, android::gralloc4::MetadataType_PixelFormatFourCC, &encoded_format);
+   if (err != Error::NONE)
+      return -EINVAL;
+
+   auto status = android::gralloc4::decodePixelFormatFourCC(encoded_format, &buf_info.drm_fourcc);
+   if (status != android::OK)
+      return -EINVAL;
+
+   hidl_vec<uint8_t> encoded_modifier;
+   err = GetMetadata(mapper, buf->handle, android::gralloc4::MetadataType_PixelFormatModifier, &encoded_modifier);
+   if (err != Error::NONE)
+      return -EINVAL;
+
+   status = android::gralloc4::decodePixelFormatModifier(encoded_modifier, &buf_info.modifier);
+   if (status != android::OK)
+      return -EINVAL;
+
+   auto layouts_opt = GetPlaneLayouts(mapper, buf->handle);
+
+   if (!layouts_opt)
+      return -EINVAL;
+
+   std::vector<PlaneLayout>& layouts = *layouts_opt;
+
+   buf_info.num_planes = layouts.size();
+
+   bool per_plane_unique_fd = buf->handle->numFds == buf_info.num_planes;
+
+   for (uint32_t i = 0; i < layouts.size(); i++) {
+      buf_info.fds[i] = per_plane_unique_fd ? buf->handle->data[i] : buf->handle->data[0];
+      buf_info.pitches[i] = layouts[i].strideInBytes;
+      buf_info.offsets[i] = layouts[i].offsetInBytes;
+   }
+
+   /* optional attributes */
+   hidl_vec<uint8_t> encoded_chroma_siting;
+   err = GetMetadata(mapper, buf->handle, android::gralloc4::MetadataType_ChromaSiting, &encoded_chroma_siting);
+   if (err == Error::NONE) {
+      ExtendableType chroma_siting_ext;
+      status = android::gralloc4::decodeChromaSiting(encoded_chroma_siting, &chroma_siting_ext);
+      if (status != android::OK)
+         return -EINVAL;
+
+      ChromaSiting chroma_siting = android::gralloc4::getStandardChromaSitingValue(chroma_siting_ext);
+      switch (chroma_siting) {
+         case ChromaSiting::SITED_INTERSTITIAL:
+            buf_info.horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5;
+            buf_info.vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
+            break;
+         case ChromaSiting::COSITED_HORIZONTAL:
+            buf_info.horizontal_siting = __DRI_YUV_CHROMA_SITING_0;
+            buf_info.vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
+            break;
+         default:
+            break;
+      }
+   }
+
+   hidl_vec<uint8_t> encoded_dataspace;
+   err = GetMetadata(mapper, buf->handle, android::gralloc4:: MetadataType_Dataspace, &encoded_dataspace);
+   if (err == Error::NONE) {
+      Dataspace dataspace;
+      status = android::gralloc4::decodeDataspace(encoded_dataspace, &dataspace);
+      if (status != android::OK)
+         return -EINVAL;
+
+      Dataspace standard = (Dataspace)((int)dataspace & (uint32_t)Dataspace::STANDARD_MASK);
+      switch (standard) {
+         case Dataspace::STANDARD_BT709:
+            buf_info.yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
+            break;
+         case Dataspace::STANDARD_BT601_625:
+         case Dataspace::STANDARD_BT601_625_UNADJUSTED:
+         case Dataspace::STANDARD_BT601_525:
+         case Dataspace::STANDARD_BT601_525_UNADJUSTED:
+            buf_info.yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
+            break;
+         case Dataspace::STANDARD_BT2020:
+         case Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE:
+            buf_info.yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
+            break;
+         default:
+            break;
+      }
+
+      Dataspace range = (Dataspace)((int)dataspace & (uint32_t)Dataspace::RANGE_MASK);
+      switch (range) {
+         case Dataspace::RANGE_FULL:
+            buf_info.sample_range = __DRI_YUV_FULL_RANGE;
+            break;
+         case Dataspace::RANGE_LIMITED:
+            buf_info.sample_range = __DRI_YUV_NARROW_RANGE;
+            break;
+         default:
+            break;
+      }
+   }
+
+   *out_buf_info = buf_info;
+
+   return 0;
+}
+
+} // extern "C"
diff --git a/src/egl/meson.build b/src/egl/meson.build
index 055cfcf75fb..ab8f4e1fdbe 100644
--- a/src/egl/meson.build
+++ b/src/egl/meson.build
@@ -22,6 +22,7 @@ inc_egl = include_directories('.', 'main')
 inc_egl_dri2 = include_directories('drivers/dri2')
 
 c_args_for_egl = [asan_c_args]
+cpp_args_for_egl = []
 link_for_egl = []
 deps_for_egl = []
 incs_for_egl = [inc_include, inc_src, inc_egl]
@@ -125,6 +126,11 @@ if with_dri2
   if with_platform_android
     deps_for_egl += dep_android
     files_egl += files('drivers/dri2/platform_android.c')
+    if dep_android_mapper4.found()
+      files_egl += files('drivers/dri2/platform_android_mapper.cpp')
+      c_args_for_egl += '-DUSE_IMAPPER4_METADATA_API'
+      cpp_args_for_egl += ['-std=c++17', '-DUSE_IMAPPER4_METADATA_API']
+    endif
   endif
 elif with_platform_haiku
   incs_for_egl += inc_haikugl
@@ -167,6 +173,7 @@ libegl = shared_library(
     c_args_for_egl,
     '-D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_ at 0@'.format(egl_native_platform.to_upper()),
   ],
+  cpp_args : [cpp_args_for_egl],
   gnu_symbol_visibility : 'hidden',
   include_directories : incs_for_egl,
   link_with : [link_for_egl, libglapi],



More information about the mesa-commit mailing list