草庐IT

OpenHarmony富设备移植指南—开源GPU驱动编译

Diemit 2023-03-28 原文

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

在OpenHarmony的各部件适配中,GPU适配是公认的最难,首先原厂安卓的驱动是没办法用的,后来又因为OpenHarmony3.1开始启用了自研的Rosen合成框架取代了Weston合成框架,原来能直接用的开源图形驱动现在也不能直接用了,新版的OpenHarmony需要图形驱动要额外对接OpenHarmony的接口,采用闭源驱动要得到原厂的支持,这个目前走不通,所以第三方设备要启用GPU加速只能选择采用开源的Mesa3d驱动,所幸OpenHarmony提供了一份mesa3d的参考实现,也能使OpenHarmony流畅丝滑了,这篇文章我打算分享一下我移植适配GPU的相关经验,希望能帮到大家。

同时在此说明一下,这些知识基本都是我在网上自学得来,不是图形专家,没有深入学习过图形方面的知识,对某些图形的专业名词或者某些概念可能会用词不准确或者解释错误,请大家谅解。

1、OpenHarmony图形显示移植适配思路

首先借用一张OpenHarmony图形能力的视图,我们可以了解到目前OpenHarmony当前以及未来支持的能力情况。

之前我们点亮屏幕采用的是CPU合成+CPU渲染的技术路径,在【2022.3】的时候开始支持的,同时采用OpenGLES接口的GPU合成+GPU渲染也在3.2Beta4【2022.12】的时候实现了,基于这个版本才能实现完整的GPU加速,可以期待一下【2023.9】基于Vulkan接口的GPU加速。

经过上面简单介绍,可能大家对GPU图形适配还是毫无头绪,因为这是在引申图形适配的一些前置知识,在此我简单总结一下适配OH图形需要关注两个大点:合成和渲染,下面是简单的解释。

1.合成:计算处理图层叠加关系。

2.渲染:生成需要显示的色彩数据(buffer)。

以上是我的个人总结,可能不准确,大致先这样分,这样后面好进行讲解移植适配的思路。

下面进入正题,因为移植GPU比较复杂,不可能一部到位,在此我拆开进行逐步实现,以便出现问题时能快速定位问题点出现在哪一部分,拆分思路如下:

1.不启用GPU功能,在CPU合成+CPU渲染的环境下,确认GPU驱动正常工作

2.启用部分GPU功能,在CPU合成+GPU渲染的环境下,确认GPU能正确渲染

3.启用GPU合成+GPU渲染,加速OpenHarmony图形显示

2、编译开源GPU驱动Mesa3d

(1)编译mesa3d

安装依赖

首先安装编译需要的依赖:

sudo apt-get install -y meson cmake llvm
python3 -m pip install meson==0.62.0
python -m pip install --upgrade pip
pip install mako atomic markupsafe

版本变更失效路径修正

OpenHarmony源码中以及带有适配过的mesa3d库,但是因为长时间没有维护,部分配置需要更新:

ohos/pkgconfig_template/gbm.pc。

libdir=${ohos_project_dir}/device/rockchip/hardware/gpu
includedir=${ohos_project_dir}/device/rockchip/hardware/gpu/include
Cflags: -I${ohos_project_dir}/device/rockchip/hardware/gpu/include

替换为:

libdir=${ohos_project_dir}/device/soc/qualcomm/msm8998/hardware/gpu
includedir=${ohos_project_dir}/device/soc/qualcomm/msm8998/hardware/gpu/include
Cflags: -I${ohos_project_dir}/device/soc/qualcomm/msm8998/hardware/gpu/include
ohos/pkgconfig_template/libdrm.pc。

libdir=${ohos_project_dir}/out/ohos-arm-release/graphic/graphic_standard/
修正为:
libdir=${ohos_project_dir}/out/ohos-arm-release/thirdparty/libdrm/
ohos/pkgconfig_template/libhilog.pc。

includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow
修正为:
includedir=${ohos_project_dir}/base/hiviewdfx/hilog/interfaces/native/innerkits/include
ohos/pkgconfig_template/libjpeg.pc。

libdir=${ohos_project_dir}/out/ohos-arm-release/obj/third_party/libjpeg/
includedir=${ohos_project_dir}/third_party/libjpeg
Libs: -L${libdir} -ljpeg_static

修正为:

libdir=${ohos_project_dir}/out/ohos-arm-release/obj/third_party/libjpeg-turbo/
includedir=${ohos_project_dir}/third_party/libjpeg-turbo
Libs: -L${libdir} -llibturbojpeg_static
ohos/pkgconfig_template/libpng.pc。

libdir=${ohos_project_dir}/out/ohos-arm-release/common/graphic_standard/
修正为:
libdir=${ohos_project_dir}/out/ohos-arm-release/thirdparty/libpng/
ohos/meson_cross_process.py。

'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/10.0.1/lib/arm-linux-ohos',
'-Lproject_stub/prebuilts/clang/ohos/linux-x87_64/llvm/lib/arm-linux-ohos/c++',
修正为:
'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current/lib/arm-linux-ohos',
'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/arm-linux-ohos/c++',
以上是因为版本变迁需要进行的修改,下面讲解适配新的GPU需要做的修改。

驱动编译脚本64位适配

因为我适配小米6采用的是64位系统,官方的mesa库里面的脚本是32位的,这里我采用的方法是复制原版32位的两个相关脚本,修改为64位编译脚本。

复制ohos/build_ohos.py为ohos/build_ohos64.py。

复制ohos/meson_cross_process.py为ohos/meson_cross_process64.py。

修改gpu驱动名以及驱动搜索路径。

ohos/build_ohos64.py。

run_cross_pross_cmd = 'python3 ' + script_dir + '/meson_cross_process.py ' + sys.argv[1] + ' ' + sys.argv[2]
...
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_cross_pross_cmd = 'python3 ' + script_dir + '/meson_cross_process64.py ' + sys.argv[1] + ' ' + sys.argv[2]
...
run_build_cmd += '-Dplatforms=ohos -Degl-native-platform=ohos -Ddri-drivers= -Dgallium-drivers=freedreno \
-Dvulkan-drivers= -Dgbm=enabled -Degl=enabled -Dcpp_rtti=false -Dglx=disabled -Dtools= -Ddri-search-path=/vendor/lib/chipsetsdk '
这里简单解释编译参数需要修改的三个地方

-Dgallium-drivers=panfrost  ->  freedreno

这里修改的是开源GPU驱动的名字,panfrost是arm mali gpu对应的开源驱动的名字,freedreno是高通gpu对应的开源驱动的名字。

-Dtools=

这个是加入编译某些可以查看gpu负载的工具,我不需要,而且加入之后编译报错,解决比较麻烦,暂时去掉了。

 -Ddri-search-path=/system/lib ->  /vendor/lib/chipsetsdk

这个是驱动so库放置的路径,原配置是3.1版本还没有soc分离思想,所以统一放置到system/lib下了,3.2采用了soc分离思想,soc驱动统一放置到vendor下了。

如果需要编译32位GPU驱动,只需要参考修改gpu驱动名以及驱动搜索路径即可。

meson_cross_process64.py

模板部分

修改【arm-linux-ohosmusl】为【aarch64-linux-ohosmusl】

去掉-march,-mtune等优化参数,最后修改为:

