前言:根据ubuntu2004的chroot开发环境的内容我们已经具备ubuntu2004的chroot环境了,基于此我们从零搭建OH的开发环境步骤如下
#!/bin/bash CHROOT_DIR=/data/squashfs-root/ # 挂载dev/proc/sys ! mountpoint -q /${CHROOT_DIR}/dev/ && mount -o bind /dev /${CHROOT_DIR}/dev/ ! mountpoint -q /${CHROOT_DIR}/dev/pts && mount -t devpts devpts /${CHROOT_DIR}/dev/pts ! mountpoint -q /${CHROOT_DIR}/proc/ && mount -t proc proc /${CHROOT_DIR}/proc/ ! mountpoint -q /${CHROOT_DIR}/sys/ && mount -t sysfs sys /${CHROOT_DIR}/sys/
根据此脚本可以正常进入2004的chroot环境
根据OH官网的文档,需要安装如下包
apt install default-jdk genext2fs mtd-utils scons gcc-arm-none-eabi gcc-arm-linux-gnueabi ccache apt install libxinerama-dev libxcursor-dev libxrandr-dev libxi-dev curl python3-pip apt-get install git git-lfs
配置repo,拉取代码,安装hb脚本如下
mkdir ~/bin curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 -o ~/bin/repo chmod a+x ~/bin/repo pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests vim ~/.bashrc # 编辑环境变量 export PATH=~/bin:$PATH # 在环境变量的最后添加一行repo路径信息 source ~/.bashrc # 应用环境变量 repo init -u git@gitee.com:openharmony/manifest.git -b master --no-repo-verify repo sync -c repo forall -c 'git lfs pull' python3 -m pip install --user build/hb export PATH=~/.local/bin:$PATH build/prebuilts_download.sh
repo init -u https://gitee.com/openharmony/manifest -b OpenHarmony-4.0-Release --no-repo-verify -g ohos:standard repo sync -c repo forall -c 'git lfs pull'
./build.sh --product-name rk3568 --ccache --no-prebuilt-sdk
build/prebuilts_download.sh ./build.sh --product-name dayu210 --ccache
out/rk3568/packages/phone/images/
最近在调试openharmony的显示问题上面受阻,原因是众达的硬件上是hdmi接的rk628转接,然后再接的lvds显示器,而openharmony实现的显示panel比较简单,直接dsi panel。所以针对于此,需要将众达的显示panel相关驱动好好梳理出来
针对众达设备的场景,我们知道其重点在于drm panel和drm bridge。这里解释一下:
drm:内核drm显示框架,用于抽象
panel:屏的意思,在drm内抽象用于表示这是一个屏幕,例如hdmi,lvds,edp等
bridge:桥的意思,很多总线概念(pcie)都有,桥接显示器的意思,这里hdmi转lvds接的屏,肯定有bridge的概念
对于众达rk3568而言,我这里图示如下:
对于我们而言,我们需要初始化hdmi驱动,并且把hdmi作为bridge使能,然后找到下一个bridge为rk628,然后在rk628上找到真正的panel。
对于实现此问题的场景,此函数应该重点讲解,它是内核提供的标准api,用于找到下一个panel或bridge。
函数的定义如下:
int drm_of_find_panel_or_bridge(struct device *dev, int port, int endpoint, struct drm_panel **panel, struct drm_bridge **bridge);
这里需要解释的是:
驱动通过此函数能够从设备树获得到下一个bridge或panel的节点,从而触发component_ops的bind回调
为了把事情说清楚,这里有必要简单介绍一下component,详细的介绍建议阅读代码学习,网上知识不多,我也是个人理解
component是组件框架,通常存在在比较大的内核框架中实现,component框架分master和component,两者没有明显区别,只是master会按照match来遍历所有组件,如果都注册了就触发bind。而组件是通过返回-517也就是-DPROBE_DEFER来延迟探测。
这里我们把显示框架"display-subsystem"作为了master,而其他的panel和bridge都以component来注册。示例如下:
ret = component_master_add_with_match(dev, &rockchip_drm_ops, match); component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
对于设备树,我们针对drm_of_find_panel_or_bridge的函数,需要按照实际硬件连接的方式准备port和endpoint,我整理如下:
hdmi: port@1 { reg = <1>; hdmi_out_hdmirx: endpoint { remote-endpoint = <&hdmirx_in_hdmi>; status = "okay"; }; }; rk628_hdmirx: ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; hdmirx_in_hdmi: endpoint { remote-endpoint = <&hdmi_out_hdmirx>; }; }; port@1 { reg = <1>; hdmirx_out_post_process: endpoint { remote-endpoint = <&post_process_in_hdmirx>; }; }; }; 抽象rk628_post_process ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; post_process_in_hdmirx: endpoint { remote-endpoint = <&hdmirx_out_post_process>; }; }; port@1 { reg = <1>; post_process_out_lvds: endpoint { remote-endpoint = <&lvds_in_post_process>; }; }; }; rk628_lvds: ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; lvds_in_post_process: endpoint { remote-endpoint = <&post_process_out_lvds>; }; }; port@1 { reg = <1>; lvds_out_panel: endpoint { remote-endpoint = <&panel_in_lvds>; }; }; }; simple_panel: port { panel_in_lvds: endpoint { remote-endpoint = <&lvds_out_panel>; }; };
上面代码我梳理一下如下:
hdmi---->hdmirx_in_hdmi---->post_process_in_hdmirx---->lvds_in_post_process---->panel_in_lvds
根据上面的代码梳理,我们可以知道了其调用流程,这里总结一下如下:
component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
添加了组件,等待调用bind
dw_hdmi_bind中drm_bridge_attach到drm中,并通过of_drm_find_bridge找下一个bridge,这里下一个设备是hdmirx_in_hdmi
drm_bridge_add添加bridge设备,attach执行回调
在attach中,调用
drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL, &hdmirx→bridge)
然后drm_bridge_attach上
这里1和-1是指的从port1上遍历找endpoint,这里是post_process_in_hdmirx
同样的
drm_bridge_add添加bridge设备,attach执行回调
在attach中,调用
drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL, &pp→bridge)
然后drm_bridge_attach上
这里1和-1是指的从port1上遍历找endpoint,这里是lvds_in_post_process
这里直接在probe函数中寻找panel设备
drm_of_find_panel_or_bridge(dev->of_node, 1, -1, &lvds->panel, NULL)
然后调用drm_bridge_add添加即可。
因为这个panel_simple驱动就是drm panel的驱动,所以它负责初始化panel drm_panel_init,添加panel drm_panel_add
根据Openharmony的display的驱动来看,通过ili9881_st_5p5.c驱动直接初始化了dsi的硬件,然后通过hdf_drm_panel.c来进行drm_panel_init和drm_panel_add
可以知道,Openharmony没有涉及bridge的概念,所以根据众达的显示panel流程,我们理想中的Openharmony的hdf实现应该是如下:
我们可以跳过1,2,3,4四个步骤,我们只实现步骤5,让驱动在component的bind的时候能够将drm bridge or panel路径走通。此方法可以参考文章《Openharmony-rk3568 移植panel_simple_common》
根据上面的分析解剖,我们知道,如果想要完全按照hdf的思想来设计hdf驱动,我们针对rk628需要写很多个驱动才能实现hdf的基本功能。
我们再基于一个原理:
drm是显示框架的抽象,它有crtc,plane,connector,encoder,frambuffer,panel和bridge。通常情况下,我们通过libdrm下发调用,不会涉及到panel和bridge,它与crtc是割裂开的。所以我们基于drm的panel和bridge也不是一定需要用hdf实现,可以借用linux的实现方式。
而crtc及其他,根据代码追踪,hdf_disp并没有去实现drm的一整套功能。
所以hdf_disp的驱动实际上是不完整的,它只实现了panel,bridge甚至都没有实现,所以我的建议是display驱动可以暂时使用linux标准。
关于hdf_disp调用drm的参考文章《Openharmony-RK3588-drm_plane设置》
针对上面的文章《Openharmony-RK3588-drm_plane设置》分析可以知道,hdf的display并不关键,所以可以完全使用linux的实现,方法如下:
基于drm的显示我们需要如下操作
对于已经编译的内核,我们修改arch/arm64/configs/rockchip_linux_defconfig文件,对于未编译的内核,我们修改kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
我们在最底下添加如下:
# CONFIG_DRIVERS_HDF_DISP is not set CONFIG_DRM_PANEL_SIMPLE=y
对于设备树,我们参考《Openharmony RK3568图层设置》修改,添加如下:
&vp0 { rockchip,plane-mask = <(1 << ROCKCHIP_VOP2_CLUSTER0 | 1 << ROCKCHIP_VOP2_ESMART0 | 1 << ROCKCHIP_VOP2_SMART0)>; rockchip,primary-plane = <ROCKCHIP_VOP2_ESMART0>; cursor-win-id = <ROCKCHIP_VOP2_CLUSTER0>; };
至此,相关修改全部完成。编译内核即可验证,这样情况下基于openharmony的内核的众达rk3568设备已经可以正常显示了。
在基于众达的rk3568板子上,使用非hdf的方式点亮了板卡之后,这里再提供一种办法,可以使用hdf的方式点亮众达rk3568的显示
移植panel_simple_common的hdf驱动可以参考文档《Openharmony-rk3568 移植panel_simple_common》
声明plane的方式可以参考文档《Openharmony RK3568图层设置》
我们在做完上述的操作之后,根据panel代码逻辑的分析,应该是可以成功的,关于分析panel代码的参考文档《Openharmony之众达rk3568内核显示panel代码梳理》
但是发现内核一直死循环,无法继续往下走,日志如下:
[ 23.289028] rockchip-vop2 fe040000.vop: [drm:vop2_bind] vp0 assign plane mask: 0x15, primary plane phy id: 2 [ 23.289095] rockchip-vop2 fe040000.vop: [drm:vop2_bind] vp1 assign plane mask: 0x0, primary plane phy id: -1 [ 23.289149] rockchip-vop2 fe040000.vop: [drm:vop2_bind] vp2 assign plane mask: 0x0, primary plane phy id: -1 [ 23.289545] rockchip-vop2 fe040000.vop: [drm:vop2_create_crtc] Cluster0-win0 as cursor plane for vp0 [ 23.289962] [drm] failed to init overlay plane Cluster0-win1 [ 23.290154] [drm] failed to init overlay plane Cluster1-win1 [ 23.290448] rockchip-drm display-subsystem: bound fe040000.vop (ops vop2_component_ops) [ 23.291207] dwhdmi-rockchip fe0a0000.hdmi: Detected HDMI TX controller v2.11a with HDCP (DWC HDMI 2.0 TX PHY) [ 23.294038] dwhdmi-rockchip fe0a0000.hdmi: registered DesignWare HDMI I2C bus driver [ 23.295241] [I/HDF_AUDIO_HDMI] [HdmiCodecProbe][line:33]: entry [ 23.299447] rk628-hdmirx rk628-hdmirx: failed to attach bridge ret=-517 [ 23.299473] Failed to attach bridge with dw-hdmi ret=-517
这里可以看到,dw-hdmi的bridge初始化失败了,也就是component组件的bind失败了。而且返回的是-EPROBE_DEFER。根据component往上反馈来追溯代码,这里代码追溯到如下:
static int rockchip_drm_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct component_match *match = NULL; int ret; ret = rockchip_drm_platform_of_probe(dev); if (ret) return ret; match = rockchip_drm_match_add(dev); if (IS_ERR(match)) return PTR_ERR(match); ret = component_master_add_with_match(dev, &rockchip_drm_ops, match); if (ret < 0) { rockchip_drm_match_remove(dev); return ret; } ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); if (ret) return ret; return 0; }
从上述代码可以知道, component_master_add_with_match会接收component的返回值,这里ret应该返回-EPROBE_DEFER。而rockchip_drm_platform_probe接收到-EPROBE_DEFER后会延迟探测,这就导致rockchip_drm_platform_probe会被重入。
另一个方面我们知道,linux的device driver的probe是在一个线程中完成的,如果rockchip display subsystem的驱动无法正常的probe,那它就阻塞了其他驱动的probe。
根据上述代码的分析,基本问题也就定位到了,那就是rockchip drm platform的驱动导致内核进入死循环了,而进入死循环的原因是hdf编写的panel_simple_common驱动没有在它之前加载。
根据上述的推理,我们有如下的方式解决问题:
下面逐一分析
我们根据书籍《Openharmony架构、内核、驱动及应用开发全栈》的第七章第五节的内容可以知道如下:

