From b4adc23fe0363fadb5bf36485a8f1b9d17aa693e Mon Sep 17 00:00:00 2001 From: lhl Date: Mon, 21 Feb 2022 00:55:56 +0800 Subject: [PATCH 1/8] add build script Signed-off-by: lhl --- ohos/README.md | 41 ++++++++++++++++++++++++ ohos/build_wayland_and_gbm.py | 36 +++++++++++++++++++++ ohos/cross_file | 60 +++++++++++++++++++++++++++++++++++ ohos/meson_cross_process.py | 7 ++-- 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 ohos/README.md create mode 100644 ohos/build_wayland_and_gbm.py create mode 100644 ohos/cross_file diff --git a/ohos/README.md b/ohos/README.md new file mode 100644 index 00000000000..b9cdbefc3e3 --- /dev/null +++ b/ohos/README.md @@ -0,0 +1,41 @@ +### 编译环境依赖: +1. meson +mesa是使用meson进行编译的并要求版本>= 0.52,可执行以下命令安装meson +``` +sudo apt-get install python3 python3-pip ninja-build +pip3 install --user meson +``` +2. pkg-config +meson配置编译环境时会使用pkg-config查找依赖库和头文件,可以执行以下命令安装 +``` +sudo apt-get install pkg-config +``` + +### 编译步骤如下: +1. 下载openharmony整个工程代码,并完成编译 +2. 因为有些依赖库是静态库,整编后会被删除需要执行以下命令单独编译以rk3568为例 +``` +./build.sh --product-name=rk3568 --build-target=expat +./build.sh --product-name=rk3568 --build-target=libwayland_server.0 +./build.sh --product-name=rk3568 --build-target=libwayland_client.0 +./build.sh --product-name=rk3568 --build-target=libwayland_server +./build.sh --product-name=rk3568 --build-target=libwayland_client +``` + +3. 编译mesa +编译鸿蒙系统下的mesa库时,需要配置鸿蒙的交叉编译链和依赖的库,相关配置和编译步骤已经封装到ohos目录下的python脚本中,编译时只需执行 build_wayland_and_gbm.py 脚本即可,执行命名需要输入三个参数 + +| 参数 | 说明 | +| ---- | ---- | +| arg1 | openharmony代码路径 | +| arg2 | 产品名字,实际上为out目录下存放系统编译结果的那个目录 如hi3516dv300 或则 rk3568, 注: LTS3.0 的版本必须是 ohos-arm-release| +| arg3 | mesa 源码路径| + +示例如下: +~/openharmony 是openharmony源码路径, rk3568是对应的产品输出目录,~/mesa3d为mesa源码路径, 执行完命令后会生成一个名叫builddir的文件夹,该文件夹是mesa的编译目录. 编译完成后相关的库存放在builddir/install/lib 下 + +``` +cd ~/mesa3d +python ohos/build_wayland_and_gbm.py ~/openharmony rk3568 ~/mesa3d + +``` \ No newline at end of file diff --git a/ohos/build_wayland_and_gbm.py b/ohos/build_wayland_and_gbm.py new file mode 100644 index 00000000000..ab4b3f4fe88 --- /dev/null +++ b/ohos/build_wayland_and_gbm.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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 expressor implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import sys +import ntpath +import os +if __name__ == '__main__': + if len(sys.argv) < 4: + print("must input the OpenHarmony directory and the product name and the source dir") + exit(-1) + script_dir = os.path.split(os.path.abspath( __file__))[0] + run_cross_pross_cmd = 'python3 ' + script_dir + '/meson_cross_process.py ' + sys.argv[1] + ' ' + sys.argv[2] + os.system(run_cross_pross_cmd) + + run_build_cmd = 'PKG_CONFIG_PATH=./pkgconfig ' + run_build_cmd += 'meson setup '+ sys.argv[3] + ' builddir ' + run_build_cmd += '-Dvulkan-drivers= -Ddri-drivers= -Dgallium-drivers=panfrost \ + -Dplatforms=wayland -Dglx=disabled -Dtools=panfrost --buildtype=release ' + run_build_cmd += '--cross-file=cross_file ' + run_build_cmd += '--prefix=' + os.getcwd() + '/builddir/install' + print("build command: %s" %run_build_cmd) + os.system(run_build_cmd) + os.system('ninja -C builddir -j26') + os.system('ninja -C builddir install') diff --git a/ohos/cross_file b/ohos/cross_file new file mode 100644 index 00000000000..ce80bcd4dc5 --- /dev/null +++ b/ohos/cross_file @@ -0,0 +1,60 @@ + +[properties] +needs_exe_wrapper = true + +c_args = [ + '-march=armv7-a', + '-mfloat-abi=softfp', + '-mtune=generic-armv7-a', + '-mfpu=neon', + '-mthumb', + '--target=arm-linux-ohosmusl', + '--sysroot=2/out/3/obj/third_party/musl', + '-fPIC'] + +cpp_args = [ + '-march=armv7-a', + '--target=arm-linux-ohosmusl', + '--sysroot=2/out/3/obj/third_party/musl', + '-fPIC'] + +c_link_args = [ + '-march=armv7-a', + '--target=arm-linux-ohosmusl', + '-fPIC', + '--sysroot=2/out/3/obj/third_party/musl', + '-L2/out/3/obj/third_party/musl/usr/lib/arm-linux-ohos', + '-L2/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/10.0.1/lib/arm-linux-ohos', + '-L2/prebuilts/clang/ohos/linux-x87_64/llvm/lib/arm-linux-ohos/c++', + '--rtlib=compiler-rt', + ] + +cpp_link_args = [ + '-march=armv7-a', + '--target=arm-linux-ohosmusl', + '--sysroot=2/out/3/obj/third_party/musl', + '-L2/out/3/obj/third_party/musl/usr/lib/arm-linux-ohos', + '-L2/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/10.0.1/lib/arm-linux-ohos', + '-L2/prebuilts/clang/ohos/linux-x87_64/llvm/lib/arm-linux-ohos/c++', + '-fPIC', + '-Wl,--exclude-libs=libunwind_llvm.a', + '-Wl,--exclude-libs=libc++_static.a', + '-Wl,--exclude-libs=libvpx_assembly_arm.a', + '-Wl,--warn-shared-textrel', + '--rtlib=compiler-rt', + ] + +[binaries] +ar = '2/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-ar' +c = ['ccache', '2/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang'] +cpp = ['ccache', '2/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++'] +c_ld= 'lld' +cpp_ld = 'lld' +strip = '2/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-strip' +pkgconfig = '/usr/bin/pkg-config' + +[host_machine] +system = 'linux' +cpu_family = 'arm' +cpu = 'armv7' +endian = 'little' diff --git a/ohos/meson_cross_process.py b/ohos/meson_cross_process.py index 426f8ee735c..36dc637b632 100644 --- a/ohos/meson_cross_process.py +++ b/ohos/meson_cross_process.py @@ -91,6 +91,8 @@ def generate_cross_file(project_stub, sysroot_stub): def generate_pc_file(file_raw, project_dir, product_name): print(file_raw) + if not os.path.exists('pkgconfig'): + os.makedirs('pkgconfig') filename = 'pkgconfig/'+ ntpath.basename(file_raw) with open(file_raw, 'r+') as file_raw: with open(filename, "w+") as file: @@ -101,10 +103,11 @@ def generate_pc_file(file_raw, project_dir, product_name): print("generate_pc_file") def process_pkgconfig(project_dir, product_name): - files = os.listdir(os.path.split(os.path.abspath( __file__))[0] + r"/pkgconfig_template") + template_dir = os.path.split(os.path.abspath( __file__))[0] + r"/pkgconfig_template" + files = os.listdir(template_dir) for file in files: if not os.path.isdir(file): - generate_pc_file(r"pkgconfig_template/" + file, project_dir, product_name) + generate_pc_file(template_dir + '/' + file, project_dir, product_name) print("process_pkgconfig") if __name__ == '__main__': -- Gitee From 746edc4dbcf505d224df6c4866f9081e2d165c55 Mon Sep 17 00:00:00 2001 From: andrewhw Date: Sat, 26 Feb 2022 16:04:56 +0800 Subject: [PATCH 2/8] impl OHOS interface and add debug log Signed-off-by: andrewhw --- include/EGL/eglext.h | 10 + meson.build | 18 +- meson_options.txt | 4 +- ohos/hilog_common.h | 202 ++++ ohos_cross.ini | 58 ++ pkgconfig/expat.pc | 10 + pkgconfig/libdrm.pc | 9 + pkgconfig/libhilog.pc | 8 + pkgconfig/libsurface.pc | 9 + pkgconfig/zlib.pc | 13 + src/egl/drivers/dri2/egl_dri2.c | 4 + src/egl/drivers/dri2/egl_dri2.h | 23 +- src/egl/drivers/dri2/platform_ohos.c | 1334 ++++++++++++++++++++++++++ src/egl/drivers/dri2/platform_ohos.h | 108 +++ src/egl/main/eglapi.c | 5 + src/egl/main/egldisplay.c | 20 +- src/egl/main/egldisplay.h | 7 + src/egl/main/egllog.c | 4 +- src/egl/main/egllog.h | 1 + src/egl/meson.build | 8 +- 20 files changed, 1842 insertions(+), 13 deletions(-) create mode 100644 ohos/hilog_common.h create mode 100644 ohos_cross.ini create mode 100644 pkgconfig/expat.pc create mode 100644 pkgconfig/libdrm.pc create mode 100644 pkgconfig/libhilog.pc create mode 100644 pkgconfig/libsurface.pc create mode 100644 pkgconfig/zlib.pc create mode 100644 src/egl/drivers/dri2/platform_ohos.c create mode 100644 src/egl/drivers/dri2/platform_ohos.h diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h index 94dd038c9e7..a3a4e3c7ab7 100644 --- a/include/EGL/eglext.h +++ b/include/EGL/eglext.h @@ -276,6 +276,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface #define EGL_PLATFORM_GBM_KHR 0x31D7 #endif /* EGL_KHR_platform_gbm */ +#ifndef EGL_KHR_platform_ohos +#define EGL_KHR_platform_ohos 1 +#define EGL_PLATFORM_OHOS_KHR 0x34E0 +#endif /* EGL_KHR_platform_ohos */ + #ifndef EGL_KHR_platform_wayland #define EGL_KHR_platform_wayland 1 #define EGL_PLATFORM_WAYLAND_KHR 0x31D8 @@ -1402,6 +1407,11 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_TRIPLE_BUFFER_NV 0x3230 #endif /* EGL_NV_triple_buffer */ +#ifndef EGL_OHOS_image_native_buffer +#define EGL_OHOS_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_OHOS 0x34E1 +#endif /* EGL_OHOS_image_native_buffer */ + #ifndef EGL_TIZEN_image_native_buffer #define EGL_TIZEN_image_native_buffer 1 #define EGL_NATIVE_BUFFER_TIZEN 0x32A0 diff --git a/meson.build b/meson.build index faf681fa419..4a0ca4bbedb 100644 --- a/meson.build +++ b/meson.build @@ -347,10 +347,11 @@ with_platform_x11 = _platforms.contains('x11') with_platform_wayland = _platforms.contains('wayland') with_platform_haiku = _platforms.contains('haiku') with_platform_windows = _platforms.contains('windows') +with_platform_ohos = _platforms.contains('ohos') with_glx = get_option('glx') if with_glx == 'auto' - if with_platform_android + if with_platform_android or with_platform_ohos with_glx = 'disabled' elif with_dri with_glx = 'dri' @@ -474,7 +475,7 @@ endif if with_egl _platforms += 'surfaceless' - if with_gbm and not with_platform_android + if with_gbm and not with_platform_android and not with_platform_ohos _platforms += 'drm' endif endif @@ -921,7 +922,7 @@ else pre_args += '-DEGL_NO_X11' gl_pkgconfig_c_flags += '-DEGL_NO_X11' endif -if with_gbm and not with_platform_android +if with_gbm and not with_platform_android and not with_platform_ohos pre_args += '-DHAVE_DRM_PLATFORM' endif if with_platform_windows @@ -959,6 +960,15 @@ if with_platform_haiku pre_args += '-DHAVE_HAIKU_PLATFORM' endif +if with_platform_ohos + pre_args += '-DHAVE_OHOS_PLATFORM' + dep_ohos = [ + dependency('libsurface'), + dependency('libhilog') + ] + c_args += '-I../ohos' +endif + prog_python = import('python').find_installation('python3') has_mako = run_command( prog_python, '-c', @@ -1958,7 +1968,7 @@ endif # TODO: symbol mangling if with_platform_wayland - dep_wl_scanner = dependency('wayland-scanner') + dep_wl_scanner = dependency('wayland-scanner', native: true) prog_wl_scanner = find_program(dep_wl_scanner.get_pkgconfig_variable('wayland_scanner')) if dep_wl_scanner.version().version_compare('>= 1.15') wl_scanner_arg = 'private-code' diff --git a/meson_options.txt b/meson_options.txt index 32c7593ee8e..49c685bc4fc 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -23,7 +23,7 @@ option( type : 'array', value : ['auto'], choices : [ - 'auto', 'x11', 'wayland', 'haiku', 'android', 'windows', + 'auto', 'x11', 'wayland', 'haiku', 'android', 'windows', 'ohos' ], description : 'window systems to support. If this is set to `auto`, all platforms applicable will be enabled.' ) @@ -33,7 +33,7 @@ option( value : 'auto', choices : [ 'auto', 'x11', 'wayland', 'haiku', 'android', 'windows', - 'surfaceless', 'drm', + 'surfaceless', 'drm', 'ohos' ], description : 'the window system EGL assumes for EGL_DEFAULT_DISPLAY', ) diff --git a/ohos/hilog_common.h b/ohos/hilog_common.h new file mode 100644 index 00000000000..f946b712309 --- /dev/null +++ b/ohos/hilog_common.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HILOG_COMMON_H +#define HILOG_COMMON_H + +#ifndef HIVIEWDFX_HILOG_C_H +#define HIVIEWDFX_HILOG_C_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LOG_DOMAIN +#define LOG_DOMAIN 0 +#endif + +#ifndef LOG_TAG +#define LOG_TAG NULL +#endif + +typedef enum { + LOG_TYPE_MIN = 0, + LOG_APP = 0, + LOG_INIT = 1, + LOG_CORE = 3, + LOG_TYPE_MAX +} LogType; + +typedef enum { + /** Debug level to be used by {@link HILOG_DEBUG} */ + LOG_DEBUG = 3, + /** Informational level to be used by {@link HILOG_INFO} */ + LOG_INFORMATION = 4, + /** Warning level to be used by {@link HILOG_WARN} */ + LOG_WARN = 5, + /** Error level to be used by {@link HILOG_ERROR} */ + LOG_ERROR = 6, + /** Fatal level to be used by {@link HILOG_FATAL} */ + LOG_FATAL = 7, + LOG_LEVEL_MAX +} LogLevel; + +int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...) + __attribute__((__format__(os_log, 5, 6))); + +#ifndef USE_MUSL +#define HILOG_DEBUG(type, ...) ((void)HiLogPrint((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) +#else +#define HILOG_DEBUG(type, ...) +#endif + +#ifndef USE_MUSL +#define HILOG_INFO(type, ...) ((void)HiLogPrint((type), LOG_INFORMATION, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) +#else +#define HILOG_INFO(type, ...) +#endif + +#ifndef USE_MUSL +#define HILOG_WARN(type, ...) ((void)HiLogPrint((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) +#else +#define HILOG_WARN(type, ...) +#endif + +#ifndef USE_MUSL +#define HILOG_ERROR(type, ...) ((void)HiLogPrint((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) +#else +#define HILOG_ERROR(type, ...) +#endif + +#ifndef USE_MUSL +#define HILOG_FATAL(type, ...) ((void)HiLogPrint((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) +#else +#define HILOG_FATAL(type, ...) +#endif + +bool HiLogIsLoggable(unsigned int domain, const char *tag, LogLevel level); + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif // HIVIEWDFX_HILOG_C_H + + + +#include +#include +#include "stdio.h" +#ifdef HDF_LOG_TAG +#undef HDF_LOG_TAG +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#undef LOG_TAG +#undef LOG_DOMAIN +#define LOG_TAG "GPU_MESA" +#define LOG_DOMAIN 0xD001400 + +#ifndef DISPLAY_UNUSED +#define DISPLAY_UNUSED(x) (void)x +#endif + +#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__) + +#ifndef DISPLAY_LOGD +#define DISPLAY_LOGD(format, ...) \ + do { \ + HILOG_DEBUG(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \ + ##__VA_ARGS__); \ + } while (0) +#endif + +#ifndef DISPLAY_LOGI +#define DISPLAY_LOGI(format, ...) \ + do { \ + HILOG_INFO(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \ + ##__VA_ARGS__); \ + } while (0) +#endif + +#ifndef DISPLAY_LOGW +#define DISPLAY_LOGW(format, ...) \ + do { \ + HILOG_WARN(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \ + ##__VA_ARGS__); \ + } while (0) +#endif + +#ifndef DISPLAY_LOGE +#define DISPLAY_LOGE(format, ...) \ + do { \ + HILOG_ERROR(LOG_CORE, \ + "\033[0;32;31m" \ + "[%{public}s@%{public}s:%{public}d] " format "\033[m" \ + "\n", \ + __FUNCTION__, __FILENAME__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#endif + +#ifndef CHECK_NULLPOINTER_RETURN_VALUE +#define CHECK_NULLPOINTER_RETURN_VALUE(pointer, ret) \ + do { \ + if ((pointer) == NULL) { \ + DISPLAY_LOGE("pointer is null and return ret\n"); \ + return (ret); \ + } \ + } while (0) +#endif + +#ifndef CHECK_NULLPOINTER_RETURN +#define CHECK_NULLPOINTER_RETURN(pointer) \ + do { \ + if ((pointer) == NULL) { \ + DISPLAY_LOGE("pointer is null and return\n"); \ + return; \ + } \ + } while (0) +#endif + +#ifndef DISPLAY_CHK_RETURN +#define DISPLAY_CHK_RETURN(val, ret, ...) \ + do { \ + if (val) { \ + __VA_ARGS__; \ + return (ret); \ + } \ + } while (0) +#endif + +#ifndef DISPLAY_CHK_RETURN_NOT_VALUE +#define DISPLAY_CHK_RETURN_NOT_VALUE(val, ret, ...) \ + do { \ + if (val) { \ + __VA_ARGS__; \ + return; \ + } \ + } while (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* DISP_COMMON_H */ \ No newline at end of file diff --git a/ohos_cross.ini b/ohos_cross.ini new file mode 100644 index 00000000000..e9a149f6fa6 --- /dev/null +++ b/ohos_cross.ini @@ -0,0 +1,58 @@ +[properties] + c_args = [ + '-march=armv7-a', + '-mfloat-abi=softfp', + '-mtune=generic-armv7-a', + '-mfpu=neon', + '-mthumb', + '-fPIC', + '--target=arm-linux-ohos', + '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', + ] + + cpp_args = [ + '-march=armv7-a', + '--target=arm-linux-ohos', + '-fPIC', + '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', + '-ftls-model=global-dynamic', + '-mtls-direct-seg-refs' + ] + + c_link_args = [ + '-march=armv7-a', + '--target=arm-linux-ohos', + '-fPIC', + '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', + '-L/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl/usr/lib/arm-linux-ohos', + '--rtlib=compiler-rt', + '-ftls-model=global-dynamic', + '-mtls-direct-seg-refs' + ] + + cpp_link_args = [ + '-march=armv7-a', + '--target=arm-linux-ohos', + '-fPIC', + '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', + '-L/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl/usr/lib/arm-linux-ohos', + '--rtlib=compiler-rt', + '-ftls-model=global-dynamic', + '-mtls-direct-seg-refs' + ] + needs_exe_wrapper = true + +[binaries] + ar = '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-ar' + c = ['ccache', '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang'] + cpp = ['ccache', '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++'] + c_ld= 'lld' + cpp_ld = 'lld' + strip = '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-strip' + pkgconfig = ['env', 'PKG_CONFIG_LIBDIR=/home/andrew/OpenHarmony/third_party/mesa3d/pkgconfig', '/usr/bin/pkg-config'] + +[host_machine] + system = 'linux' + cpu_family = 'arm' + cpu = 'armv7' + endian = 'little' diff --git a/pkgconfig/expat.pc b/pkgconfig/expat.pc new file mode 100644 index 00000000000..a9830072399 --- /dev/null +++ b/pkgconfig/expat.pc @@ -0,0 +1,10 @@ +ohos_project_dir=/home/andrew/OpenHarmony +libdir=${ohos_project_dir}/out/rk3568/obj/third_party/expat +includedir=${ohos_project_dir}/third_party/expat/lib + +Name: expat +Version: 2.4.1 +Description: expat XML parser +URL: http://www.libexpat.org +Libs: -L${libdir} -lexpat +Cflags: -I${includedir} \ No newline at end of file diff --git a/pkgconfig/libdrm.pc b/pkgconfig/libdrm.pc new file mode 100644 index 00000000000..27830b55a48 --- /dev/null +++ b/pkgconfig/libdrm.pc @@ -0,0 +1,9 @@ +ohos_project_dir=/home/andrew/OpenHarmony +libdir=${ohos_project_dir}/out/rk3568/graphic/graphic_standard/ +includedir=${ohos_project_dir}/third_party/libdrm + +Name: libdrm +Description: Userspace interface to kernel DRM services +Version: 2.4.102 +Libs: -L${libdir} -ldrm +Cflags: -I${includedir} -I${includedir}/include/drm/ \ No newline at end of file diff --git a/pkgconfig/libhilog.pc b/pkgconfig/libhilog.pc new file mode 100644 index 00000000000..d61af30104b --- /dev/null +++ b/pkgconfig/libhilog.pc @@ -0,0 +1,8 @@ +ohos_project_dir=/home/andrew/OpenHarmony +libdir=${ohos_project_dir}/out/rk3568/hiviewdfx/hilog_native +includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow + +Name: libhilog +Description: libhilog +Version: 2.4.1 +Libs: -L${libdir} -lhilog \ No newline at end of file diff --git a/pkgconfig/libsurface.pc b/pkgconfig/libsurface.pc new file mode 100644 index 00000000000..9db4e0628a3 --- /dev/null +++ b/pkgconfig/libsurface.pc @@ -0,0 +1,9 @@ +ohos_project_dir=/home/andrew/OpenHarmony +libdir=${ohos_project_dir}/out/rk3568/graphic/graphic_standard +includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow + +Name: libsurface +Version: 2.4.1 +Description: libsurface +Libs: -L${libdir} -lsurface.z +Cflags: -I${includedir} -I${ohos_project_dir}/drivers/peripheral/display/interfaces/include -I${ohos_project_dir}/drivers/peripheral/base \ No newline at end of file diff --git a/pkgconfig/zlib.pc b/pkgconfig/zlib.pc new file mode 100644 index 00000000000..4f9245f3387 --- /dev/null +++ b/pkgconfig/zlib.pc @@ -0,0 +1,13 @@ +prefix=/home/andrew/OpenHarmony +exec_prefix=${prefix} +libdir=${prefix}/out/rk3568/obj/third_party/zlib +sharedlibdir=${libdir} +includedir=${prefix}/third_party/zlib + +Name: zlib +Description: zlib compression library +Version: 1.2.12 + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} \ No newline at end of file diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index d687533168b..872ef032d97 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -1186,6 +1186,10 @@ dri2_initialize(_EGLDisplay *disp) case _EGL_PLATFORM_ANDROID: ret = dri2_initialize_android(disp); break; + case _EGL_PLATFORM_OHOS: + // NEED add openharmony init for dri2 + ret = dri2_initialize_ohos(disp); + break; default: unreachable("Callers ensure we cannot get here."); return EGL_FALSE; diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 9acc846687b..f5ccc19bd53 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -73,6 +73,10 @@ struct zwp_linux_dmabuf_v1; #include #endif +#ifdef HAVE_OHOS_PLATFORM +#include "window.h" +#endif + #endif /* HAVE_ANDROID_PLATFORM */ #include "eglconfig.h" @@ -332,9 +336,9 @@ struct dri2_egl_surface } color_buffers[4], *back, *current; #endif -#ifdef HAVE_ANDROID_PLATFORM - struct ANativeWindow *window; - struct ANativeWindowBuffer *buffer; +#if defined(HAVE_ANDROID_PLATFORM) || defined (HAVE_OHOS_PLATFORM) + struct NativeWindow *window; + struct NativeWindowBuffer *buffer; __DRIimage *dri_image_back; __DRIimage *dri_image_front; @@ -344,7 +348,7 @@ struct dri2_egl_surface */ int color_buffers_count; struct { - struct ANativeWindowBuffer *buffer; + struct NativeWindowBuffer *buffer; int age; } *color_buffers, *back; uint32_t gralloc_usage; @@ -529,6 +533,17 @@ dri2_initialize_android(_EGLDisplay *disp) } #endif +#ifdef HAVE_OHOS_PLATFORM +EGLBoolean +dri2_initialize_ohos(_EGLDisplay *disp); +#else +static inline EGLBoolean +dri2_initialize_ohos(_EGLDisplay *disp) +{ + return _eglError(EGL_NOT_INITIALIZED, "ohos platform not built"); +} +#endif + EGLBoolean dri2_initialize_surfaceless(_EGLDisplay *disp); diff --git a/src/egl/drivers/dri2/platform_ohos.c b/src/egl/drivers/dri2/platform_ohos.c new file mode 100644 index 00000000000..5c840463c08 --- /dev/null +++ b/src/egl/drivers/dri2/platform_ohos.c @@ -0,0 +1,1334 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2010-2011 Chia-I Wu + * Copyright (C) 2010-2011 LunarG Inc. + * + * Based on platform_x11, which has + * + * Copyright © 2011 Intel Corporation + * + * 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 +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +#include "util/compiler.h" +#include "util/os_file.h" + +#include "loader.h" +#include "egl_dri2.h" +#include "platform_ohos.h" +#include "libsync.h" +#ifdef HAVE_DRM_GRALLOC +#include +#include "gralloc_drm.h" +#endif /* HAVE_DRM_GRALLOC */ + +#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) + +enum chroma_order { + YCbCr, + YCrCb, +}; + +struct droid_yuv_format { + /* Lookup keys */ + int native; /* PIXEL_FMT_ */ + enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */ + int chroma_step; /* Distance in bytes between subsequent chroma pixels. */ + + /* Result */ + int fourcc; /* DRM_FORMAT_ */ +}; + + +static bool +is_yuv(int native) +{ + return false; +} + +static int +get_format_bpp(int native) +{ + int bpp; + + switch (native) { + case PIXEL_FMT_RGBA_8888: + case PIXEL_FMT_RGBX_8888: + case PIXEL_FMT_BGRA_8888: + bpp = 4; + break; + case PIXEL_FMT_RGB_565: + bpp = 2; + break; + default: + bpp = 0; + break; + } + + return bpp; +} + +/* returns # of fds, and by reference the actual fds */ +static unsigned +get_native_buffer_fds(struct ANativeWindowBuffer *buf, int fds[3]) +{ + BufferHandle* handle = NULL; + handle = GetBufferHandleFromNative(buf); + fds[0] = handle->fd; + if (!handle) + return 0; + return 1; +} + +/* createImageFromFds requires fourcc format */ +static int get_fourcc(int native) +{ + switch (native) { + case PIXEL_FMT_RGB_565: return DRM_FORMAT_RGB565; + case PIXEL_FMT_BGRA_8888: return DRM_FORMAT_ARGB8888; + case PIXEL_FMT_RGBA_8888: return DRM_FORMAT_ABGR8888; + case PIXEL_FMT_RGBX_8888: return DRM_FORMAT_XBGR8888; + default: + _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", native); + } + return -1; +} + +static int +native_window_buffer_get_buffer_info(struct dri2_egl_display *dri2_dpy, + struct ANativeWindowBuffer *buf, + struct buffer_info *out_buf_info) +{ + int num_planes = 0; + int drm_fourcc = 0; + int pitch = 0; + int fds[3]; + /* + * Non-YUV formats could *also* have multiple planes, such as ancillary + * color compression state buffer, but the rest of the code isn't ready + * yet to deal with modifiers: + */ + num_planes = get_native_buffer_fds(buf, fds); + if (num_planes == 0) + return -EINVAL; + + assert(num_planes == 1); + BufferHandle* bufferHandle; + bufferHandle = GetBufferHandleFromNative(buf); + drm_fourcc = get_fourcc(bufferHandle->format); + if (drm_fourcc == -1) { + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + return -EINVAL; + } + pitch = bufferHandle->stride; + if (pitch == 0) { + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + return -EINVAL; + } + + *out_buf_info = (struct buffer_info){ + .width = bufferHandle->width, + .height = bufferHandle->height, + .drm_fourcc = drm_fourcc, + .num_planes = num_planes, + .fds = { fds[0], -1, -1, -1 }, + .modifier = DRM_FORMAT_MOD_INVALID, + .offsets = { 0, 0, 0, 0 }, + .pitches = { pitch, 0, 0, 0 }, + .yuv_color_space = EGL_ITU_REC601_EXT, + .sample_range = EGL_YUV_NARROW_RANGE_EXT, + .horizontal_siting = EGL_YUV_CHROMA_SITING_0_EXT, + .vertical_siting = EGL_YUV_CHROMA_SITING_0_EXT, + }; + + return 0; +} + + +static __DRIimage * +droid_create_image_from_buffer_info(struct dri2_egl_display *dri2_dpy, + struct buffer_info *buf_info, + void *priv) +{ + unsigned error; + + if (dri2_dpy->image->base.version >= 15 && + dri2_dpy->image->createImageFromDmaBufs2 != NULL) { + return dri2_dpy->image->createImageFromDmaBufs2( + dri2_dpy->dri_screen, buf_info->width, buf_info->height, + buf_info->drm_fourcc, buf_info->modifier, buf_info->fds, + buf_info->num_planes, buf_info->pitches, buf_info->offsets, + buf_info->yuv_color_space, buf_info->sample_range, + buf_info->horizontal_siting, buf_info->vertical_siting, &error, + priv); + } + + return dri2_dpy->image->createImageFromDmaBufs( + dri2_dpy->dri_screen, buf_info->width, buf_info->height, + buf_info->drm_fourcc, buf_info->fds, buf_info->num_planes, + buf_info->pitches, buf_info->offsets, buf_info->yuv_color_space, + buf_info->sample_range, buf_info->horizontal_siting, + buf_info->vertical_siting, &error, priv); +} + +static __DRIimage * +droid_create_image_from_native_buffer(_EGLDisplay *disp, + struct ANativeWindowBuffer *buf, + void *priv) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct buffer_info buf_info; + __DRIimage *img = NULL; + + /* If dri driver is gallium virgl, real modifier info queried back from + * CrOS info (and potentially mapper metadata if integrated later) cannot + * get resolved and the buffer import will fail. Thus the fallback behavior + * is preserved down to native_window_buffer_get_buffer_info() so that the + * buffer can be imported without modifier info as a last resort. + */ + + if (!img && !native_window_buffer_get_buffer_info(dri2_dpy, buf, &buf_info)) + img = droid_create_image_from_buffer_info(dri2_dpy, &buf_info, priv); + + return img; +} + +static EGLBoolean +droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) +{ + int fence_fd; + + if (ANativeWindow_dequeueBuffer(dri2_surf->window, &dri2_surf->buffer, + &fence_fd)) + return EGL_FALSE; + + /* If access to the buffer is controlled by a sync fence, then block on the + * fence. + * + * It may be more performant to postpone blocking until there is an + * immediate need to write to the buffer. But doing so would require adding + * hooks to the DRI2 loader. + * + * From the ANativeWindow_dequeueBuffer documentation: + * + * The libsync fence file descriptor returned in the int pointed to by + * the fenceFd argument will refer to the fence that must signal + * before the dequeued buffer may be written to. A value of -1 + * indicates that the caller may access the buffer immediately without + * waiting on a fence. If a valid file descriptor is returned (i.e. + * any value except -1) then the caller is responsible for closing the + * file descriptor. + */ + if (fence_fd >= 0) { + /* From the SYNC_IOC_WAIT documentation in : + * + * Waits indefinitely if timeout < 0. + */ + int timeout = -1; + sync_wait(fence_fd, timeout); + close(fence_fd); + } + /* Record all the buffers created by ANativeWindow and update back buffer + * for updating buffer's age in swap_buffers. + */ + EGLBoolean updated = EGL_FALSE; + for (int i = 0; i < dri2_surf->color_buffers_count; i++) { + if (!dri2_surf->color_buffers[i].buffer) { + dri2_surf->color_buffers[i].buffer = dri2_surf->buffer; + } + if (dri2_surf->color_buffers[i].buffer == dri2_surf->buffer) { + dri2_surf->back = &dri2_surf->color_buffers[i]; + updated = EGL_TRUE; + break; + } + } + + if (!updated) { + /* In case of all the buffers were recreated by ANativeWindow, reset + * the color_buffers + */ + for (int i = 0; i < dri2_surf->color_buffers_count; i++) { + dri2_surf->color_buffers[i].buffer = NULL; + dri2_surf->color_buffers[i].age = 0; + } + dri2_surf->color_buffers[0].buffer = dri2_surf->buffer; + dri2_surf->back = &dri2_surf->color_buffers[0]; + } + + return EGL_TRUE; +} + +static EGLBoolean +droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + /* To avoid blocking other EGL calls, release the display mutex before + * we enter droid_window_enqueue_buffer() and re-acquire the mutex upon + * return. + */ + mtx_unlock(&disp->Mutex); + + /* Queue the buffer with stored out fence fd. The ANativeWindow or buffer + * consumer may choose to wait for the fence to signal before accessing + * it. If fence fd value is -1, buffer can be accessed by consumer + * immediately. Consumer or application shouldn't rely on timestamp + * associated with fence if the fence fd is -1. + * + * Ownership of fd is transferred to consumer after queueBuffer and the + * consumer is responsible for closing it. Caller must not use the fd + * after passing it to queueBuffer. + */ + int fence_fd = dri2_surf->out_fence_fd; + dri2_surf->out_fence_fd = -1; + ANativeWindow_queueBuffer(dri2_surf->window, dri2_surf->buffer, fence_fd); + + dri2_surf->buffer = NULL; + dri2_surf->back = NULL; + + mtx_lock(&disp->Mutex); + + if (dri2_surf->dri_image_back) { + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; + } + + return EGL_TRUE; +} + +static void +droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) +{ + int ret; + int fence_fd = dri2_surf->out_fence_fd; + + dri2_surf->out_fence_fd = -1; + ret = ANativeWindow_cancelBuffer(dri2_surf->window, dri2_surf->buffer, + fence_fd); + dri2_surf->buffer = NULL; + if (ret < 0) { + _eglLog(_EGL_WARNING, "ANativeWindow_cancelBuffer failed"); + dri2_surf->base.Lost = EGL_TRUE; + } +} + +static _EGLSurface * +droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, + void *native_window, const EGLint *attrib_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); + struct dri2_egl_surface *dri2_surf; + struct ANativeWindow *window = native_window; + const __DRIconfig *config; + + dri2_surf = calloc(1, sizeof *dri2_surf); + if (!dri2_surf) { + _eglError(EGL_BAD_ALLOC, "droid_create_surface"); + return NULL; + } + + if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, + true, native_window)) + goto cleanup_surface; + + if (type == EGL_WINDOW_BIT) { + int format; + int buffer_count; + + format = ANativeWindow_getFormat(window); + if (format < 0) { + _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); + goto cleanup_surface; + } + + + /* Required buffer caching slots. */ + buffer_count = 3; // default use 3 buffer + + dri2_surf->color_buffers = calloc(buffer_count, + sizeof(*dri2_surf->color_buffers)); + if (!dri2_surf->color_buffers) { + _eglError(EGL_BAD_ALLOC, "droid_create_surface"); + goto cleanup_surface; + } + dri2_surf->color_buffers_count = buffer_count; + + if (format != dri2_conf->base.NativeVisualID) { + _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x", + format, dri2_conf->base.NativeVisualID); + } + + NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &dri2_surf->base.Height, &dri2_surf->base.Width); + } + + config = dri2_get_dri_config(dri2_conf, type, + dri2_surf->base.GLColorspace); + if (!config) { + _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration"); + goto cleanup_surface; + } + + if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) + goto cleanup_surface; + + if (window) { + ANativeWindow_acquire(window); + dri2_surf->window = window; + } + + return &dri2_surf->base; + +cleanup_surface: + if (dri2_surf->color_buffers_count) + free(dri2_surf->color_buffers); + free(dri2_surf); + + return NULL; +} + +static _EGLSurface * +droid_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, + void *native_window, const EGLint *attrib_list) +{ + return droid_create_surface(disp, EGL_WINDOW_BIT, conf, + native_window, attrib_list); +} + +static _EGLSurface * +droid_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, + const EGLint *attrib_list) +{ + return droid_create_surface(disp, EGL_PBUFFER_BIT, conf, + NULL, attrib_list); +} + +static EGLBoolean +droid_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + + dri2_egl_surface_free_local_buffers(dri2_surf); + + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + if (dri2_surf->buffer) + droid_window_cancel_buffer(dri2_surf); + + ANativeWindow_release(dri2_surf->window); + } + + if (dri2_surf->dri_image_back) { + _eglLog(_EGL_DEBUG, "%s : %d : destroy dri_image_back", __func__, __LINE__); + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; + } + + if (dri2_surf->dri_image_front) { + _eglLog(_EGL_DEBUG, "%s : %d : destroy dri_image_front", __func__, __LINE__); + dri2_dpy->image->destroyImage(dri2_surf->dri_image_front); + dri2_surf->dri_image_front = NULL; + } + + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); + + dri2_fini_surface(surf); + free(dri2_surf->color_buffers); + free(dri2_surf); + + return EGL_TRUE; +} + +static int +update_buffers(struct dri2_egl_surface *dri2_surf) +{ + if (dri2_surf->base.Lost) + return -1; + + if (dri2_surf->base.Type != EGL_WINDOW_BIT) + return 0; + + /* try to dequeue the next back buffer */ + if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) { + _eglLog(_EGL_WARNING, "Could not dequeue buffer from native window"); + dri2_surf->base.Lost = EGL_TRUE; + return -1; + } + BufferHandle* handle = GetBufferHandleFromNative(dri2_surf->buffer); + /* free outdated buffers and update the surface size */ + if (dri2_surf->base.Width != handle->width || + dri2_surf->base.Height != handle->height) { + dri2_egl_surface_free_local_buffers(dri2_surf); + dri2_surf->base.Width = handle->width; + dri2_surf->base.Height = handle->height; + } + + return 0; +} + +static int +get_front_bo(struct dri2_egl_surface *dri2_surf, unsigned int format) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + + if (dri2_surf->dri_image_front) + return 0; + + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + /* According current EGL spec, front buffer rendering + * for window surface is not supported now. + * and mesa doesn't have the implementation of this case. + * Add warning message, but not treat it as error. + */ + _eglLog(_EGL_DEBUG, "DRI driver requested unsupported front buffer for window surface"); + } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) { + dri2_surf->dri_image_front = + dri2_dpy->image->createImage(dri2_dpy->dri_screen, + dri2_surf->base.Width, + dri2_surf->base.Height, + format, + 0, + NULL); + if (!dri2_surf->dri_image_front) { + _eglLog(_EGL_WARNING, "dri2_image_front allocation failed"); + return -1; + } + } + + return 0; +} + +static int +get_back_bo(struct dri2_egl_surface *dri2_surf) +{ + _EGLDisplay *disp = dri2_surf->base.Resource.Display; + + if (dri2_surf->dri_image_back) + return 0; + + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + if (!dri2_surf->buffer) { + _eglLog(_EGL_WARNING, "Could not get native buffer"); + return -1; + } + + dri2_surf->dri_image_back = + droid_create_image_from_native_buffer(disp, dri2_surf->buffer, NULL); + if (!dri2_surf->dri_image_back) { + _eglLog(_EGL_WARNING, "failed to create DRI image from FD"); + return -1; + } + } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) { + /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically, + * the spec states that they have a back buffer but no front buffer, in + * contrast to pixmaps, which have a front buffer but no back buffer. + * + * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate + * from the spec, following the precedent of Mesa's EGL X11 platform. The + * X11 platform correctly assigns pbuffers to single-buffered configs, but + * assigns the pbuffer a front buffer instead of a back buffer. + * + * Pbuffers in the X11 platform mostly work today, so let's just copy its + * behavior instead of trying to fix (and hence potentially breaking) the + * world. + */ + _eglLog(_EGL_DEBUG, "DRI driver requested unsupported back buffer for pbuffer surface"); + } + + return 0; +} + +/* Some drivers will pass multiple bits in buffer_mask. + * For such case, will go through all the bits, and + * will not return error when unsupported buffer is requested, only + * return error when the allocation for supported buffer failed. + */ +static int +droid_image_get_buffers(__DRIdrawable *driDrawable, + unsigned int format, + uint32_t *stamp, + void *loaderPrivate, + uint32_t buffer_mask, + struct __DRIimageList *images) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + images->image_mask = 0; + images->front = NULL; + images->back = NULL; + + if (update_buffers(dri2_surf) < 0) + return 0; + + if (_eglSurfaceInSharedBufferMode(&dri2_surf->base)) { + if (get_back_bo(dri2_surf) < 0) + return 0; + + /* We have dri_image_back because this is a window surface and + * get_back_bo() succeeded. + */ + assert(dri2_surf->dri_image_back); + images->back = dri2_surf->dri_image_back; + images->image_mask |= __DRI_IMAGE_BUFFER_SHARED; + + /* There exists no accompanying back nor front buffer. */ + return 1; + } + + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { + if (get_front_bo(dri2_surf, format) < 0) + return 0; + + if (dri2_surf->dri_image_front) { + images->front = dri2_surf->dri_image_front; + images->image_mask |= __DRI_IMAGE_BUFFER_FRONT; + } + } + + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) { + if (get_back_bo(dri2_surf) < 0) + return 0; + + if (dri2_surf->dri_image_back) { + images->back = dri2_surf->dri_image_back; + images->image_mask |= __DRI_IMAGE_BUFFER_BACK; + } + } + + return 1; +} + +static EGLint +droid_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) +{ + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); + + if (update_buffers(dri2_surf) < 0) { + _eglError(EGL_BAD_ALLOC, "droid_query_buffer_age"); + return -1; + } + + return dri2_surf->back ? dri2_surf->back->age : 0; +} + +static EGLBoolean +droid_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); + const bool has_mutable_rb = _eglSurfaceHasMutableRenderBuffer(draw); + + /* From the EGL_KHR_mutable_render_buffer spec (v12): + * + * If surface is a single-buffered window, pixmap, or pbuffer surface + * for which there is no pending change to the EGL_RENDER_BUFFER + * attribute, eglSwapBuffers has no effect. + */ + if (has_mutable_rb && + draw->RequestedRenderBuffer == EGL_SINGLE_BUFFER && + draw->ActiveRenderBuffer == EGL_SINGLE_BUFFER) { + _eglLog(_EGL_DEBUG, "%s: remain in shared buffer mode", __func__); + return EGL_TRUE; + } + + for (int i = 0; i < dri2_surf->color_buffers_count; i++) { + if (dri2_surf->color_buffers[i].age > 0) + dri2_surf->color_buffers[i].age++; + } + + /* "XXX: we don't use get_back_bo() since it causes regressions in + * several dEQP tests. + */ + if (dri2_surf->back) + dri2_surf->back->age = 1; + + dri2_flush_drawable_for_swapbuffers(disp, draw); + + /* dri2_surf->buffer can be null even when no error has occured. For + * example, if the user has called no GL rendering commands since the + * previous eglSwapBuffers, then the driver may have not triggered + * a callback to ANativeWindow_dequeueBuffer, in which case + * dri2_surf->buffer remains null. + */ + if (dri2_surf->buffer) + droid_window_enqueue_buffer(disp, dri2_surf); + + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); + + return EGL_TRUE; +} + +static EGLBoolean +droid_query_surface(_EGLDisplay *disp, _EGLSurface *surf, + EGLint attribute, EGLint *value) +{ + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + EGLint dummy; + switch (attribute) { + case EGL_WIDTH: + if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) { + NativeWindowHandleOpt(dri2_surf->window, + GET_BUFFER_GEOMETRY, &dummy, value); + return EGL_TRUE; + } + break; + case EGL_HEIGHT: + if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) { + NativeWindowHandleOpt(dri2_surf->window, + GET_BUFFER_GEOMETRY, value, &dummy); + return EGL_TRUE; + } + break; + default: + break; + } + return _eglQuerySurface(disp, surf, attribute, value); +} + +static _EGLImage * +dri2_create_image_ohos_native_buffer(_EGLDisplay *disp, + _EGLContext *ctx, + struct ANativeWindowBuffer *buf) +{ + if (ctx != NULL) { + /* From the EGL_ANDROID_image_native_buffer spec: + * + * * If is EGL_NATIVE_BUFFER_ANDROID and is not + * EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated. + */ + _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for " + "EGL_NATIVE_BUFFER_OHOS, the context must be " + "EGL_NO_CONTEXT"); + return NULL; + } + __DRIimage *dri_image = + droid_create_image_from_native_buffer(disp, buf, buf); + +// [TODO] +// #ifdef HAVE_DRM_GRALLOC +// if (dri_image == NULL) +// dri_image = droid_create_image_from_name(disp, buf, buf); +// #endif + + if (dri_image) { + return dri2_create_image_from_dri(disp, dri_image); + } + + return NULL; +} + +static _EGLImage * +droid_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + switch (target) { + case EGL_NATIVE_BUFFER_OHOS: + return dri2_create_image_ohos_native_buffer(disp, ctx, + (struct ANativeWindowBuffer *) buffer); + default: + return dri2_create_image_khr(disp, ctx, target, buffer, attr_list); + } +} + +static void +droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) +{ +} + +#ifdef HAVE_DRM_GRALLOC +static int +droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, + unsigned int *attachments, int count) +{ + int num_buffers = 0; + + /* fill dri2_surf->buffers */ + for (int i = 0; i < count * 2; i += 2) { + __DRIbuffer *buf, *local; + + assert(num_buffers < ARRAY_SIZE(dri2_surf->buffers)); + buf = &dri2_surf->buffers[num_buffers]; + + switch (attachments[i]) { + case __DRI_BUFFER_BACK_LEFT: + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + buf->attachment = attachments[i]; + buf->name = get_native_buffer_name(dri2_surf->buffer); + buf->cpp = get_format_bpp(dri2_surf->buffer->format); + buf->pitch = dri2_surf->buffer->stride * buf->cpp; + buf->flags = 0; + + if (buf->name) + num_buffers++; + + break; + } + FALLTHROUGH; /* for pbuffers */ + case __DRI_BUFFER_DEPTH: + case __DRI_BUFFER_STENCIL: + case __DRI_BUFFER_ACCUM: + case __DRI_BUFFER_DEPTH_STENCIL: + case __DRI_BUFFER_HIZ: + local = dri2_egl_surface_alloc_local_buffer(dri2_surf, + attachments[i], attachments[i + 1]); + + if (local) { + *buf = *local; + num_buffers++; + } + break; + case __DRI_BUFFER_FRONT_LEFT: + case __DRI_BUFFER_FRONT_RIGHT: + case __DRI_BUFFER_FAKE_FRONT_LEFT: + case __DRI_BUFFER_FAKE_FRONT_RIGHT: + case __DRI_BUFFER_BACK_RIGHT: + default: + /* no front or right buffers */ + break; + } + } + + return num_buffers; +} + +static __DRIbuffer * +droid_get_buffers_with_format(__DRIdrawable * driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + if (update_buffers(dri2_surf) < 0) + return NULL; + + *out_count = droid_get_buffers_parse_attachments(dri2_surf, attachments, count); + + if (width) + *width = dri2_surf->base.Width; + if (height) + *height = dri2_surf->base.Height; + + return dri2_surf->buffers; +} +#endif /* HAVE_DRM_GRALLOC */ + +static unsigned +droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap) +{ + /* Note: loaderPrivate is _EGLDisplay* */ + switch (cap) { + case DRI_LOADER_CAP_RGBA_ORDERING: + return 1; + default: + return 0; + } +} + +static void +droid_destroy_loader_image_state(void *loaderPrivate) +{ +#if ANDROID_API_LEVEL >= 26 + if (loaderPrivate) { + AHardwareBuffer_release( + ANativeWindowBuffer_getHardwareBuffer(loaderPrivate)); + } +#endif +} + +static EGLBoolean +droid_add_configs_for_visuals(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + static const struct { + int format; + int rgba_shifts[4]; + unsigned int rgba_sizes[4]; + } visuals[] = { + { PIXEL_FMT_RGBA_8888, { 0, 8, 16, 24 }, { 8, 8, 8, 8 } }, + { PIXEL_FMT_RGBX_8888, { 0, 8, 16, -1 }, { 8, 8, 8, 0 } }, + { PIXEL_FMT_RGB_565, { 11, 5, 0, -1 }, { 5, 6, 5, 0 } }, + /* This must be after PIXEL_FMT_RGBA_8888, we only keep BGRA + * visual if it turns out RGBA visual is not available. + */ + { PIXEL_FMT_BGRA_8888, { 16, 8, 0, 24 }, { 8, 8, 8, 8 } }, + }; + + unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 }; + int config_count = 0; + + /* The nesting of loops is significant here. Also significant is the order + * of the HAL pixel formats. Many Android apps (such as Google's official + * NDK GLES2 example app), and even portions the core framework code (such + * as SystemServiceManager in Nougat), incorrectly choose their EGLConfig. + * They neglect to match the EGLConfig's EGL_NATIVE_VISUAL_ID against the + * window's native format, and instead choose the first EGLConfig whose + * channel sizes match those of the native window format while ignoring the + * channel *ordering*. + * + * We can detect such buggy clients in logcat when they call + * eglCreateSurface, by detecting the mismatch between the EGLConfig's + * format and the window's format. + * + * As a workaround, we generate EGLConfigs such that all EGLConfigs for HAL + * pixel format i precede those for HAL pixel format i+1. In my + * (chadversary) testing on Android Nougat, this was good enough to pacify + * the buggy clients. + */ + bool has_rgba = false; + for (int i = 0; i < ARRAY_SIZE(visuals); i++) { + /* Only enable BGRA configs when RGBA is not available. BGRA configs are + * buggy on stock Android. + */ + if (visuals[i].format == PIXEL_FMT_BGRA_8888 && has_rgba) + continue; + for (int j = 0; dri2_dpy->driver_configs[j]; j++) { + const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; + + const EGLint config_attrs[] = { + EGL_NATIVE_VISUAL_ID, visuals[i].format, + EGL_NATIVE_VISUAL_TYPE, visuals[i].format, + EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE, + EGL_RECORDABLE_ANDROID, EGL_TRUE, + EGL_NONE + }; + + struct dri2_egl_config *dri2_conf = + dri2_add_config(disp, dri2_dpy->driver_configs[j], + config_count + 1, surface_type, config_attrs, + visuals[i].rgba_shifts, visuals[i].rgba_sizes); + if (dri2_conf) { + if (dri2_conf->base.ConfigID == config_count + 1) + config_count++; + format_count[i]++; + } + } + if (visuals[i].format == PIXEL_FMT_RGBA_8888 && format_count[i]) + has_rgba = true; + } + + for (int i = 0; i < ARRAY_SIZE(format_count); i++) { + if (!format_count[i]) { + _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x", + visuals[i].format); + } + } + + return (config_count != 0); +} + +static const struct dri2_egl_display_vtbl droid_display_vtbl = { + .authenticate = NULL, + .create_window_surface = droid_create_window_surface, + .create_pbuffer_surface = droid_create_pbuffer_surface, + .destroy_surface = droid_destroy_surface, + .create_image = droid_create_image_khr, + .swap_buffers = droid_swap_buffers, + .swap_interval = NULL, + .query_buffer_age = droid_query_buffer_age, + .query_surface = droid_query_surface, + .get_dri_drawable = dri2_surface_get_dri_drawable, +}; + +static const __DRIimageLoaderExtension droid_image_loader_extension = { + .base = { __DRI_IMAGE_LOADER, 4 }, + + .getBuffers = droid_image_get_buffers, + .flushFrontBuffer = droid_flush_front_buffer, + .getCapability = droid_get_capability, + .flushSwapBuffers = NULL, + .destroyLoaderImageState = droid_destroy_loader_image_state, +}; + +static void +droid_display_shared_buffer(__DRIdrawable *driDrawable, int fence_fd, + void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + struct ANativeWindowBuffer *old_buffer UNUSED = dri2_surf->buffer; + + if (!_eglSurfaceInSharedBufferMode(&dri2_surf->base)) { + _eglLog(_EGL_WARNING, "%s: internal error: buffer is not shared", + __func__); + return; + } + + if (fence_fd >= 0) { + /* The driver's fence is more recent than the surface's out fence, if it + * exists at all. So use the driver's fence. + */ + if (dri2_surf->out_fence_fd >= 0) { + close(dri2_surf->out_fence_fd); + dri2_surf->out_fence_fd = -1; + } + } else if (dri2_surf->out_fence_fd >= 0) { + fence_fd = dri2_surf->out_fence_fd; + dri2_surf->out_fence_fd = -1; + } + + if (ANativeWindow_queueBuffer(dri2_surf->window, dri2_surf->buffer, + fence_fd)) { + _eglLog(_EGL_WARNING, "%s: ANativeWindow_queueBuffer failed", __func__); + close(fence_fd); + return; + } + + fence_fd = -1; + + if (ANativeWindow_dequeueBuffer(dri2_surf->window, &dri2_surf->buffer, + &fence_fd)) { + /* Tear down the surface because it no longer has a back buffer. */ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + + _eglLog(_EGL_WARNING, "%s: ANativeWindow_dequeueBuffer failed", __func__); + + dri2_surf->base.Lost = true; + dri2_surf->buffer = NULL; + dri2_surf->back = NULL; + + if (dri2_surf->dri_image_back) { + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; + } + + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); + return; + } + + if (fence_fd < 0) + return; + + /* Access to the buffer is controlled by a sync fence. Block on it. + * + * Ideally, we would submit the fence to the driver, and the driver would + * postpone command execution until it signalled. But DRI lacks API for + * that (as of 2018-04-11). + * + * SYNC_IOC_WAIT waits forever if timeout < 0 + */ + sync_wait(fence_fd, -1); + close(fence_fd); +} + +static const __DRImutableRenderBufferLoaderExtension droid_mutable_render_buffer_extension = { + .base = { __DRI_MUTABLE_RENDER_BUFFER_LOADER, 1 }, + .displaySharedBuffer = droid_display_shared_buffer, +}; + +static const __DRIextension *droid_image_loader_extensions[] = { + &droid_image_loader_extension.base, + &image_lookup_extension.base, + &use_invalidate.base, + &droid_mutable_render_buffer_extension.base, + NULL, +}; + +static EGLBoolean +droid_load_driver(_EGLDisplay *disp, bool swrast) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd); + if (dri2_dpy->driver_name == NULL) + return false; + +#ifdef HAVE_DRM_GRALLOC + /* Handle control nodes using __DRI_DRI2_LOADER extension and GEM names + * for backwards compatibility with drm_gralloc. (Do not use on new + * systems.) */ + dri2_dpy->loader_extensions = droid_dri2_loader_extensions; + if (!dri2_load_driver(disp)) { + goto error; + } +#else + if (swrast) { + /* Use kms swrast only with vgem / virtio_gpu. + * virtio-gpu fallbacks to software rendering when 3D features + * are unavailable since 6c5ab. + */ + if (strcmp(dri2_dpy->driver_name, "vgem") == 0 || + strcmp(dri2_dpy->driver_name, "virtio_gpu") == 0) { + free(dri2_dpy->driver_name); + dri2_dpy->driver_name = strdup("kms_swrast"); + } else { + goto error; + } + } + + dri2_dpy->loader_extensions = droid_image_loader_extensions; + if (!dri2_load_driver_dri3(disp)) { + goto error; + } +#endif + + return true; + +error: + free(dri2_dpy->driver_name); + dri2_dpy->driver_name = NULL; + return false; +} + +static void +droid_unload_driver(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + dlclose(dri2_dpy->driver); + dri2_dpy->driver = NULL; + free(dri2_dpy->driver_name); + dri2_dpy->driver_name = NULL; +} + +static int +droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor) +{ + drmVersionPtr ver = drmGetVersion(fd); + if (!ver) + return -1; + + if (strcmp(vendor, ver->name) != 0) { + drmFreeVersion(ver); + return -1; + } + + drmFreeVersion(ver); + return 0; +} + +static EGLBoolean +droid_probe_device(_EGLDisplay *disp, bool swrast) +{ + /* Check that the device is supported, by attempting to: + * - load the dri module + * - and, create a screen + */ + if (!droid_load_driver(disp, swrast)) + return EGL_FALSE; + + if (!dri2_create_screen(disp)) { + _eglLog(_EGL_WARNING, "DRI2: failed to create screen"); + droid_unload_driver(disp); + return EGL_FALSE; + } + return EGL_TRUE; +} + +#ifdef HAVE_DRM_GRALLOC +static EGLBoolean +droid_open_device(_EGLDisplay *disp, bool swrast) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + int fd = -1, err = -EINVAL; + + if (swrast) + return EGL_FALSE; + + if (dri2_dpy->gralloc->perform) + err = dri2_dpy->gralloc->perform(dri2_dpy->gralloc, + GRALLOC_MODULE_PERFORM_GET_DRM_FD, + &fd); + if (err || fd < 0) { + _eglLog(_EGL_WARNING, "fail to get drm fd"); + return EGL_FALSE; + } + + dri2_dpy->fd = os_dupfd_cloexec(fd); + if (dri2_dpy->fd < 0) + return EGL_FALSE; + + if (drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER) + return EGL_FALSE; + + return droid_probe_device(disp, swrast); +} +#else +static EGLBoolean +droid_open_device(_EGLDisplay *disp, bool swrast) +{ +#define MAX_DRM_DEVICES 64 + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + drmDevicePtr device, devices[MAX_DRM_DEVICES] = { NULL }; + int num_devices; + + char *vendor_name = NULL; + // char vendor_buf[PROPERTY_VALUE_MAX]; + +#ifdef EGL_FORCE_RENDERNODE + const unsigned node_type = DRM_NODE_RENDER; +#else + const unsigned node_type = swrast ? DRM_NODE_PRIMARY : DRM_NODE_RENDER; +#endif + + // if (property_get("drm.gpu.vendor_name", vendor_buf, NULL) > 0) + // vendor_name = vendor_buf; + + num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices)); + if (num_devices < 0) + return EGL_FALSE; + + for (int i = 0; i < num_devices; i++) { + device = devices[i]; + + if (!(device->available_nodes & (1 << node_type))) + continue; + + dri2_dpy->fd = loader_open_device(device->nodes[node_type]); + if (dri2_dpy->fd < 0) { + _eglLog(_EGL_WARNING, "%s() Failed to open DRM device %s", + __func__, device->nodes[node_type]); + continue; + } + + /* If a vendor is explicitly provided, we use only that. + * Otherwise we fall-back the first device that is supported. + */ + if (vendor_name) { + if (droid_filter_device(disp, dri2_dpy->fd, vendor_name)) { + /* Device does not match - try next device */ + close(dri2_dpy->fd); + dri2_dpy->fd = -1; + continue; + } + /* If the requested device matches - use it. Regardless if + * init fails, do not fall-back to any other device. + */ + if (!droid_probe_device(disp, false)) { + close(dri2_dpy->fd); + dri2_dpy->fd = -1; + } + + break; + } + if (droid_probe_device(disp, swrast)) + break; + + /* No explicit request - attempt the next device */ + close(dri2_dpy->fd); + dri2_dpy->fd = -1; + } + drmFreeDevices(devices, num_devices); + + if (dri2_dpy->fd < 0) { + _eglLog(_EGL_WARNING, "Failed to open %s DRM device", + vendor_name ? "desired": "any"); + return EGL_FALSE; + } + + return EGL_TRUE; +#undef MAX_DRM_DEVICES +} + +#endif + +EGLBoolean +dri2_initialize_ohos(_EGLDisplay *disp) +{ + _EGLDevice *dev; + bool device_opened = false; + struct dri2_egl_display *dri2_dpy; + const char *err; + + dri2_dpy = calloc(1, sizeof(*dri2_dpy)); + if (!dri2_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + dri2_dpy->fd = -1; + + disp->DriverData = (void *) dri2_dpy; + device_opened = droid_open_device(disp, disp->Options.ForceSoftware); + + if (!device_opened) { + err = "DRI2: failed to open device"; + goto cleanup; + } + + dev = _eglAddDevice(dri2_dpy->fd, false); + if (!dev) { + err = "DRI2: failed to find EGLDevice"; + goto cleanup; + } + + disp->Device = dev; + + if (!dri2_setup_extensions(disp)) { + err = "DRI2: failed to setup extensions"; + goto cleanup; + } + + dri2_setup_screen(disp); + + /* We set the maximum swap interval as 1 for Android platform, since it is + * the maximum value supported by Android according to the value of + * ANativeWindow::maxSwapInterval. + */ + dri2_setup_swap_interval(disp, 1); + + disp->Extensions.ANDROID_framebuffer_target = EGL_TRUE; + disp->Extensions.ANDROID_image_native_buffer = EGL_TRUE; + disp->Extensions.ANDROID_recordable = EGL_TRUE; + + /* Querying buffer age requires a buffer to be dequeued. Without + * EGL_ANDROID_native_fence_sync, dequeue might call eglClientWaitSync and + * result in a deadlock (the lock is already held by eglQuerySurface). + */ + if (disp->Extensions.ANDROID_native_fence_sync) { + disp->Extensions.EXT_buffer_age = EGL_TRUE; + } else { + /* disable KHR_partial_update that might have been enabled in + * dri2_setup_screen + */ + disp->Extensions.KHR_partial_update = EGL_FALSE; + } + + disp->Extensions.KHR_image = EGL_TRUE; + + /* Create configs *after* enabling extensions because presence of DRI + * driver extensions can affect the capabilities of EGLConfigs. + */ + if (!droid_add_configs_for_visuals(disp)) { + err = "DRI2: failed to add configs"; + goto cleanup; + } + + /* Fill vtbl last to prevent accidentally calling virtual function during + * initialization. + */ + dri2_dpy->vtbl = &droid_display_vtbl; + + return EGL_TRUE; + +cleanup: + dri2_display_destroy(disp); + return _eglError(EGL_NOT_INITIALIZED, err); +} diff --git a/src/egl/drivers/dri2/platform_ohos.h b/src/egl/drivers/dri2/platform_ohos.h new file mode 100644 index 00000000000..11d9cbbbaa5 --- /dev/null +++ b/src/egl/drivers/dri2/platform_ohos.h @@ -0,0 +1,108 @@ +/* + * 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"), + * 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 (including the next + * paragraph) 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. + */ + +#ifndef EGL_OHOS_INCLUDED +#define EGL_OHOS_INCLUDED + +#include +#include +#include + +#include + +#include "egl_dri2.h" +#include "display_type.h" +#include "window.h" + +#define ANativeWindow NativeWindow +#define ANativeWindowBuffer NativeWindowBuffer +static inline void +ANativeWindow_acquire(struct ANativeWindow *window) +{ + NativeObjectReference(window); +} + +static inline void +ANativeWindow_release(struct ANativeWindow *window) +{ + NativeObjectReference(window); +} + +static inline int32_t +ANativeWindow_getFormat(struct ANativeWindow *window) +{ + int32_t format = PIXEL_FMT_RGBA_8888; + int32_t res = NativeWindowHandleOpt(window, GET_FORMAT, &format); + return res == 0 ? format : res; +} + +static inline int32_t +ANativeWindow_dequeueBuffer(struct ANativeWindow *window, + struct ANativeWindowBuffer **buffer, + int *fenceFd) +{ + return NativeWindowRequestBuffer(window, buffer, fenceFd); +} + +static inline int32_t +ANativeWindow_queueBuffer(struct ANativeWindow *window, + struct ANativeWindowBuffer *buffer, + int fenceFd) +{ + struct Region dirty; + dirty.rectNumber = 0; + dirty.rects = NULL; + return NativeWindowFlushBuffer(window, buffer, fenceFd, dirty); +} + +static inline int32_t +ANativeWindow_cancelBuffer(struct ANativeWindow *window, + struct ANativeWindowBuffer *buffer, + int fenceFd) +{ + return NativeWindowCancelBuffer(window, buffer); +} + +static inline int32_t +ANativeWindow_setUsage(struct ANativeWindow *window, uint64_t usage) +{ + return NativeWindowHandleOpt(window, SET_USAGE, usage); +} + +struct buffer_info { + int width; + int height; + 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; +}; + +#endif /* EGL_OHOS_INCLUDED */ diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 437865df0fe..26f1764d0a7 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -412,6 +412,11 @@ _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display, case EGL_PLATFORM_ANDROID_KHR: disp = _eglGetAndroidDisplay(native_display, attrib_list); break; +#endif +#ifdef HAVE_OHOS_PLATFORM + case EGL_PLATFORM_OHOS_KHR: + disp = _eglGetOHOSDisplay(native_display, attrib_list); + break; #endif case EGL_PLATFORM_DEVICE_EXT: disp = _eglGetDeviceDisplay(native_display, attrib_list); diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 131fc22786f..175dcb51f81 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -67,7 +67,7 @@ #ifdef HAVE_WINDOWS_PLATFORM #include #endif - +#include "hilog_common.h" /** * Map build-system platform names to platform types. @@ -85,6 +85,7 @@ static const struct { { _EGL_PLATFORM_SURFACELESS, "surfaceless" }, { _EGL_PLATFORM_DEVICE, "device" }, { _EGL_PLATFORM_WINDOWS, "windows" }, + { _EGL_PLATFORM_OHOS, "openharmony" }, }; @@ -608,6 +609,23 @@ _eglGetAndroidDisplay(void *native_display, } #endif /* HAVE_ANDROID_PLATFORM */ +#ifdef HAVE_OHOS_PLATFORM +_EGLDisplay* +_eglGetOHOSDisplay(void *native_display, + const EGLAttrib *attrib_list) +{ + DISPLAY_LOGD(); + /* This platform recognizes no display attributes. */ + if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { + _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); + return NULL; + } + + return _eglFindDisplay(_EGL_PLATFORM_OHOS, native_display, + attrib_list); +} +#endif /* HAVE_OHOS_PLATFORM */ + _EGLDisplay* _eglGetDeviceDisplay(void *native_display, const EGLAttrib *attrib_list) diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 0ee06a487c0..fdd9956ab26 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -53,6 +53,7 @@ enum _egl_platform_type { _EGL_PLATFORM_SURFACELESS, _EGL_PLATFORM_DEVICE, _EGL_PLATFORM_WINDOWS, + _EGL_PLATFORM_OHOS, _EGL_NUM_PLATFORMS, _EGL_INVALID_PLATFORM = -1 @@ -329,6 +330,12 @@ _eglGetAndroidDisplay(void *native_display, const EGLAttrib *attrib_list); #endif +#ifdef HAVE_OHOS_PLATFORM +_EGLDisplay* +_eglGetOHOSDisplay(void *native_display, + const EGLAttrib *attrib_list); +#endif + _EGLDisplay* _eglGetDeviceDisplay(void *native_display, const EGLAttrib *attrib_list); diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c index 984dd5b1939..a9f5100090f 100644 --- a/src/egl/main/egllog.c +++ b/src/egl/main/egllog.c @@ -95,6 +95,7 @@ _eglDefaultLogger(EGLint level, const char *msg) #else fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg); #endif /* HAVE_ANDROID_PLATFORM */ + DISPLAY_LOGE("libEGL %{public}s: %{public}s\n", level_strings[level], msg); } @@ -146,11 +147,12 @@ _eglLog(EGLint level, const char *fmtStr, ...) int ret; /* one-time initialization; a little race here is fine */ + /* if (!logging.initialized) _eglInitLogger(); if (level > logging.level || level < 0) return; - + */ mtx_lock(&logging.mutex); va_start(args, fmtStr); diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h index 2a06a34684a..6928f62d78e 100644 --- a/src/egl/main/egllog.h +++ b/src/egl/main/egllog.h @@ -32,6 +32,7 @@ #include "egltypedefs.h" +#include "hilog_common.h" #ifdef __cplusplus diff --git a/src/egl/meson.build b/src/egl/meson.build index 65faf607705..b1df319c639 100644 --- a/src/egl/meson.build +++ b/src/egl/meson.build @@ -106,7 +106,7 @@ if with_dri2 endif deps_for_egl += [dep_x11_xcb, dep_xcb_dri2, dep_xcb_xfixes] endif - if with_gbm and not with_platform_android + if with_gbm and not with_platform_android and not with_platform_ohos files_egl += files('drivers/dri2/platform_drm.c') link_for_egl += libgbm incs_for_egl += [inc_gbm, include_directories('../gbm/main')] @@ -132,6 +132,12 @@ if with_dri2 cpp_args_for_egl += ['-std=c++17', '-DUSE_IMAPPER4_METADATA_API'] endif endif + + if with_platform_ohos + deps_for_egl += dep_ohos + files_egl += files('drivers/dri2/platform_ohos.c') + endif + elif with_platform_haiku incs_for_egl += inc_haikugl c_args_for_egl += [ -- Gitee From 28012fd25ba9401083b634ba36f19a3ff385ecd2 Mon Sep 17 00:00:00 2001 From: andrewhw Date: Sat, 26 Feb 2022 19:30:42 +0800 Subject: [PATCH 3/8] add build_ohos script Signed-off-by: andrewhw --- .gitignore | 4 ++- ohos/build_ohos.py | 36 +++++++++++++++++++++++++ ohos_cross.ini | 58 ----------------------------------------- pkgconfig/expat.pc | 10 ------- pkgconfig/libdrm.pc | 9 ------- pkgconfig/libhilog.pc | 8 ------ pkgconfig/libsurface.pc | 9 ------- pkgconfig/zlib.pc | 13 --------- 8 files changed, 39 insertions(+), 108 deletions(-) create mode 100644 ohos/build_ohos.py delete mode 100644 ohos_cross.ini delete mode 100644 pkgconfig/expat.pc delete mode 100644 pkgconfig/libdrm.pc delete mode 100644 pkgconfig/libhilog.pc delete mode 100644 pkgconfig/libsurface.pc delete mode 100644 pkgconfig/zlib.pc diff --git a/.gitignore b/.gitignore index 825ad5fd165..9d60df4c9f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.pyc *.pyo *.out -build +build-ohos +cross_file +pkgconfig/ diff --git a/ohos/build_ohos.py b/ohos/build_ohos.py new file mode 100644 index 00000000000..11ded623347 --- /dev/null +++ b/ohos/build_ohos.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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 expressor implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import sys +import ntpath +import os +if __name__ == '__main__': + if len(sys.argv) < 4: + print("must input the OpenHarmony directory and the product name and the source dir") + exit(-1) + script_dir = os.path.split(os.path.abspath( __file__))[0] + run_cross_pross_cmd = 'python3 ' + script_dir + '/meson_cross_process.py ' + sys.argv[1] + ' ' + sys.argv[2] + os.system(run_cross_pross_cmd) + + run_build_cmd = 'PKG_CONFIG_PATH=./pkgconfig ' + run_build_cmd += 'meson setup '+ sys.argv[3] + ' build-ohos ' + run_build_cmd += '-Dplatforms=ohos -Degl-native-platform=ohos -Ddri-drivers= -Dgallium-drivers=panfrost \ + -Dvulkan-drivers= -Dgbm=enabled -Degl=enabled -Dcpp_rtti=false -Dglx=disabled -Dtools=panfrost -Ddri-search-path=/system/lib ' + run_build_cmd += '--cross-file=cross_file ' + run_build_cmd += '--prefix=' + os.getcwd() + '/build-ohos/install' + print("build command: %s" %run_build_cmd) + os.system(run_build_cmd) + os.system('ninja -C build-ohos -j26') + os.system('ninja -C build-ohos install') diff --git a/ohos_cross.ini b/ohos_cross.ini deleted file mode 100644 index e9a149f6fa6..00000000000 --- a/ohos_cross.ini +++ /dev/null @@ -1,58 +0,0 @@ -[properties] - c_args = [ - '-march=armv7-a', - '-mfloat-abi=softfp', - '-mtune=generic-armv7-a', - '-mfpu=neon', - '-mthumb', - '-fPIC', - '--target=arm-linux-ohos', - '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', - ] - - cpp_args = [ - '-march=armv7-a', - '--target=arm-linux-ohos', - '-fPIC', - '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', - '-ftls-model=global-dynamic', - '-mtls-direct-seg-refs' - ] - - c_link_args = [ - '-march=armv7-a', - '--target=arm-linux-ohos', - '-fPIC', - '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', - '-L/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl/usr/lib/arm-linux-ohos', - '--rtlib=compiler-rt', - '-ftls-model=global-dynamic', - '-mtls-direct-seg-refs' - ] - - cpp_link_args = [ - '-march=armv7-a', - '--target=arm-linux-ohos', - '-fPIC', - '--sysroot=/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl', - '-L/home/andrew/OpenHarmony/out/rk3568/obj/third_party/musl/usr/lib/arm-linux-ohos', - '--rtlib=compiler-rt', - '-ftls-model=global-dynamic', - '-mtls-direct-seg-refs' - ] - needs_exe_wrapper = true - -[binaries] - ar = '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-ar' - c = ['ccache', '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang'] - cpp = ['ccache', '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++'] - c_ld= 'lld' - cpp_ld = 'lld' - strip = '/home/andrew/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-strip' - pkgconfig = ['env', 'PKG_CONFIG_LIBDIR=/home/andrew/OpenHarmony/third_party/mesa3d/pkgconfig', '/usr/bin/pkg-config'] - -[host_machine] - system = 'linux' - cpu_family = 'arm' - cpu = 'armv7' - endian = 'little' diff --git a/pkgconfig/expat.pc b/pkgconfig/expat.pc deleted file mode 100644 index a9830072399..00000000000 --- a/pkgconfig/expat.pc +++ /dev/null @@ -1,10 +0,0 @@ -ohos_project_dir=/home/andrew/OpenHarmony -libdir=${ohos_project_dir}/out/rk3568/obj/third_party/expat -includedir=${ohos_project_dir}/third_party/expat/lib - -Name: expat -Version: 2.4.1 -Description: expat XML parser -URL: http://www.libexpat.org -Libs: -L${libdir} -lexpat -Cflags: -I${includedir} \ No newline at end of file diff --git a/pkgconfig/libdrm.pc b/pkgconfig/libdrm.pc deleted file mode 100644 index 27830b55a48..00000000000 --- a/pkgconfig/libdrm.pc +++ /dev/null @@ -1,9 +0,0 @@ -ohos_project_dir=/home/andrew/OpenHarmony -libdir=${ohos_project_dir}/out/rk3568/graphic/graphic_standard/ -includedir=${ohos_project_dir}/third_party/libdrm - -Name: libdrm -Description: Userspace interface to kernel DRM services -Version: 2.4.102 -Libs: -L${libdir} -ldrm -Cflags: -I${includedir} -I${includedir}/include/drm/ \ No newline at end of file diff --git a/pkgconfig/libhilog.pc b/pkgconfig/libhilog.pc deleted file mode 100644 index d61af30104b..00000000000 --- a/pkgconfig/libhilog.pc +++ /dev/null @@ -1,8 +0,0 @@ -ohos_project_dir=/home/andrew/OpenHarmony -libdir=${ohos_project_dir}/out/rk3568/hiviewdfx/hilog_native -includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow - -Name: libhilog -Description: libhilog -Version: 2.4.1 -Libs: -L${libdir} -lhilog \ No newline at end of file diff --git a/pkgconfig/libsurface.pc b/pkgconfig/libsurface.pc deleted file mode 100644 index 9db4e0628a3..00000000000 --- a/pkgconfig/libsurface.pc +++ /dev/null @@ -1,9 +0,0 @@ -ohos_project_dir=/home/andrew/OpenHarmony -libdir=${ohos_project_dir}/out/rk3568/graphic/graphic_standard -includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow - -Name: libsurface -Version: 2.4.1 -Description: libsurface -Libs: -L${libdir} -lsurface.z -Cflags: -I${includedir} -I${ohos_project_dir}/drivers/peripheral/display/interfaces/include -I${ohos_project_dir}/drivers/peripheral/base \ No newline at end of file diff --git a/pkgconfig/zlib.pc b/pkgconfig/zlib.pc deleted file mode 100644 index 4f9245f3387..00000000000 --- a/pkgconfig/zlib.pc +++ /dev/null @@ -1,13 +0,0 @@ -prefix=/home/andrew/OpenHarmony -exec_prefix=${prefix} -libdir=${prefix}/out/rk3568/obj/third_party/zlib -sharedlibdir=${libdir} -includedir=${prefix}/third_party/zlib - -Name: zlib -Description: zlib compression library -Version: 1.2.12 - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -lz -Cflags: -I${includedir} \ No newline at end of file -- Gitee From 153d4334a100684e7983cb094be76f7ce033a37f Mon Sep 17 00:00:00 2001 From: andrewhw Date: Mon, 28 Feb 2022 17:48:06 +0800 Subject: [PATCH 4/8] fix codedex Signed-off-by: andrewhw --- ohos/build_ohos.py | 31 ++-- ohos/build_wayland_and_gbm.py | 32 ++-- ohos/hilog_common.h | 33 ++-- ohos/meson_cross_process.py | 50 +++--- src/egl/drivers/dri2/platform_ohos.c | 239 ++++++++++----------------- src/egl/drivers/dri2/platform_ohos.h | 4 + 6 files changed, 175 insertions(+), 214 deletions(-) diff --git a/ohos/build_ohos.py b/ohos/build_ohos.py index 11ded623347..8f2485922ed 100644 --- a/ohos/build_ohos.py +++ b/ohos/build_ohos.py @@ -1,18 +1,25 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2021 Huawei Device Co., Ltd. -# 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 expressor implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (c) 2022 Huawei Device Co., Ltd. + +# 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. import sys import ntpath import os diff --git a/ohos/build_wayland_and_gbm.py b/ohos/build_wayland_and_gbm.py index ab4b3f4fe88..a5ce071de3a 100644 --- a/ohos/build_wayland_and_gbm.py +++ b/ohos/build_wayland_and_gbm.py @@ -1,18 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2021 Huawei Device Co., Ltd. -# 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 expressor implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (c) 2022 Huawei Device Co., Ltd. + +# 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. + import sys import ntpath import os diff --git a/ohos/hilog_common.h b/ohos/hilog_common.h index f946b712309..07b48eee980 100644 --- a/ohos/hilog_common.h +++ b/ohos/hilog_common.h @@ -1,17 +1,24 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * 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. - */ +* Copyright (c) 2022 Huawei Device Co., Ltd. + +* 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. +*/ #ifndef HILOG_COMMON_H #define HILOG_COMMON_H diff --git a/ohos/meson_cross_process.py b/ohos/meson_cross_process.py index 36dc637b632..479ba685719 100644 --- a/ohos/meson_cross_process.py +++ b/ohos/meson_cross_process.py @@ -1,18 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2021 Huawei Device Co., Ltd. -# 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. +# Copyright (c) 2022 Huawei Device Co., Ltd. + +# 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. + import sys import ntpath import os @@ -82,10 +90,10 @@ cpu = 'armv7' endian = 'little' ''' -def generate_cross_file(project_stub, sysroot_stub): +def generate_cross_file(project_stub_in, sysroot_stub_in): with open("cross_file", 'w+') as file: - result = corss_file_content.replace("project_stub", project_stub) - result = result.replace("sysroot_stub", sysroot_stub) + result = corss_file_content.replace("project_stub", project_stub_in) + result = result.replace("sysroot_stub", sysroot_stub_in) file.write(result) print("generate_cross_file") @@ -95,19 +103,19 @@ def generate_pc_file(file_raw, project_dir, product_name): os.makedirs('pkgconfig') filename = 'pkgconfig/'+ ntpath.basename(file_raw) with open(file_raw, 'r+') as file_raw: - with open(filename, "w+") as file: + with open(filename, "w+") as pc_file: raw_content = file_raw.read() raw_content = raw_content.replace("ohos_project_directory_stub", project_dir) raw_content = raw_content.replace("ohos-arm-release", product_name) - file.write(raw_content) + pc_file.write(raw_content) print("generate_pc_file") def process_pkgconfig(project_dir, product_name): template_dir = os.path.split(os.path.abspath( __file__))[0] + r"/pkgconfig_template" - files = os.listdir(template_dir) - for file in files: - if not os.path.isdir(file): - generate_pc_file(template_dir + '/' + file, project_dir, product_name) + templates = os.listdir(template_dir) + for template in templates: + if not os.path.isdir(template): + generate_pc_file(template_dir + '/' + template, project_dir, product_name) print("process_pkgconfig") if __name__ == '__main__': diff --git a/src/egl/drivers/dri2/platform_ohos.c b/src/egl/drivers/dri2/platform_ohos.c index 5c840463c08..d45a62a2ce9 100644 --- a/src/egl/drivers/dri2/platform_ohos.c +++ b/src/egl/drivers/dri2/platform_ohos.c @@ -1,12 +1,16 @@ /* * Mesa 3-D graphics library * + * Copyright (c) 2021 Huawei Device Co., Ltd. + * + * Based on platform_android, which has + * * Copyright (C) 2010-2011 Chia-I Wu * Copyright (C) 2010-2011 LunarG Inc. * * Based on platform_x11, which has * - * Copyright © 2011 Intel Corporation + * Copyright (c) 2021 Huawei Device Co., Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -52,28 +56,6 @@ #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) -enum chroma_order { - YCbCr, - YCrCb, -}; - -struct droid_yuv_format { - /* Lookup keys */ - int native; /* PIXEL_FMT_ */ - enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */ - int chroma_step; /* Distance in bytes between subsequent chroma pixels. */ - - /* Result */ - int fourcc; /* DRM_FORMAT_ */ -}; - - -static bool -is_yuv(int native) -{ - return false; -} - static int get_format_bpp(int native) { @@ -100,11 +82,11 @@ get_format_bpp(int native) static unsigned get_native_buffer_fds(struct ANativeWindowBuffer *buf, int fds[3]) { - BufferHandle* handle = NULL; - handle = GetBufferHandleFromNative(buf); - fds[0] = handle->fd; - if (!handle) + BufferHandle* handle = GetBufferHandleFromNative(buf); + if (!handle) { + fds[0] = handle->fd; return 0; + } return 1; } @@ -174,7 +156,7 @@ native_window_buffer_get_buffer_info(struct dri2_egl_display *dri2_dpy, static __DRIimage * -droid_create_image_from_buffer_info(struct dri2_egl_display *dri2_dpy, +ohos_create_image_from_buffer_info(struct dri2_egl_display *dri2_dpy, struct buffer_info *buf_info, void *priv) { @@ -200,7 +182,7 @@ droid_create_image_from_buffer_info(struct dri2_egl_display *dri2_dpy, } static __DRIimage * -droid_create_image_from_native_buffer(_EGLDisplay *disp, +ohos_create_image_from_native_buffer(_EGLDisplay *disp, struct ANativeWindowBuffer *buf, void *priv) { @@ -215,14 +197,15 @@ droid_create_image_from_native_buffer(_EGLDisplay *disp, * buffer can be imported without modifier info as a last resort. */ - if (!img && !native_window_buffer_get_buffer_info(dri2_dpy, buf, &buf_info)) - img = droid_create_image_from_buffer_info(dri2_dpy, &buf_info, priv); + if (!native_window_buffer_get_buffer_info(dri2_dpy, buf, &buf_info)) { + img = ohos_create_image_from_buffer_info(dri2_dpy, &buf_info, priv); + } return img; } static EGLBoolean -droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) +ohos_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) { int fence_fd; @@ -287,12 +270,12 @@ droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) } static EGLBoolean -droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf) +ohos_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); /* To avoid blocking other EGL calls, release the display mutex before - * we enter droid_window_enqueue_buffer() and re-acquire the mutex upon + * we enter ohos_window_enqueue_buffer() and re-acquire the mutex upon * return. */ mtx_unlock(&disp->Mutex); @@ -325,7 +308,7 @@ droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_sur } static void -droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) +ohos_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) { int ret; int fence_fd = dri2_surf->out_fence_fd; @@ -341,7 +324,7 @@ droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) } static _EGLSurface * -droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, +ohos_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); @@ -352,7 +335,7 @@ droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { - _eglError(EGL_BAD_ALLOC, "droid_create_surface"); + _eglError(EGL_BAD_ALLOC, "ohos_create_surface"); return NULL; } @@ -366,7 +349,7 @@ droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, format = ANativeWindow_getFormat(window); if (format < 0) { - _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); + _eglError(EGL_BAD_NATIVE_WINDOW, "ohos_create_surface"); goto cleanup_surface; } @@ -377,7 +360,7 @@ droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, dri2_surf->color_buffers = calloc(buffer_count, sizeof(*dri2_surf->color_buffers)); if (!dri2_surf->color_buffers) { - _eglError(EGL_BAD_ALLOC, "droid_create_surface"); + _eglError(EGL_BAD_ALLOC, "ohos_create_surface"); goto cleanup_surface; } dri2_surf->color_buffers_count = buffer_count; @@ -416,23 +399,23 @@ cleanup_surface: } static _EGLSurface * -droid_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, +ohos_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { - return droid_create_surface(disp, EGL_WINDOW_BIT, conf, + return ohos_create_surface(disp, EGL_WINDOW_BIT, conf, native_window, attrib_list); } static _EGLSurface * -droid_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, +ohos_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, const EGLint *attrib_list) { - return droid_create_surface(disp, EGL_PBUFFER_BIT, conf, + return ohos_create_surface(disp, EGL_PBUFFER_BIT, conf, NULL, attrib_list); } static EGLBoolean -droid_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) +ohos_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); @@ -441,7 +424,7 @@ droid_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->buffer) - droid_window_cancel_buffer(dri2_surf); + ohos_window_cancel_buffer(dri2_surf); ANativeWindow_release(dri2_surf->window); } @@ -477,7 +460,7 @@ update_buffers(struct dri2_egl_surface *dri2_surf) return 0; /* try to dequeue the next back buffer */ - if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) { + if (!dri2_surf->buffer && !ohos_window_dequeue_buffer(dri2_surf)) { _eglLog(_EGL_WARNING, "Could not dequeue buffer from native window"); dri2_surf->base.Lost = EGL_TRUE; return -1; @@ -542,7 +525,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) } dri2_surf->dri_image_back = - droid_create_image_from_native_buffer(disp, dri2_surf->buffer, NULL); + ohos_create_image_from_native_buffer(disp, dri2_surf->buffer, NULL); if (!dri2_surf->dri_image_back) { _eglLog(_EGL_WARNING, "failed to create DRI image from FD"); return -1; @@ -573,7 +556,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) * return error when the allocation for supported buffer failed. */ static int -droid_image_get_buffers(__DRIdrawable *driDrawable, +ohos_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, uint32_t *stamp, void *loaderPrivate, @@ -628,12 +611,12 @@ droid_image_get_buffers(__DRIdrawable *driDrawable, } static EGLint -droid_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) +ohos_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) { struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); if (update_buffers(dri2_surf) < 0) { - _eglError(EGL_BAD_ALLOC, "droid_query_buffer_age"); + _eglError(EGL_BAD_ALLOC, "ohos_query_buffer_age"); return -1; } @@ -641,7 +624,7 @@ droid_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) } static EGLBoolean -droid_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) +ohos_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); @@ -680,7 +663,7 @@ droid_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) * dri2_surf->buffer remains null. */ if (dri2_surf->buffer) - droid_window_enqueue_buffer(disp, dri2_surf); + ohos_window_enqueue_buffer(disp, dri2_surf); dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); @@ -688,7 +671,7 @@ droid_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) } static EGLBoolean -droid_query_surface(_EGLDisplay *disp, _EGLSurface *surf, +ohos_query_surface(_EGLDisplay *disp, _EGLSurface *surf, EGLint attribute, EGLint *value) { struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); @@ -720,9 +703,9 @@ dri2_create_image_ohos_native_buffer(_EGLDisplay *disp, struct ANativeWindowBuffer *buf) { if (ctx != NULL) { - /* From the EGL_ANDROID_image_native_buffer spec: + /* From the EGL_OHOS_image_native_buffer spec: * - * * If is EGL_NATIVE_BUFFER_ANDROID and is not + * * If is EGL_NATIVE_BUFFER_OHOS and is not * EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated. */ _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for " @@ -731,13 +714,7 @@ dri2_create_image_ohos_native_buffer(_EGLDisplay *disp, return NULL; } __DRIimage *dri_image = - droid_create_image_from_native_buffer(disp, buf, buf); - -// [TODO] -// #ifdef HAVE_DRM_GRALLOC -// if (dri_image == NULL) -// dri_image = droid_create_image_from_name(disp, buf, buf); -// #endif + ohos_create_image_from_native_buffer(disp, buf, buf); if (dri_image) { return dri2_create_image_from_dri(disp, dri_image); @@ -747,7 +724,7 @@ dri2_create_image_ohos_native_buffer(_EGLDisplay *disp, } static _EGLImage * -droid_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, +ohos_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { switch (target) { @@ -760,13 +737,13 @@ droid_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, } static void -droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) +ohos_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) { } #ifdef HAVE_DRM_GRALLOC static int -droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, +ohos_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, unsigned int *attachments, int count) { int num_buffers = 0; @@ -821,7 +798,7 @@ droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, } static __DRIbuffer * -droid_get_buffers_with_format(__DRIdrawable * driDrawable, +ohos_get_buffers_with_format(__DRIdrawable * driDrawable, int *width, int *height, unsigned int *attachments, int count, int *out_count, void *loaderPrivate) @@ -831,7 +808,7 @@ droid_get_buffers_with_format(__DRIdrawable * driDrawable, if (update_buffers(dri2_surf) < 0) return NULL; - *out_count = droid_get_buffers_parse_attachments(dri2_surf, attachments, count); + *out_count = ohos_get_buffers_parse_attachments(dri2_surf, attachments, count); if (width) *width = dri2_surf->base.Width; @@ -843,7 +820,7 @@ droid_get_buffers_with_format(__DRIdrawable * driDrawable, #endif /* HAVE_DRM_GRALLOC */ static unsigned -droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap) +ohos_get_capability(void *loaderPrivate, enum dri_loader_cap cap) { /* Note: loaderPrivate is _EGLDisplay* */ switch (cap) { @@ -855,18 +832,12 @@ droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap) } static void -droid_destroy_loader_image_state(void *loaderPrivate) +ohos_destroy_loader_image_state(void *loaderPrivate) { -#if ANDROID_API_LEVEL >= 26 - if (loaderPrivate) { - AHardwareBuffer_release( - ANativeWindowBuffer_getHardwareBuffer(loaderPrivate)); - } -#endif } static EGLBoolean -droid_add_configs_for_visuals(_EGLDisplay *disp) +ohos_add_configs_for_visuals(_EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); static const struct { @@ -886,29 +857,8 @@ droid_add_configs_for_visuals(_EGLDisplay *disp) unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 }; int config_count = 0; - /* The nesting of loops is significant here. Also significant is the order - * of the HAL pixel formats. Many Android apps (such as Google's official - * NDK GLES2 example app), and even portions the core framework code (such - * as SystemServiceManager in Nougat), incorrectly choose their EGLConfig. - * They neglect to match the EGLConfig's EGL_NATIVE_VISUAL_ID against the - * window's native format, and instead choose the first EGLConfig whose - * channel sizes match those of the native window format while ignoring the - * channel *ordering*. - * - * We can detect such buggy clients in logcat when they call - * eglCreateSurface, by detecting the mismatch between the EGLConfig's - * format and the window's format. - * - * As a workaround, we generate EGLConfigs such that all EGLConfigs for HAL - * pixel format i precede those for HAL pixel format i+1. In my - * (chadversary) testing on Android Nougat, this was good enough to pacify - * the buggy clients. - */ bool has_rgba = false; for (int i = 0; i < ARRAY_SIZE(visuals); i++) { - /* Only enable BGRA configs when RGBA is not available. BGRA configs are - * buggy on stock Android. - */ if (visuals[i].format == PIXEL_FMT_BGRA_8888 && has_rgba) continue; for (int j = 0; dri2_dpy->driver_configs[j]; j++) { @@ -917,8 +867,6 @@ droid_add_configs_for_visuals(_EGLDisplay *disp) const EGLint config_attrs[] = { EGL_NATIVE_VISUAL_ID, visuals[i].format, EGL_NATIVE_VISUAL_TYPE, visuals[i].format, - EGL_FRAMEBUFFER_TARGET_ANDROID, EGL_TRUE, - EGL_RECORDABLE_ANDROID, EGL_TRUE, EGL_NONE }; @@ -946,31 +894,31 @@ droid_add_configs_for_visuals(_EGLDisplay *disp) return (config_count != 0); } -static const struct dri2_egl_display_vtbl droid_display_vtbl = { +static const struct dri2_egl_display_vtbl ohos_display_vtbl = { .authenticate = NULL, - .create_window_surface = droid_create_window_surface, - .create_pbuffer_surface = droid_create_pbuffer_surface, - .destroy_surface = droid_destroy_surface, - .create_image = droid_create_image_khr, - .swap_buffers = droid_swap_buffers, + .create_window_surface = ohos_create_window_surface, + .create_pbuffer_surface = ohos_create_pbuffer_surface, + .destroy_surface = ohos_destroy_surface, + .create_image = ohos_create_image_khr, + .swap_buffers = ohos_swap_buffers, .swap_interval = NULL, - .query_buffer_age = droid_query_buffer_age, - .query_surface = droid_query_surface, + .query_buffer_age = ohos_query_buffer_age, + .query_surface = ohos_query_surface, .get_dri_drawable = dri2_surface_get_dri_drawable, }; -static const __DRIimageLoaderExtension droid_image_loader_extension = { +static const __DRIimageLoaderExtension ohos_image_loader_extension = { .base = { __DRI_IMAGE_LOADER, 4 }, - .getBuffers = droid_image_get_buffers, - .flushFrontBuffer = droid_flush_front_buffer, - .getCapability = droid_get_capability, + .getBuffers = ohos_image_get_buffers, + .flushFrontBuffer = ohos_flush_front_buffer, + .getCapability = ohos_get_capability, .flushSwapBuffers = NULL, - .destroyLoaderImageState = droid_destroy_loader_image_state, + .destroyLoaderImageState = ohos_destroy_loader_image_state, }; static void -droid_display_shared_buffer(__DRIdrawable *driDrawable, int fence_fd, +ohos_display_shared_buffer(__DRIdrawable *driDrawable, int fence_fd, void *loaderPrivate) { struct dri2_egl_surface *dri2_surf = loaderPrivate; @@ -1040,21 +988,21 @@ droid_display_shared_buffer(__DRIdrawable *driDrawable, int fence_fd, close(fence_fd); } -static const __DRImutableRenderBufferLoaderExtension droid_mutable_render_buffer_extension = { +static const __DRImutableRenderBufferLoaderExtension ohos_mutable_render_buffer_extension = { .base = { __DRI_MUTABLE_RENDER_BUFFER_LOADER, 1 }, - .displaySharedBuffer = droid_display_shared_buffer, + .displaySharedBuffer = ohos_display_shared_buffer, }; -static const __DRIextension *droid_image_loader_extensions[] = { - &droid_image_loader_extension.base, +static const __DRIextension *ohos_image_loader_extensions[] = { + &ohos_image_loader_extension.base, &image_lookup_extension.base, &use_invalidate.base, - &droid_mutable_render_buffer_extension.base, + &ohos_mutable_render_buffer_extension.base, NULL, }; static EGLBoolean -droid_load_driver(_EGLDisplay *disp, bool swrast) +ohos_load_driver(_EGLDisplay *disp, bool swrast) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); @@ -1066,7 +1014,7 @@ droid_load_driver(_EGLDisplay *disp, bool swrast) /* Handle control nodes using __DRI_DRI2_LOADER extension and GEM names * for backwards compatibility with drm_gralloc. (Do not use on new * systems.) */ - dri2_dpy->loader_extensions = droid_dri2_loader_extensions; + dri2_dpy->loader_extensions = ohos_dri2_loader_extensions; if (!dri2_load_driver(disp)) { goto error; } @@ -1085,7 +1033,7 @@ droid_load_driver(_EGLDisplay *disp, bool swrast) } } - dri2_dpy->loader_extensions = droid_image_loader_extensions; + dri2_dpy->loader_extensions = ohos_image_loader_extensions; if (!dri2_load_driver_dri3(disp)) { goto error; } @@ -1100,7 +1048,7 @@ error: } static void -droid_unload_driver(_EGLDisplay *disp) +ohos_unload_driver(_EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); @@ -1111,7 +1059,7 @@ droid_unload_driver(_EGLDisplay *disp) } static int -droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor) +ohos_filter_device(_EGLDisplay *disp, int fd, const char *vendor) { drmVersionPtr ver = drmGetVersion(fd); if (!ver) @@ -1127,18 +1075,18 @@ droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor) } static EGLBoolean -droid_probe_device(_EGLDisplay *disp, bool swrast) +ohos_probe_device(_EGLDisplay *disp, bool swrast) { /* Check that the device is supported, by attempting to: * - load the dri module * - and, create a screen */ - if (!droid_load_driver(disp, swrast)) + if (!ohos_load_driver(disp, swrast)) return EGL_FALSE; if (!dri2_create_screen(disp)) { _eglLog(_EGL_WARNING, "DRI2: failed to create screen"); - droid_unload_driver(disp); + ohos_unload_driver(disp); return EGL_FALSE; } return EGL_TRUE; @@ -1146,7 +1094,7 @@ droid_probe_device(_EGLDisplay *disp, bool swrast) #ifdef HAVE_DRM_GRALLOC static EGLBoolean -droid_open_device(_EGLDisplay *disp, bool swrast) +ohos_open_device(_EGLDisplay *disp, bool swrast) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); int fd = -1, err = -EINVAL; @@ -1170,11 +1118,11 @@ droid_open_device(_EGLDisplay *disp, bool swrast) if (drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER) return EGL_FALSE; - return droid_probe_device(disp, swrast); + return ohos_probe_device(disp, swrast); } #else static EGLBoolean -droid_open_device(_EGLDisplay *disp, bool swrast) +ohos_open_device(_EGLDisplay *disp, bool swrast) { #define MAX_DRM_DEVICES 64 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); @@ -1214,7 +1162,7 @@ droid_open_device(_EGLDisplay *disp, bool swrast) * Otherwise we fall-back the first device that is supported. */ if (vendor_name) { - if (droid_filter_device(disp, dri2_dpy->fd, vendor_name)) { + if (ohos_filter_device(disp, dri2_dpy->fd, vendor_name)) { /* Device does not match - try next device */ close(dri2_dpy->fd); dri2_dpy->fd = -1; @@ -1223,14 +1171,14 @@ droid_open_device(_EGLDisplay *disp, bool swrast) /* If the requested device matches - use it. Regardless if * init fails, do not fall-back to any other device. */ - if (!droid_probe_device(disp, false)) { + if (!ohos_probe_device(disp, false)) { close(dri2_dpy->fd); dri2_dpy->fd = -1; } break; } - if (droid_probe_device(disp, swrast)) + if (ohos_probe_device(disp, swrast)) break; /* No explicit request - attempt the next device */ @@ -1266,7 +1214,7 @@ dri2_initialize_ohos(_EGLDisplay *disp) dri2_dpy->fd = -1; disp->DriverData = (void *) dri2_dpy; - device_opened = droid_open_device(disp, disp->Options.ForceSoftware); + device_opened = ohos_open_device(disp, disp->Options.ForceSoftware); if (!device_opened) { err = "DRI2: failed to open device"; @@ -1288,35 +1236,14 @@ dri2_initialize_ohos(_EGLDisplay *disp) dri2_setup_screen(disp); - /* We set the maximum swap interval as 1 for Android platform, since it is - * the maximum value supported by Android according to the value of - * ANativeWindow::maxSwapInterval. - */ dri2_setup_swap_interval(disp, 1); - disp->Extensions.ANDROID_framebuffer_target = EGL_TRUE; - disp->Extensions.ANDROID_image_native_buffer = EGL_TRUE; - disp->Extensions.ANDROID_recordable = EGL_TRUE; - - /* Querying buffer age requires a buffer to be dequeued. Without - * EGL_ANDROID_native_fence_sync, dequeue might call eglClientWaitSync and - * result in a deadlock (the lock is already held by eglQuerySurface). - */ - if (disp->Extensions.ANDROID_native_fence_sync) { - disp->Extensions.EXT_buffer_age = EGL_TRUE; - } else { - /* disable KHR_partial_update that might have been enabled in - * dri2_setup_screen - */ - disp->Extensions.KHR_partial_update = EGL_FALSE; - } - disp->Extensions.KHR_image = EGL_TRUE; /* Create configs *after* enabling extensions because presence of DRI * driver extensions can affect the capabilities of EGLConfigs. */ - if (!droid_add_configs_for_visuals(disp)) { + if (!ohos_add_configs_for_visuals(disp)) { err = "DRI2: failed to add configs"; goto cleanup; } @@ -1324,7 +1251,7 @@ dri2_initialize_ohos(_EGLDisplay *disp) /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ - dri2_dpy->vtbl = &droid_display_vtbl; + dri2_dpy->vtbl = &ohos_display_vtbl; return EGL_TRUE; diff --git a/src/egl/drivers/dri2/platform_ohos.h b/src/egl/drivers/dri2/platform_ohos.h index 11d9cbbbaa5..dfec8bd38a7 100644 --- a/src/egl/drivers/dri2/platform_ohos.h +++ b/src/egl/drivers/dri2/platform_ohos.h @@ -1,4 +1,8 @@ /* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * + * Based on platform_android, which has + * * Copyright © 2021, Google Inc. * Copyright (C) 2021, GlobalLogic Ukraine * -- Gitee From 46f8d7e73af9d8268a3890895015c6a961f76f49 Mon Sep 17 00:00:00 2001 From: andrewhw Date: Wed, 16 Mar 2022 14:48:59 +0800 Subject: [PATCH 5/8] add template for libsurface and hilog Signed-off-by: andrewhw --- ohos/pkgconfig_template/libhilog.pc | 8 ++++++++ ohos/pkgconfig_template/libsurface.pc | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 ohos/pkgconfig_template/libhilog.pc create mode 100644 ohos/pkgconfig_template/libsurface.pc diff --git a/ohos/pkgconfig_template/libhilog.pc b/ohos/pkgconfig_template/libhilog.pc new file mode 100644 index 00000000000..68d36cb4b2c --- /dev/null +++ b/ohos/pkgconfig_template/libhilog.pc @@ -0,0 +1,8 @@ +ohos_project_dir=ohos_project_directory_stub +libdir=${ohos_project_dir}/out/ohos-arm-release/hiviewdfx/hilog_native +includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow + +Name: libhilog +Version: 2.4.1 +Description: libhilog +Libs: -L${libdir} -lhilog diff --git a/ohos/pkgconfig_template/libsurface.pc b/ohos/pkgconfig_template/libsurface.pc new file mode 100644 index 00000000000..63a4c60121a --- /dev/null +++ b/ohos/pkgconfig_template/libsurface.pc @@ -0,0 +1,9 @@ +ohos_project_dir=ohos_project_directory_stub +libdir=${ohos_project_dir}/out/ohos-arm-release/graphic/graphic_standard/ +includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow + +Name: libsurface +Version: 2.4.1 +Description: libsurface +Libs: -L${libdir} -lsurface.z +Cflags: -I${includedir} -I${ohos_project_dir}/drivers/peripheral/display/interfaces/include -I${ohos_project_dir}/drivers/peripheral/base -- Gitee From a299f7997526ed191ae77f5f30944431045f3a78 Mon Sep 17 00:00:00 2001 From: andrewhw Date: Wed, 16 Mar 2022 14:54:24 +0800 Subject: [PATCH 6/8] remove hilog Signed-off-by: andrewhw --- meson.build | 1 - ohos/hilog_common.h | 209 -------------------------------------- src/egl/main/egldisplay.c | 2 - src/egl/main/egllog.c | 1 - src/egl/main/egllog.h | 1 - 5 files changed, 214 deletions(-) delete mode 100644 ohos/hilog_common.h diff --git a/meson.build b/meson.build index 4a0ca4bbedb..2f66354ee0d 100644 --- a/meson.build +++ b/meson.build @@ -964,7 +964,6 @@ if with_platform_ohos pre_args += '-DHAVE_OHOS_PLATFORM' dep_ohos = [ dependency('libsurface'), - dependency('libhilog') ] c_args += '-I../ohos' endif diff --git a/ohos/hilog_common.h b/ohos/hilog_common.h deleted file mode 100644 index 07b48eee980..00000000000 --- a/ohos/hilog_common.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -* Copyright (c) 2022 Huawei Device Co., Ltd. - -* 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. -*/ - -#ifndef HILOG_COMMON_H -#define HILOG_COMMON_H - -#ifndef HIVIEWDFX_HILOG_C_H -#define HIVIEWDFX_HILOG_C_H -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LOG_DOMAIN -#define LOG_DOMAIN 0 -#endif - -#ifndef LOG_TAG -#define LOG_TAG NULL -#endif - -typedef enum { - LOG_TYPE_MIN = 0, - LOG_APP = 0, - LOG_INIT = 1, - LOG_CORE = 3, - LOG_TYPE_MAX -} LogType; - -typedef enum { - /** Debug level to be used by {@link HILOG_DEBUG} */ - LOG_DEBUG = 3, - /** Informational level to be used by {@link HILOG_INFO} */ - LOG_INFORMATION = 4, - /** Warning level to be used by {@link HILOG_WARN} */ - LOG_WARN = 5, - /** Error level to be used by {@link HILOG_ERROR} */ - LOG_ERROR = 6, - /** Fatal level to be used by {@link HILOG_FATAL} */ - LOG_FATAL = 7, - LOG_LEVEL_MAX -} LogLevel; - -int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...) - __attribute__((__format__(os_log, 5, 6))); - -#ifndef USE_MUSL -#define HILOG_DEBUG(type, ...) ((void)HiLogPrint((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) -#else -#define HILOG_DEBUG(type, ...) -#endif - -#ifndef USE_MUSL -#define HILOG_INFO(type, ...) ((void)HiLogPrint((type), LOG_INFORMATION, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) -#else -#define HILOG_INFO(type, ...) -#endif - -#ifndef USE_MUSL -#define HILOG_WARN(type, ...) ((void)HiLogPrint((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) -#else -#define HILOG_WARN(type, ...) -#endif - -#ifndef USE_MUSL -#define HILOG_ERROR(type, ...) ((void)HiLogPrint((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) -#else -#define HILOG_ERROR(type, ...) -#endif - -#ifndef USE_MUSL -#define HILOG_FATAL(type, ...) ((void)HiLogPrint((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) -#else -#define HILOG_FATAL(type, ...) -#endif - -bool HiLogIsLoggable(unsigned int domain, const char *tag, LogLevel level); - -#ifdef __cplusplus -} -#endif -/** @} */ -#endif // HIVIEWDFX_HILOG_C_H - - - -#include -#include -#include "stdio.h" -#ifdef HDF_LOG_TAG -#undef HDF_LOG_TAG -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -#undef LOG_TAG -#undef LOG_DOMAIN -#define LOG_TAG "GPU_MESA" -#define LOG_DOMAIN 0xD001400 - -#ifndef DISPLAY_UNUSED -#define DISPLAY_UNUSED(x) (void)x -#endif - -#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__) - -#ifndef DISPLAY_LOGD -#define DISPLAY_LOGD(format, ...) \ - do { \ - HILOG_DEBUG(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \ - ##__VA_ARGS__); \ - } while (0) -#endif - -#ifndef DISPLAY_LOGI -#define DISPLAY_LOGI(format, ...) \ - do { \ - HILOG_INFO(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \ - ##__VA_ARGS__); \ - } while (0) -#endif - -#ifndef DISPLAY_LOGW -#define DISPLAY_LOGW(format, ...) \ - do { \ - HILOG_WARN(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \ - ##__VA_ARGS__); \ - } while (0) -#endif - -#ifndef DISPLAY_LOGE -#define DISPLAY_LOGE(format, ...) \ - do { \ - HILOG_ERROR(LOG_CORE, \ - "\033[0;32;31m" \ - "[%{public}s@%{public}s:%{public}d] " format "\033[m" \ - "\n", \ - __FUNCTION__, __FILENAME__, __LINE__, ##__VA_ARGS__); \ - } while (0) -#endif - -#ifndef CHECK_NULLPOINTER_RETURN_VALUE -#define CHECK_NULLPOINTER_RETURN_VALUE(pointer, ret) \ - do { \ - if ((pointer) == NULL) { \ - DISPLAY_LOGE("pointer is null and return ret\n"); \ - return (ret); \ - } \ - } while (0) -#endif - -#ifndef CHECK_NULLPOINTER_RETURN -#define CHECK_NULLPOINTER_RETURN(pointer) \ - do { \ - if ((pointer) == NULL) { \ - DISPLAY_LOGE("pointer is null and return\n"); \ - return; \ - } \ - } while (0) -#endif - -#ifndef DISPLAY_CHK_RETURN -#define DISPLAY_CHK_RETURN(val, ret, ...) \ - do { \ - if (val) { \ - __VA_ARGS__; \ - return (ret); \ - } \ - } while (0) -#endif - -#ifndef DISPLAY_CHK_RETURN_NOT_VALUE -#define DISPLAY_CHK_RETURN_NOT_VALUE(val, ret, ...) \ - do { \ - if (val) { \ - __VA_ARGS__; \ - return; \ - } \ - } while (0) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* DISP_COMMON_H */ \ No newline at end of file diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 175dcb51f81..bc612219195 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -67,7 +67,6 @@ #ifdef HAVE_WINDOWS_PLATFORM #include #endif -#include "hilog_common.h" /** * Map build-system platform names to platform types. @@ -614,7 +613,6 @@ _EGLDisplay* _eglGetOHOSDisplay(void *native_display, const EGLAttrib *attrib_list) { - DISPLAY_LOGD(); /* This platform recognizes no display attributes. */ if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c index a9f5100090f..49ab4e15bdf 100644 --- a/src/egl/main/egllog.c +++ b/src/egl/main/egllog.c @@ -95,7 +95,6 @@ _eglDefaultLogger(EGLint level, const char *msg) #else fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg); #endif /* HAVE_ANDROID_PLATFORM */ - DISPLAY_LOGE("libEGL %{public}s: %{public}s\n", level_strings[level], msg); } diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h index 6928f62d78e..2a06a34684a 100644 --- a/src/egl/main/egllog.h +++ b/src/egl/main/egllog.h @@ -32,7 +32,6 @@ #include "egltypedefs.h" -#include "hilog_common.h" #ifdef __cplusplus -- Gitee From b889f4cd8a2d48f348cdd3a132989e12a07a3b8a Mon Sep 17 00:00:00 2001 From: andrewhw Date: Mon, 21 Mar 2022 11:15:07 +0800 Subject: [PATCH 7/8] fix License Signed-off-by: andrewhw --- src/egl/drivers/dri2/platform_ohos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/egl/drivers/dri2/platform_ohos.c b/src/egl/drivers/dri2/platform_ohos.c index d45a62a2ce9..2c8cd4813f5 100644 --- a/src/egl/drivers/dri2/platform_ohos.c +++ b/src/egl/drivers/dri2/platform_ohos.c @@ -1,7 +1,7 @@ /* * Mesa 3-D graphics library * - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021 Huawei Device Co., Ltd. * * * Based on platform_android, which has * @@ -10,7 +10,7 @@ * * Based on platform_x11, which has * - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright © 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), -- Gitee From aa2689b9182013a99876a4ec0d664d5dfc747d4f Mon Sep 17 00:00:00 2001 From: andrewhw Date: Mon, 21 Mar 2022 11:51:12 +0800 Subject: [PATCH 8/8] fix null handle Signed-off-by: andrewhw --- src/egl/drivers/dri2/platform_ohos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/egl/drivers/dri2/platform_ohos.c b/src/egl/drivers/dri2/platform_ohos.c index 2c8cd4813f5..bde66d70892 100644 --- a/src/egl/drivers/dri2/platform_ohos.c +++ b/src/egl/drivers/dri2/platform_ohos.c @@ -83,10 +83,11 @@ static unsigned get_native_buffer_fds(struct ANativeWindowBuffer *buf, int fds[3]) { BufferHandle* handle = GetBufferHandleFromNative(buf); - if (!handle) { - fds[0] = handle->fd; + if (handle == NULL) { return 0; } + + fds[0] = handle->fd; return 1; } -- Gitee