corss_file_content='''
[properties]
needs_exe_wrapper = true

c_args = [
'--target=aarch64-linux-ohosmusl',
'--sysroot=sysroot_stub',
'-fPIC']

cpp_args = [
'--target=aarch64-linux-ohosmusl',
'--sysroot=sysroot_stub',
'-fPIC']

c_link_args = [
'--target=aarch64-linux-ohosmusl',
'-fPIC',
'--sysroot=sysroot_stub',
'-Lsysroot_stub/usr/lib/aarch64-linux-ohos',
'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current/lib/aarch64-linux-ohos',
'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/aarch64-linux-ohos/c++',
'--rtlib=compiler-rt',
]

cpp_link_args = [
'--target=aarch64-linux-ohosmusl',
'--sysroot=sysroot_stub',
'-Lsysroot_stub/usr/lib/aarch64-linux-ohos',
'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current/lib/aarch64-linux-ohos',
'-Lproject_stub/prebuilts/clang/ohos/linux-x86_64/llvm/lib/aarch64-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 = 'project_stub/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-ar'
c = ['ccache', 'project_stub/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang']
cpp = ['ccache', 'project_stub/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++']
c_ld= 'lld'
cpp_ld = 'lld'
strip = 'project_stub/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-strip'
pkgconfig = '/usr/bin/pkg-config'

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8'
endian = 'little'
'''
另外generate_pc_file函数中需要添加多一行,把pkgconfig_template中的【ohos-arm】替换为【ohos-arm64】

raw_content = raw_content.replace("ohos_project_directory_stub", project_dir)
raw_content = raw_content.replace("ohos-arm-release", product_name)
添加:
raw_content = raw_content.replace("ohos-arm", "ohos-arm64")

修改build_id获取函数

因为OpenHarmony在elf文件里面的note信息添加了一个ohos特有的标识符,导致mesa3d获取build_id的函数进行地址偏移计算的时候计算失误,需要修正build_id获取函数。

src/util/build_id.c。

mesa编译

soc目录下参照rockchip新建对应的qualcomm/msm8998/hardware/gpu目录,include内的头文件可复制rockchip下的文件。

修改完毕之后参照README_zh.md,在mesa3d目录下执行py脚本进行编译

python ohos/build_ohos64.py /home/diemit/ohos_beta5 sagit /home/diemit/ohos_beta5/third_party/mesa3d/
正常完成如下显示。

3、OpenHarmony编译框架适配

复制编译出的lib到对应的soc/gpu目录下

cp build-ohos/src/gallium/targets/dri/libgallium_dri.so ../../device/soc/qualcomm/msm8998/hardware/gpu/lib64
cp build-ohos/src/egl/libEGL.so.1.0.0 ../../device/soc/qualcomm/msm8998/hardware/gpu/lib64
cp build-ohos/install/lib/libGLESv1_CM.so.1.1.0 ../../device/soc/qualcomm/msm8998/hardware/gpu/lib64
cp build-ohos/install/lib/libGLESv2.so.2.0.0 ../../device/soc/qualcomm/msm8998/hardware/gpu/lib64
cp build-ohos/install/lib/libgbm.so.1.0.0 ../../device/soc/qualcomm/msm8998/hardware/gpu/lib64
cp build-ohos/install/lib/libglapi.so.0.0.0 ../../device/soc/qualcomm/msm8998/hardware/gpu/lib64
添加对应的BUILD.gn,复制对应的so文件到vendor下,并创建软连接

import("//build/ohos.gni")
import("//build/ohos/ndk/ndk.gni")

ohos_prebuilt_shared_library("mesa_egl") {
source = "lib64/libEGL.so.1.0.0"
install_enable = true
part_name = "qualcomm_products"
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
symlink_target_name = [
"libEGL.so",
"libEGL_impl.so",
]
}

ohos_prebuilt_shared_library("mesa_gbm") {
source = "lib64/libgbm.so.1.0.0"
install_enable = true
part_name = "qualcomm_products"
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
symlink_target_name = [
"libgbm.so.1",
"libgbm.so",
]
}

ohos_prebuilt_shared_library("mesa_glapi") {
source = "lib64/libglapi.so.0.0.0"
install_enable = true
part_name = "qualcomm_products"
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
symlink_target_name = [
"libglapi.so.0",
"libglapi.so",
]
}

