
??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??
??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??
??https://ost.51cto.com??
在OpenHarmony的各部件適配中,GPU適配是公認(rèn)的最難,首先原廠(chǎng)安卓的驅(qū)動(dòng)是沒(méi)辦法用的,后來(lái)又因?yàn)镺penHarmony3.1開(kāi)始啟用了自研的Rosen合成框架取代了Weston合成框架,原來(lái)能直接用的開(kāi)源圖形驅(qū)動(dòng)現(xiàn)在也不能直接用了,新版的OpenHarmony需要圖形驅(qū)動(dòng)要額外對(duì)接OpenHarmony的接口,采用閉源驅(qū)動(dòng)要得到原廠(chǎng)的支持,這個(gè)目前走不通,所以第三方設(shè)備要啟用GPU加速只能選擇采用開(kāi)源的Mesa3d驅(qū)動(dòng),所幸OpenHarmony提供了一份mesa3d的參考實(shí)現(xiàn),也能使OpenHarmony流暢絲滑了,這篇文章我打算分享一下我移植適配GPU的相關(guān)經(jīng)驗(yàn),希望能幫到大家。
同時(shí)在此說(shuō)明一下,這些知識(shí)基本都是我在網(wǎng)上自學(xué)得來(lái),不是圖形專(zhuān)家,沒(méi)有深入學(xué)習(xí)過(guò)圖形方面的知識(shí),對(duì)某些圖形的專(zhuān)業(yè)名詞或者某些概念可能會(huì)用詞不準(zhǔn)確或者解釋錯(cuò)誤,請(qǐng)大家諒解。
1、OpenHarmony圖形顯示移植適配思路
首先借用一張OpenHarmony圖形能力的視圖,我們可以了解到目前OpenHarmony當(dāng)前以及未來(lái)支持的能力情況。

之前我們點(diǎn)亮屏幕采用的是CPU合成+CPU渲染的技術(shù)路徑,在【2022.3】的時(shí)候開(kāi)始支持的,同時(shí)采用OpenGLES接口的GPU合成+GPU渲染也在3.2Beta4【2022.12】的時(shí)候?qū)崿F(xiàn)了,基于這個(gè)版本才能實(shí)現(xiàn)完整的GPU加速,可以期待一下【2023.9】基于Vulkan接口的GPU加速。
經(jīng)過(guò)上面簡(jiǎn)單介紹,可能大家對(duì)GPU圖形適配還是毫無(wú)頭緒,因?yàn)檫@是在引申圖形適配的一些前置知識(shí),在此我簡(jiǎn)單總結(jié)一下適配OH圖形需要關(guān)注兩個(gè)大點(diǎn):合成和渲染,下面是簡(jiǎn)單的解釋。
1.合成:計(jì)算處理圖層疊加關(guān)系。
2.渲染:生成需要顯示的色彩數(shù)據(jù)(buffer)。
以上是我的個(gè)人總結(jié),可能不準(zhǔn)確,大致先這樣分,這樣后面好進(jìn)行講解移植適配的思路。
下面進(jìn)入正題,因?yàn)橐浦睪PU比較復(fù)雜,不可能一部到位,在此我拆開(kāi)進(jìn)行逐步實(shí)現(xiàn),以便出現(xiàn)問(wèn)題時(shí)能快速定位問(wèn)題點(diǎn)出現(xiàn)在哪一部分,拆分思路如下:
1.不啟用GPU功能,在CPU合成+CPU渲染的環(huán)境下,確認(rèn)GPU驅(qū)動(dòng)正常工作
2.啟用部分GPU功能,在CPU合成+GPU渲染的環(huán)境下,確認(rèn)GPU能正確渲染
3.啟用GPU合成+GPU渲染,加速OpenHarmony圖形顯示
2、編譯開(kāi)源GPU驅(qū)動(dòng)Mesa3d
(1)編譯mesa3d
安裝依賴(lài)
首先安裝編譯需要的依賴(lài):
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源碼中以及帶有適配過(guò)的mesa3d庫(kù),但是因?yàn)殚L(zhǎng)時(shí)間沒(méi)有維護(hù),部分配置需要更新:
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++',
以上是因?yàn)榘姹咀冞w需要進(jìn)行的修改,下面講解適配新的GPU需要做的修改。
驅(qū)動(dòng)編譯腳本64位適配
因?yàn)槲疫m配小米6采用的是64位系統(tǒng),官方的mesa庫(kù)里面的腳本是32位的,這里我采用的方法是復(fù)制原版32位的兩個(gè)相關(guān)腳本,修改為64位編譯腳本。
復(fù)制ohos/build_ohos.py為ohos/build_ohos64.py。
復(fù)制ohos/meson_cross_process.py為ohos/meson_cross_process64.py。
修改gpu驅(qū)動(dòng)名以及驅(qū)動(dòng)搜索路徑。
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 '
這里簡(jiǎn)單解釋編譯參數(shù)需要修改的三個(gè)地方
-Dgallium-drivers=panfrost -> freedreno
這里修改的是開(kāi)源GPU驅(qū)動(dòng)的名字,panfrost是arm mali gpu對(duì)應(yīng)的開(kāi)源驅(qū)動(dòng)的名字,freedreno是高通gpu對(duì)應(yīng)的開(kāi)源驅(qū)動(dòng)的名字。
-Dtools=
這個(gè)是加入編譯某些可以查看gpu負(fù)載的工具,我不需要,而且加入之后編譯報(bào)錯(cuò),解決比較麻煩,暫時(shí)去掉了。
-Ddri-search-path=/system/lib -> /vendor/lib/chipsetsdk
這個(gè)是驅(qū)動(dòng)so庫(kù)放置的路徑,原配置是3.1版本還沒(méi)有soc分離思想,所以統(tǒng)一放置到system/lib下了,3.2采用了soc分離思想,soc驅(qū)動(dòng)統(tǒng)一放置到vendor下了。
如果需要編譯32位GPU驅(qū)動(dòng),只需要參考修改gpu驅(qū)動(dòng)名以及驅(qū)動(dòng)搜索路徑即可。
meson_cross_process64.py
模板部分
修改【arm-linux-ohosmusl】為【aarch64-linux-ohosmusl】
去掉-march,-mtune等優(yōu)化參數(shù),最后修改為:
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函數(shù)中需要添加多一行,把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獲取函數(shù)
因?yàn)镺penHarmony在elf文件里面的note信息添加了一個(gè)ohos特有的標(biāo)識(shí)符,導(dǎo)致mesa3d獲取build_id的函數(shù)進(jìn)行地址偏移計(jì)算的時(shí)候計(jì)算失誤,需要修正build_id獲取函數(shù)。
src/util/build_id.c。

