OpenHarmony开源GPU库Mesa3D适配说明
本文档主要讲解在OpenHarmony中,Mesa3D的适配方法及原理说明。 环境说明: OHOS版本: 适用3.2-Beta3及以上 内核版本: linux-5.10 硬件环境: Dayu200-rk3568一、背景介绍 OpenHarmony对图形的渲染,支持CPU和GPU两种方式。为了支持流畅的用户体现,GPU适配是必不可少的。Ope
本文档主要讲解在OpenHarmony中,Mesa3D的适配方法及原理说明。
环境说明:
-
OHOS版本: 适用3.2-Beta3及以上
-
内核版本: linux-5.10
-
硬件环境: Dayu200-rk3568
一、背景介绍
OpenHarmony对图形的渲染,支持CPU和GPU两种方式。为了支持流畅的用户体现,GPU适配是必不可少的。OpenHarmony使用GPU渲染,就必须依赖OpenGL接口。
OpenGL(Open Graphics Library) 开放图形库,是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(仅定义了接口及规范,没有实现)。OpenGL的高效性(利用了图形加速硬件)依赖于显示设备厂家的硬件及实现。
OpenGL API实现的方式又分为闭源及开源两种方式。闭源实现一般由设备厂家完成,这种方式充分保证了它的高效性,但移植起来比较麻烦。今天我们要重点介绍的是另外一种开源实现的方式:mesa3D。
Mesa3D 图形库就是OpenGL API的一种开源实现。新版本还支持OpenCL、OpenGL ES等等。Mesa3D对上提供标准的OpenGL接口,对下使用Gallium框架,屏蔽驱动差异。在RK3568中,panfrost对ARM GPU提供了非常好的开源驱动支持。
二、适配方法
在RK3568 GPU 开源库mesa3D适配时,我们同时依赖了drm panfrost的实现。目前OpenHarmony 3.2-Release基线中,支持4.19及5.10两个Linux版本,而只有5.10才提供了对panfrost的支持。如果当前Linux版本不支持panfrost,那就需要升级内核版本,或者把panfrost移植到当前版本上。
2.1 适配框架说明
以下是我们这次适配的框架示意图:
通过上图我们可以看出,一个大致的UI显示流程如下:
JS创建window->调用skia完成接口封装->调用mesa3D的OpenGL接口完成渲染->返回EglSurface数据->送到Dislay HDI的GFX合成->调用KMS完成数据转换->LCD硬件完成显示
2.2 适配前提条件
从适配框架图可以看出,GPU适配,需要建立在Dislay HDI、DRM、LCD驱动完整的基础之上,否则Launcher没有启动,也不能确定适配是否完好。所以,在GPU适配之前,需要确保在CPU渲染的基础上,Launcher是能正常启动的。
CPU渲染修改方法: 设置graphic_standard_feature_ace_enable_gpu = false。包含在以下路径中:
foundation/graphic/standard/graphic_config.gni
productdefine/common/inherit/rich.json
productdefine/common/products/ohos-arm64.json
编译过程中,旧版本可能会报如下错误:
解决方案如下:
vendor/hihope/rk3568/config.json
"ace_engine_feature_enable_web = false"
使用CPU模式能正常进入桌面,代表系统启动正常。
2.3 Mesa3D适配
-
依赖库安装
sudo apt-get install -y meson cmake llvm ninja-build pkg-config python3 -m pip install meson==0.62.0 python -m pip install --upgrade pip pip install mako atomic markupsafe
-
合入patch
https://gitee.com/openharmony/third_party_mesa3d/pulls/13 //mesa3D相关 必须合入 https://gitee.com/zleoyu/device_soc_rockchip/commit/4467466a50adca43f26a77912cab710901f909e4 //合入产品配置 必须合入。
单独测试mesa3d编译:
python3 ohos/build_ohos.py OH目录 rk3568 OH目录/third_party/mesa3d
-
修改成GPU模式
foundation/graphic/standard/graphic_config.gni productdefine/common/inherit/rich.json productdefine/common/products/ohos-arm64.json
graphic_standard_feature_ace_enable_gpu = true
-
GPU合成
如果需要使用GPU合成,需要打开如下开关:
foundation/graphic/standard/graphic_config.gni
graphic_standard_feature_rs_enable_eglimage = true
-
patch错误修改:
-
mesa3d patch合入报错:
修改方案:
diff --git a/src/loader/loader.c b/src/loader/loader.c index fd2ce99..3b443d6 100644 --- a/src/loader/loader.c +++ b/src/loader/loader.c @@ -77,7 +77,7 @@ static void default_logger(int level, const char *fmt, ...) va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); - sprintf_s(log_string, MAX_BUFFER_LEN, fmt, args); + sprintf(log_string, fmt, args); va_end(args); } DISPLAY_LOGI(); @@ -89,7 +89,7 @@ static void ohos_logger(int level, const char *fmt, ...) char log_string[MAX_BUFFER_LEN]; va_list args; va_start(args, fmt); - (void)sprintf_s(log_string, MAX_BUFFER_LEN, fmt, args); + (void)sprintf(log_string, fmt, args); va_end(args); switch (level) { case _LOADER_WARNING:
-
合入产品配置报错
解决方案:
diff --git a/rk3568/hardware/display/BUILD.gn b/rk3568/hardware/display/BUILD.gn index 85daf66..773abdc 100644 --- a/rk3568/hardware/display/BUILD.gn +++ b/rk3568/hardware/display/BUILD.gn @@ -242,7 +242,7 @@ ohos_static_library("display_utils") { cflags = [ "-Wno-macro-redefined" ] deps = [ "//third_party/libdrm:libdrm", - "//utils/native/base:utils", +# "//utils/native/base:utils", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] }
-
三、下载及验证
3.1 编译及下载img
RK3568 在ubuntu环境中,通过以下命令下载到设备:
//让内核重新编译
touch device/board/hihope/rk3568/kernel/build_kernel.sh
//编译OpenHarmony
./build.sh --product-name rk3568 --compile-config enable_mesa3d
//下载img
cd out/rk3568/packages/phone/images
upgrade_tool di -p parameter.txt -uboot uboot.img -boot_linux boot_linux.img -resource resource.img -vendor vendor.img -system system.img -userdata userdata.img -updater updater.img
//重启
upgrade_tool RD
3.2 panfrost正确日志打印
以下是panfrost启动成功后的串口日志打印:
Line 480: [ 0.780211] panfrost fde60000.gpu: clock rate = 594000000
Line 481: [ 0.780254] panfrost fde60000.gpu: bus_clock rate = 500000000
Line 482: [ 0.780476] panfrost fde60000.gpu: [drm:panfrost_devfreq_init] *ERROR* Couldn't set OPP regulators
Line 824: [ 2.008794] panfrost fde60000.gpu: clock rate = 594000000
Line 825: [ 2.008852] panfrost fde60000.gpu: bus_clock rate = 500000000
Line 826: [ 2.010067] panfrost fde60000.gpu: mali-g52 id 0x7402 major 0x1 minor 0x0 status 0x0
Line 827: [ 2.010100] panfrost fde60000.gpu: features: 00000000,13de77ff, issues: 00000000,00000400
Line 828: [ 2.010114] panfrost fde60000.gpu: Features: L2:0x07110206 Shader:0x00000002 Tiler:0x00000209 Mem:0x1 MMU:0x00002823 AS:0xff JS:0x7
Line 829: [ 2.010124] panfrost fde60000.gpu: shader_present=0x1 l2_present=0x1
Line 830: [ 2.012042] [drm] Initialized panfrost 1.1.0 20180908 for fde60000.gpu on minor 1
3.3 GPU渲染标志性打印
输入hilog并输出egl相关,能看到如下打印:
hilog -e egl
OHOS::ROSEN: RSSurfaceOhosGl:RequestFrame, eglsurface is 0x38f1ab0, width is 720, height is 48
OHOS::ROSEN: RSSurfaceOhosGl: FlushFrame, SwapBuffers eglsurface is 0x38f1ab0
OHOS::ROSEN: RSSurfaceOhosGl:RequestFrame, eglsurface is 0x39c1ba0, width is 720, height is 72
OHOS::ROSEN: RSSurfaceOhosGl: FlushFrame, SwapBuffers eglsurface is 0x39c1ba0
OHOS::ROSEN: RSSurfaceOhosGl:RequestFrame, eglsurface is 0x2df8350, width is 720, height is 1280
如果这个时候屏幕能够正常显示launcher想着内容,就恭喜你适配成功了。
四、知识分享
从上面的适配框架可以看出,除了Mesa3D外,drm、panfrost、Display HDI也是至关重要的,下面我们简单介绍相关知识及验证方法。
4.1 drm
drm(Direct Rendering Manager) 直接渲染管理,是Linux目前主流的图形显示框架。并且管理着GPU及Display驱动,使得软件架构更为统一,方便管理和维护。
DRM从模块上划分,可以简单分为3部分。
-
libdrm
为用户态提供各种IOCTL操作接口。
-
KMS(Kernel Mode Setting)
包换以下模块的实现:CRTC,ENCODER,CONNECTOR,PLANE,FB,VBLANK,property
-
GEM
显示内存的分配管理。包含:DUMB、PRIME、fence
一个新设备drm的实现就是对KMS及GEM的实现,drm提供了一个虚拟设备例子参考:drivers/gpu/drm/vkms。以下链接非常详细的介绍了drm相关知识:
在用户态,libdrm提供了modetest工具,来检测drm基础功能,是否适配成功。它可以测试基本显示功能,并列举出几大组件的参数。但一些扩展的硬件功能,modetest无法检测,比如显存压缩技术AFBC。但适配前期,modetest还是非常好用的。
4.2 panfrost
panfrost的是对ARM 系列GPU驱动的开源实现,它的功能主要是完成对GPU硬件的初始化,以及以job的方式,完成对渲染数据硬件处理。在本文档中,GPU相关的配置,渲染管理等都是通过Mesa3D对panfrost ioctl来实现的。
4.3 Display HDI
Display HDI是OpenHarmony显示接口适配层。主要功能分三部分:
-
Display 显示管理及配置
-
Gralloc 显存管理
-
GFX Layer合成管理
HDI 通过libdrm提供的接口来管理显示设备及送显。OpenHarmony 使用的是atomic接口,需要drm支持atomic的property操作方式。HDI操作流程基本与modetest代码一致。在使用modetest确保drm驱动基本完整的情况下,可以使用hello_composer工具来测试HDI是否适配成功。
4.4 常用错误及处理方法
以下是适配过程中遇到的一些问题,为文档阅读者提供一些参考思路。
4.4.1 panfrost 初始化失败
panfrost初始化GPU硬件时,会遇到写复位寄器超时,有如下打印:
gpu soft reset timed out
这个时候发现读写GPU寄存器都表现异常,应该考虑GPU是否上电成功。
4.4.2 Launcher显示异常
桌面显示异常,状态和文字相关能正常显示,与图片相关的只显示一个框框,其它都是白色。并报如下错误:
[ 39.747285] panfrost 60000000.gpu: js fault, js=0, status=DATA_INVALID_FAULT, head=0x659c5c0, tail=0x659c5c0
[ 39.757132] panfrost 60000000.gpu: gpu sched timeout, js=0, config=0x3300, status=0x58, head=0x659c5c0, tail=0x659c5c0, sched_job=f77ff5d1
从错误来看,显示数据无效错误。经过定位,发现GPU是支持AFBC(显存压缩技术),但DRM没有适配。最后在Mesa3D中关闭该功能,显示正常。
--- a/src/panfrost/lib/pan_props.c
+++ b/src/panfrost/lib/pan_props.c
@@ -241,7 +241,7 @@ panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev)
dev->quirks = panfrost_get_quirks(dev->gpu_id, revision);
dev->compressed_formats = panfrost_query_compressed_formats(fd);
dev->tiler_features = panfrost_query_tiler_features(fd);
- dev->has_afbc = panfrost_query_afbc(fd, dev->arch);
+ dev->has_afbc = false;//panfrost_query_afbc(fd, dev->arch);
4.4.3 ISA Config配置异常
案例参考: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7228
4.4.5 其它调试手段
如果OpenHarmony无法点亮屏幕,可以用buildroot来先测试,成功后再使用OpenHarmony验证。
buildroot小巧,修改编译调试都比较方便,并且自带glmark2测试工具。
步骤一: 关闭ramdisk
# CONFIG_BLK_DEV_INITRD=y
# CONFIG_INITRAMFS_SOURCE=""
步骤二:编译buildroot。
参考:https://blog.csdn.net/u013131156/article/details/124337444
步骤三:下载
使用rootfs.ext4 替换OHOS的system.img。
步骤四:调试
1、开机必要的环境变量配置:
mkdir /tmp/xdg
export XDG_RUNTIME_DIR=/tmp/xdg
2 打开日志(可选):
export PAN_MESA_DEBUG=trace
export MESA_DEBUG=1
export EGL_LOG_LEVEL=debug
export LIBGL_DEBUG=verbose
export WAYLAND_DEBUG=1
3 启动桌面
weston --tty 1 & //GPU
或者
weston --tty=1 --use-pixman & //CPU
4 运行glmark2性能测试工具
glmark2-es2-wayland
4.4.5 闭源GPU so适配
闭源GPU so库适配最简单的是修改这个mali-bifrost-g52-g2p0-ohos动态库的实现。
ohos_prebuilt_shared_library("mali-bifrost-g52-g2p0-ohos") {
if (target_cpu == "arm") {
source = "lib/libmali-bifrost-g52-g2p0-ohos.so"//修改成厂家so库
} else if (target_cpu == "arm64") {
source = "lib64/libmali-bifrost-g52-g2p0-ohos.so"
}
# decoupling system.img and vendor.img
install_images = [ chipset_base_dir ]
relative_install_dir = "chipsetsdk"
subsystem_name = "rockchip_products"
part_name = "rockchip_products"
install_enable = true
symlink_target_name = [
"libEGL_impl.so",
"libGLESv1_impl.so",
"libGLESv2_impl.so",
"libGLESv3_impl.so",
"libmali.so.0",
"libmali.so.1",
]
}
如果要修改mali-bifrost-g52-g2p0-ohos这个动态库名字,那在另外一个gn中也要同步修改:
device/soc/rockchip/rk3568/hardware/BUILD.gn
group("hardware_group") {
deps = [
"//device/soc/rockchip/rk3568/hardware/gpu:mali-bifrost-g52-g2p0-ohos",//这个名字需要同步修改
"//device/soc/rockchip/rk3568/hardware/isp:isp",
"//device/soc/rockchip/rk3568/hardware/mpp:mpp",
"//device/soc/rockchip/rk3568/hardware/wifi:ap6xxx",
]
}
更多推荐
所有评论(0)