ohos_prebuilt_shared_library("mesa_glesv1") {
source = "lib64/libGLESv1_CM.so.1.1.0"
install_enable = true
part_name = "qualcomm_products"
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
symlink_target_name = [
"libGLESv1.so",
"libGLESv1_impl.so",
]
}

ohos_prebuilt_shared_library("mesa_glesv2") {
source = "lib64/libGLESv2.so.2.0.0"
install_enable = true
part_name = "qualcomm_products"
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
symlink_target_name = [
"libGLESv2.so",
"libGLESv2_impl.so",
"libGLESv3.so",
"libGLESv3_impl.so",
]
}

ohos_prebuilt_shared_library("libgallium_dri") {
source = "lib64/libgallium_dri.so"
install_enable = true
part_name = "qualcomm_products"
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
symlink_target_name = [
"msm_dri.so",
]
}

group("mesa3d-lib") {
deps = [
":mesa_egl",
":mesa_gbm",
":mesa_glapi",
":mesa_glesv1",
":mesa_glesv2",
":libgallium_dri",
]
}
上层BUILD.gn中添加gpu对应的lib信息。

import("//build/ohos.gni")
group("hardware_group") {
deps = [
"gpu:mesa3d-lib",
]
}
这里可能会有的小伙伴会疑惑,为啥要复制build-ohos/src/gallium/targets/dri/libgallium_dri.so而不是build-ohos/install/lib/dri/msm_dri.so,这也是我之前遇到的问题,后来我发现dri下面那一大堆都是同一个文件,都是通过脚本从libgallium_dri.so复制过来重命名的而已,所以直接复制libgallium_dri.so即可,libgallium_dri.so可以软连接成所有x_dri.so

另外为什么要软连接成x_impl.so,是因为OH的代码里面是用这个文件名进行lib的加载。

GPU适配这块我是在树莓派上首次验证成功,细节印象还比较深刻,所以打算详细讲解,篇幅会比较长,第一篇先讲解mesa编译的坑与解决办法,下篇讲解编译gpu测试程序,与gpu驱动程序的验证,敬请期待。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

有关OpenHarmony富设备移植指南—开源GPU驱动编译的更多相关文章

  1. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  2. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  3. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  4. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby-on-rails - 禁用设备的 :confirmable on-the-fly to batch-generate users - 2

    Devise是一个Ruby库,它为我提供了这个User类:classUser当写入:confirmable时,注册时会发送一封确认邮件。上周我不得不批量创建300个用户,所以我在恢复之前注释掉了:confirmable几分钟。现在我正在为用户批量创建创建一个UI,因此我需要即时添加/删除:confirmable。(我也可以直接修改Devise的源码,但我宁愿不去调和它)问题:如何即时添加/删除:confirmable? 最佳答案 WayneConrad的解决方案:user=User.newuser.skip_confirmation

  7. .net - 是否有 Ruby .NET 编译器? - 2

    是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/

  8. ruby-on-rails - 可移植 Ruby on Rails 环境 - 2

    我给自己买了一个新的8gigUSBkey,我正在寻找一个合适的解决方案来拥有一个可移植RoR环境来学习。我在谷歌上搜索了一下,发现了一些可能性,但我很想听听一些现实生活中的经历和意见。谢谢! 最佳答案 我喜欢InstantRails,非常容易使用,无需安装程序,也不会修改您的系统环境。 关于ruby-on-rails-可移植RubyonRails环境,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

  9. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

  10. python - 使用 Python、Ruby 和 Perl 重新编译 MacPort 版本的 MacVim - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭10年前。ImprovethisquestionLinux专家正在转向Mac(10.8)。因为我懒...我使用MacPorts安装MacVim。它似乎安装没有错误。我只需要mvim中的python、ruby和perl支持。$/opt/local/bin/mvim--version|egrep'patches|python|ruby|perl'Includedpatches:1-244,246-646+multi_lang-mzscheme+

随机推荐