mesa編譯
soc目錄下參照rockchip新建對(duì)應(yīng)的qualcomm/msm8998/hardware/gpu目錄,include內(nèi)的頭文件可復(fù)制rockchip下的文件。
修改完畢之后參照README_zh.md,在mesa3d目錄下執(zhí)行py腳本進(jìn)行編譯
python ohos/build_ohos64.py /home/diemit/ohos_beta5 sagit /home/diemit/ohos_beta5/third_party/mesa3d/
正常完成如下顯示。

3、OpenHarmony編譯框架適配
復(fù)制編譯出的lib到對(duì)應(yīng)的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
添加對(duì)應(yīng)的BUILD.gn,復(fù)制對(duì)應(yīng)的so文件到vendor下,并創(chuàng)建軟連接
import("http://build/ohos.gni")
import("http://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對(duì)應(yīng)的lib信息。
import("http://build/ohos.gni")
group("hardware_group") {
deps = [
"gpu:mesa3d-lib",
]
}
這里可能會(huì)有的小伙伴會(huì)疑惑,為啥要復(fù)制build-ohos/src/gallium/targets/dri/libgallium_dri.so而不是build-ohos/install/lib/dri/msm_dri.so,這也是我之前遇到的問(wèn)題,后來(lái)我發(fā)現(xiàn)dri下面那一大堆都是同一個(gè)文件,都是通過(guò)腳本從libgallium_dri.so復(fù)制過(guò)來(lái)重命名的而已,所以直接復(fù)制libgallium_dri.so即可,libgallium_dri.so可以軟連接成所有x_dri.so


另外為什么要軟連接成x_impl.so,是因?yàn)镺H的代碼里面是用這個(gè)文件名進(jìn)行l(wèi)ib的加載。

GPU適配這塊我是在樹(shù)莓派上首次驗(yàn)證成功,細(xì)節(jié)印象還比較深刻,所以打算詳細(xì)講解,篇幅會(huì)比較長(zhǎng),第一篇先講解mesa編譯的坑與解決辦法,下篇講解編譯gpu測(cè)試程序,與gpu驅(qū)動(dòng)程序的驗(yàn)證,敬請(qǐng)期待。
??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??
??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??
??https://ost.51cto.com??