hdf最开始是通过调用DeviceManagerInit来启动hdf框架,DeviceManagerInit的代码如下:
static int __init DeviceManagerInit(void) { int ret; ret = DeviceManagerStart(); if (ret < 0) { HDF_LOGE("%s start failed %d", __func__, ret); } else { HDF_LOGD("%s start success", __func__); } return ret; } late_initcall(DeviceManagerInit);
根据上述代码我们可以知道,hdf肯定是late_initcall,而rk的drm platform驱动是module_init,如下:
module_init(rockchip_drm_init); module_exit(rockchip_drm_fini);
有过内核开发的基础都清楚,此时hdf肯定加载在module_init之后。
再根据《Openharmony架构、内核、驱动及应用开发全栈》中提到的加载驱动流程如下:
我们可以知道在DeviceManagerInit之后,hdf还有一段分发流程,我们根据hcs的描述如下:
display :: host { hostName = "display_host"; device_hdf_drm_panel :: device { device0 :: deviceNode { policy = 0; priority = 197; preload = 0; moduleName = "HDF_DRM_PANEL_SIMPLE"; } } device_lcd :: device { device3 :: deviceNode { policy = 0; priority = 100; preload = 0; moduleName = "PANEL_SIMPLE_COMMON"; }
可以知道display先从host初始化"HDF_DRM_PANEL_SIMPLE",然后在从devicenode初始化"PANEL_SIMPLE_COMMON"。而这块的顺序我们不是很好控制了。
如果我们修改整个hdf的初始化流程,可能对hdf框架带来不好的影响,一方面是hdf本身不成熟,另一方面我们对hdf理解也不深刻。提前hdf是否带来问题心里没办法拍板。
这里我们需要明确的是,rockchip的drm platform驱动会绑定多个vp,在dayu200上,除了dsi还有hdmi设备,即使hdf编写的dsi的panel初始化比较晚,但是hdmi这块完全没有走hdf,所以是不会造成死循环的。
不会产生死循环,只要-EPROBE_DEFER能等得到驱动完成初始化,那就没问题。
我们对内核框架代码是十分清楚的,drm platform驱动的推迟只不过是导致系统黑屏时间长而已,那我们可以推迟moduleinit吗?
结论是不建议
根据上述问题,推迟rockchip drm驱动的方法也不可行,主要原因和4.1同理,怕对hdf带来不好的影响
既然上面两个方法都不建议处理,再鉴于咱们对内核比较熟悉,我们可以对rockchip drm platform driver进行简单改造。让其component match过程放在kthread中,如下
--- a/rockchip_drm_drv.c 2024-05-28 20:38:23.259111826 +0800 +++ b/rockchip_drm_drv.c 2024-06-04 17:18:50.965436190 +0800 @@ -35,6 +35,7 @@ #include "rockchip_drm_fbdev.h" #include "rockchip_drm_gem.h" #include "rockchip_drm_logo.h" +#include <linux/kthread.h> #include "../drm_crtc_internal.h" @@ -46,6 +47,7 @@ static bool is_support_iommu = true; static struct drm_driver rockchip_drm_driver; +struct task_struct *match_thread = NULL; void drm_mode_convert_to_split_mode(struct drm_display_mode *mode) { @@ -1773,30 +1775,42 @@ return 0; } -static int rockchip_drm_platform_probe(struct platform_device *pdev) +static int thread_component_match(void *data) { - struct device *dev = &pdev->dev; - struct component_match *match = NULL; - int ret; - - ret = rockchip_drm_platform_of_probe(dev); - if (ret) - return ret; - - match = rockchip_drm_match_add(dev); - if (IS_ERR(match)) - return PTR_ERR(match); + struct platform_device *pdev = data; + struct device *dev = &pdev->dev; + struct component_match *match = NULL; + int ret; + + while (!kthread_should_stop()) { + ret = rockchip_drm_platform_of_probe(dev); + if (ret) + return ret; + + match = rockchip_drm_match_add(dev); + if (IS_ERR(match)) + return PTR_ERR(match); + + ret = component_master_add_with_match(dev, &rockchip_drm_ops, match); + if (ret < 0) { + rockchip_drm_match_remove(dev); + msleep(2000); + }else if(ret == 0){ + break; + } - ret = component_master_add_with_match(dev, &rockchip_drm_ops, match); - if (ret < 0) { - rockchip_drm_match_remove(dev); - return ret; + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); + if (ret) + return ret; } + return 0; +} - ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); - if (ret) - return ret; - +static int rockchip_drm_platform_probe(struct platform_device *pdev) +{ + match_thread = kthread_run(thread_component_match, pdev, "tangfeng"); + if (IS_ERR(match_thread)) + return PTR_ERR(match_thread); return 0; } @@ -1806,6 +1820,9 @@ rockchip_drm_match_remove(&pdev->dev); + if (match_thread) + kthread_stop(match_thread); + return 0; }
上面代码比较仓促,这里match_thread应该放驱动私有结构体。
根据上面的改造,我们可以确保如果panel未准备好,thread会sleep 2秒,直到panel准备好之后,thread正常退出。这能够有效的解决死循环的问题
根据上述的分析,我们可以通过线程化来解决此问题,在内核中,很多事情都可以线程化,只是取决于驱动的使用场景。从实际意义上来说,将rockchip drm platform驱动线程化没有多大的影响,如果sleep那里调教的比较好,对实际显示的影响(黑屏时间)几乎不会多大(会有影响,但不大)。
而且,根据文章《Openharmony之众达rk3568内核显示panel代码梳理》的第四章可以知道,单独写panel_simple驱动在hdf的设计上来说实际上是一种偷懒的行为,所以我们不必要较真此方法的实用性。
根据众达3568的panel流程,完整的实现hdf 驱动才是这个问题的正解:如下
我们基于Openharmony开发,需要针对repo做一个周编译脚本,这样能够在每周固化系统版本。如下是脚本的使用方法
可以通过git获取此仓库如下:
git clone https://gitlab2.kylin.com/sh-product-Embedded/openharmony/weekly_build_script.git
阶段性版本固化
git clone git@gitlab2.kylin.com:sh-product-Embedded/openharmony/weekly_build_script.git -b B01-kylin-ZD-3568
当获取到此仓库之后,仅需要在仓库目录下运行run.sh即可,如下
cd weekly_build_script && ./run.sh
等待大概2小时后,可以获取到update.img,在如下目录:
out/kylin/update-xxxxxxxx.img
此脚本主要完成如下四个动作
其中同步代码和拉取prebuilts可能因为网络而失败,所以是通过while1来循环
而编译openharmony可能会失败,所以重编译次数为5次,如下:
if ((c>5)) ;then break ; fi
Openharmony在RK3588上不是很成熟,SDK编译经常失败,这里记录编译出的问题
此问题是openharmony内的BUILD.gn需要添加exec_script时,需要在core/gn/ohos_exec_script_allowlist.gni声明,针对此问题, 可以如下
diff --git a/core/gn/ohos_exec_script_allowlist.gni b/core/gn/ohos_exec_script_allowlist.gni index 0a986f49..813976a9 100644 --- a/core/gn/ohos_exec_script_allowlist.gni +++ b/core/gn/ohos_exec_script_allowlist.gni @@ -60,6 +60,7 @@ ohos_exec_script_config = { + "//device/board/hihope/dayu210/camera/BUILD.gn",
错误日志如下:
ninja: error: '../../drivers/peripheral/camera/vdi_base/v4l2/src/camera_dump.cpp', needed by 'obj/drivers/peripheral/camera/vdi_base/v4l2/src/camera_host_vdi_impl_1.0/camera_dump.o', missing and no known rule to make it
原因是dayu210的提交和openharmony sdk不匹配,故根据当前版本设置如下:
diff --git a/dayu210/camera/vdi_impl/v4l2/BUILD.gn b/dayu210/camera/vdi_impl/v4l2/BUILD.gn index 55b0018..c892d56 100755 --- a/dayu210/camera/vdi_impl/v4l2/BUILD.gn +++ b/dayu210/camera/vdi_impl/v4l2/BUILD.gn @@ -139,7 +139,7 @@ if (product_name == "rk3568_mini_system") { host_sources = [ "$camera_path/../v4l2/src/camera_device/camera_device_vdi_impl.cpp", - "$camera_path/../v4l2/src/camera_dump.cpp", + "$camera_path/dump/src/camera_dump.cpp" "$camera_path/../v4l2/src/camera_host/camera_host_config.cpp", @@ -158,6 +158,7 @@ if (product_name == "rk3568_mini_system") { ] host_includes = [ + "$camera_path/dump/include", "$camera_path/../../interfaces/include",
错误日志如下:
Exception: //device/soc/rockchip/rk3588/hardware/display:display_composer_vendor depend part //third_party/libdrm:libdrm, need set part deps libdrm info to device_rk3588.
这里根据文章《Openharmony 4.0 SDK移植RK3588之白名单》可以知道是"third_deps_bundle_not_add"设置问题,这里display_composer_vendor需要添加设置一下,如下
diff --git a/compile_standard_whitelist.json b/compile_standard_whitelist.json index ce4ca863..57fe46b5 100644 --- a/compile_standard_whitelist.json +++ b/compile_standard_whitelist.json "third_deps_bundle_not_add": [ "//arkcompiler/toolchain/tooling:libark_ecma_debugger_test", @@ -455,9 +529,13 @@ + "//device/soc/rockchip/rk3588/hardware/display:display_composer_vendor", + "//device/soc/rockchip/rk3588/hardware/display:libdisplay_buffer_vendor", + "//device/soc/rockchip/rk3588/hardware/display:libhigbm_vendor",
此问题是虚函数声明了函数实现,但是继承的类没有实现,所以原因是openharmony4.1的改动在rk3588的hdi上没有更新,所以我们需要更新rk3588的hdi,新增这些虚函数定义,如下:
diff --git a/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.cpp b/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.cpp index 0affeb9..70c7456 100755 --- a/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.cpp +++ b/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.cpp @@ -116,6 +116,36 @@ int32_t DisplayBufferVdiImpl::IsSupportedAlloc(const std::vector<VerifyAllocInfo return HDF_ERR_NOT_SUPPORT; } +int32_t DisplayBufferVdiImpl::RegisterBuffer(const BufferHandle& handle) +{ + DISPLAY_LOGE("%s is not supported", __func__); + return DISPLAY_NOT_SUPPORT; +} + +int32_t DisplayBufferVdiImpl::SetMetadata(const BufferHandle& handle, uint32_t key, const std::vector<uint8_t>& value) +{ + DISPLAY_LOGE("%s is not supported", __func__); + return DISPLAY_NOT_SUPPORT; +} + +int32_t DisplayBufferVdiImpl::GetMetadata(const BufferHandle& handle, uint32_t key, std::vector<uint8_t>& value) +{ + DISPLAY_LOGE("%s is not supported", __func__); + return DISPLAY_NOT_SUPPORT; +} + +int32_t DisplayBufferVdiImpl::ListMetadataKeys(const BufferHandle& handle, std::vector<uint32_t>& keys) +{ + DISPLAY_LOGE("%s is not supported", __func__); + return DISPLAY_NOT_SUPPORT; +} + +int32_t DisplayBufferVdiImpl::EraseMetadataKey(const BufferHandle& handle, uint32_t key) +{ + DISPLAY_LOGE("%s is not supported", __func__); + return DISPLAY_NOT_SUPPORT; +} + diff --git a/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.h b/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.h index 9cb70a4..8e22852 100755 --- a/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.h +++ b/rk3588/hardware/display/src/display_gralloc/display_buffer_vdi_impl.h @@ -38,6 +38,11 @@ public: virtual int32_t InvalidateCache(const BufferHandle& handle) const override; virtual int32_t IsSupportedAlloc(const std::vector<VerifyAllocInfo>& infos, std::vector<bool>& supporteds) const override; + virtual int32_t RegisterBuffer(const BufferHandle& handle) override; + virtual int32_t SetMetadata(const BufferHandle& handle, uint32_t key, const std::vector<uint8_t>& value) override; + virtual int32_t GetMetadata(const BufferHandle& handle, uint32_t key, std::vector<uint8_t>& value) override; + virtual int32_t ListMetadataKeys(const BufferHandle& handle, std::vector<uint32_t>& keys) override; + virtual int32_t EraseMetadataKey(const BufferHandle& handle, uint32_t key) override; }; } // namespace DISPLAY } // namespace HDI