往期鸿蒙5.0全套实战文章必看:(文中附带全栈鸿蒙5.0学习资料)
概述
显示VDI(Vendor Device Interface)接口是为了方便芯片厂商接入OpenHarmony显示驱动框架模型而提供的接口。 显示VDI接口分为Composer和Buffer部分:
- Composer:负责图层(Layer)合成和显示。
- Buffer:负责申请和释放SurfaceBuffer。
Composer部分
图 1 Display Composer HDI架构
该框架模型内部分为三层,依次为框架层、HDI实现层、和Vendor驱动层。各层基本概念如下:
- 框架层:对接HDI实现层的控制、图层的显示和合成,管理显示模块各个硬件设备等功能。
- HDI实现层:实现OHOS(OpenHarmony Operation System)Composer HDI接口。
- Vendor驱动层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配。
Buffer部分
图 2 Display Buffer HDI架构
该框架模型内部分为三层,依次为框架层、HDI实现层、和Vendor驱动层。各层基本概念如下:
- 框架层:对接HDI实现层的控制、图形buffer的申请和释放。
- HDI实现层:实现OHOS(OpenHarmony Operation System)Buffer HDI接口。
- Vendor驱动层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配。
开发指导
Composer部分
接口说明
注:以下接口列举的为VDI接口,接口声明见文件/drivers/peripheral/display/composer/hdi_service/include/idisplay_composer_vdi.h
,获取路径为:drivers_peripheral: 暂无描述 - Gitee.com。
-
idisplay_composer_vdi.h
功能描述 接口名称 注册热插拔事件回调 int32_t RegHotPlugCallback(HotPlugCallback cb, void* data) 获取显示设备能力集 int32_t GetDisplayCapability(uint32_t devId, DisplayCapability& info) 获取显示设备支持的显示模式信息 int32_t GetDisplaySupportedModes(uint32_t devId, std::vector<DisplayModeInfo>& modes) 获取显示设备当前的显示模式 int32_t GetDisplayMode(uint32_t devId, uint32_t& modeId) 设置显示设备的显示模式 int32_t SetDisplayMode(uint32_t devId, uint32_t modeId) 获取显示设备当前的电源状态 int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus& status) 设置显示设备当前的电源状态 int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status) 获取显示设备当前的背光值 int32_t GetDisplayBacklight(uint32_t devId, uint32_t& level) 设置显示设备当前的背光值 int32_t SetDisplayBacklight(uint32_t devId, uint32_t level) 获取显示设备属性值 int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t& value) 获取显示设备合成类型有变化的layer int32_t GetDisplayCompChange(uint32_t devId, std::vector<uint32_t>& layers, std::vector<int32_t>& types) 设置显示设备的裁剪区域 int32_t SetDisplayClientCrop(uint32_t devId, const IRect& rect) 设置显示设备的显示缓存 int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle& buffer, int32_t fence) 设置显示设备的显示脏区 int32_t SetDisplayClientDamage(uint32_t devId, std::vector<IRect>& rects) 使能垂直同步信号 int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled) 注册VBlank事件回调 int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback cb, void* data) 获取显示图层fence int32_t GetDisplayReleaseFence(uint32_t devId, std::vector<uint32_t>& layers, std::vector<int32_t>& fences) 创建虚拟显示设备 int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t& format, uint32_t& devId) 销毁虚拟显示设备 int32_t DestroyVirtualDisplay(uint32_t devId) 设置虚拟屏的输出缓存 int32_t SetVirtualDisplayBuffer(uint32_t devId, const BufferHandle& buffer, const int32_t fence) 设置显示设备属性值 int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value) 提交合成送显请求 int32_t Commit(uint32_t devId, int32_t& fence) 打开图层 int32_t CreateLayer(uint32_t devId, const LayerInfo& layerInfo, uint32_t& layerId) 关闭图层 int32_t DestroyLayer(uint32_t devId, uint32_t layerId) 准备要送显的图层 int32_t PrepareDisplayLayers(uint32_t devId, bool& needFlushFb) 设置图层alpha值 int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, const LayerAlpha& alpha) 设置图层区域 int32_t SetLayerRegion(uint32_t devId, uint32_t layerId, const IRect& rect) 设置图层裁剪区域 int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, const IRect& rect) 设置图层Z轴次序 int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder) 设置图层预乘 int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul) 设置图层转换模式 int32_t SetLayerTransformMode(uint32_t devId, uint32_t layerId, TransformType type) 设置图层刷新区域 int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, const std::vector<IRect>& rects) 设置一个图层的可见区域 int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, std::vector<IRect>& rects) 设置一个层的缓冲区 int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle& buffer, int32_t fence) 设置客户端期望的组合类型 int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type) 设置混合类型 int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type) 设置图层蒙版信息 int32_t SetLayerMaskInfo(uint32_t devId, uint32_t layerId, const MaskInfo maskInfo) 设置纯色图层 int32_t SetLayerColor(uint32_t devId, uint32_t layerId, const LayerColor& layerColor)
开发步骤
下面以rk3568为例说明,Composer接入VDI开发过程主要包含以下步骤:
- 实现Composer VDI接口
芯片厂商应实现idisplay_composer_vdi.h中定义的接口,接口定义如下:
class DisplayComposerVdiImpl : public IDisplayComposerVdi {
public:
DisplayComposerVdiImpl();
virtual ~DisplayComposerVdiImpl();
virtual int32_t RegHotPlugCallback(HotPlugCallback cb, void* data) override;
virtual int32_t GetDisplayCapability(uint32_t devId, DisplayCapability& info) override;
virtual int32_t GetDisplaySupportedModes(uint32_t devId, std::vector<DisplayModeInfo>& modes) override;
virtual int32_t GetDisplayMode(uint32_t devId, uint32_t& modeId) override;
virtual int32_t SetDisplayMode(uint32_t devId, uint32_t modeId) override;
virtual int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus& status) override;
virtual int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status) override;
virtual int32_t GetDisplayBacklight(uint32_t devId, uint32_t& level) override;
virtual int32_t SetDisplayBacklight(uint32_t devId, uint32_t level) override;
virtual int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t& value) override;
virtual int32_t GetDisplayCompChange(uint32_t devId, std::vector<uint32_t>& layers,
std::vector<int32_t>& types) override;
virtual int32_t SetDisplayClientCrop(uint32_t devId, const IRect& rect) override;
virtual int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle& buffer, int32_t fence) override;
virtual int32_t SetDisplayClientDamage(uint32_t devId, std::vector<IRect>& rects) override;
virtual int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled) override;
virtual int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback cb, void* data) override;
virtual int32_t GetDisplayReleaseFence(uint32_t devId, std::vector<uint32_t>& layers,
std::vector<int32_t>& fences) override;
virtual int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t& format, uint32_t& devId) override;
virtual int32_t DestroyVirtualDisplay(uint32_t devId) override;
virtual int32_t SetVirtualDisplayBuffer(uint32_t devId, const BufferHandle& buffer, const int32_t fence) override;
virtual int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value) override;
virtual int32_t Commit(uint32_t devId, int32_t& fence) override;
virtual int32_t CreateLayer(uint32_t devId, const LayerInfo& layerInfo, uint32_t& layerId) override;
virtual int32_t DestroyLayer(uint32_t devId, uint32_t layerId) override;
virtual int32_t PrepareDisplayLayers(uint32_t devId, bool& needFlushFb) override;
virtual int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, const LayerAlpha& alpha) override;
virtual int32_t SetLayerRegion(uint32_t devId, uint32_t layerId, const IRect& rect) override;
virtual int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, const IRect& rect) override;
virtual int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder) override;
virtual int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul) override;
virtual int32_t SetLayerTransformMode(uint32_t devId, uint32_t layerId, TransformType type) override;
virtual int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, const std::vector<IRect>& rects) override;
virtual int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, std::vector<IRect>& rects) override;
virtual int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId,
const BufferHandle& buffer, int32_t fence) override;
virtual int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type) override;
virtual int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type) override;
virtual int32_t SetLayerMaskInfo(uint32_t devId, uint32_t layerId, const MaskInfo maskInfo) override;
virtual int32_t SetLayerColor(uint32_t devId, uint32_t layerId, const LayerColor& layerColor) override;
};
using CreateComposerVdiFunc = IDisplayComposerVdi* (*)();
using DestroyComposerVdiFunc = void (*)(IDisplayComposerVdi* vdi);
extern "C" IDisplayComposerVdi* CreateComposerVdi();
extern "C" void DestroyComposerVdi(IDisplayComposerVdi* vdi);
- 编译共享库
实现上述接口后,编译一个名为libdisplay_composer_vdi_impl.z.so的共享库。参考如下编译,BUILD.gn文件见device/soc/rockchip/rk3568/hardware/display/BUILD.gn
,获取路径为:rk3568/hardware/display/BUILD.gn · OpenHarmony/device_soc_rockchip - Gitee.com。
ohos_shared_library("libdisplay_composer_vdi_impl") {
sources = [ "src/display_device/display_composer_vdi_impl.cpp" ]
include_dirs = [
"src/display_device",
"${root_path}/drivers/peripheral/display/utils/include",
"${root_path}/drivers/interface/display/composer",
"${root_path}/drivers/peripheral/display/composer/hdi_service/include",
"${root_path}/drivers/interface/display/composer/hdifd_parcelable",
]
deps = [ ":display_composer_vendor" ]
external_deps = [
"c_utils:utils",
"drivers_interface_display:display_composer_idl_headers",
"graphic_chipsetsdk:buffer_handle",
"hilog:libhilog",
"ipc:ipc_single",
]
install_enable = true
install_images = [ chipset_base_dir ]
subsystem_name = "hdf"
part_name = "rockchip_products"
}
BUILD.gn文件编写好后,可以在项目的根目录执行如下命令进行编译:
./build.sh -p rk3568 -T display_composer_model
执行完成后,即可在目录out/rk3568/hdf/rockchip_products中找到名为libdisplay_composer_vdi_impl.z.so的共享库。
开发实例
OpenHarmony中有一个默认VDI实现,芯片厂商可参考此实现。见drivers/peripheral/display/composer/vdi_base
,获取路径为:drivers_peripheral: 暂无描述 - Gitee.com。
Buffer部分
接口说明
注:以下接口列举的为VDI接口,接口声明见文件/drivers/peripheral/display/buffer/hdi_service/include/idisplay_buffer_vdi.h
,获取路径为:drivers_peripheral: 暂无描述 - Gitee.com。
-
idisplay_composer_vdi.h
功能描述 接口名称 申请Buffer int32_t AllocMem(const AllocInfo& info, BufferHandle*& handle) 释放Buffer void FreeMem(const BufferHandle& handle) 将Buffer映射到内存 void* Mmap(const BufferHandle& handle) 解除Buffer内存映射 int32_t Unmap(const BufferHandle& handle) 刷新Buffer缓存 int32_t FlushCache(const BufferHandle& handle) 废弃Buffer缓存 int32_t InvalidateCache(const BufferHandle& handle) 判断是否能申请请求的buffer int32_t IsSupportedAlloc(const std::vector& infos, std::vector& supporteds) 注册Buffer int32_t RegisterBuffer(const BufferHandle& handle) 获取Buffer的元数据 int32_t GetMetadata(const BufferHandle& handle, uint32_t key, std::vector<uint8_t>& value) 列出所有元数据的key int32_t ListMetadataKeys(const BufferHandle& handle, std::vector<uint32_t>& keys) 清除指定key的元数据信息 int32_t EraseMetadataKey(const BufferHandle& handle, uint32_t key)
开发步骤
下面以rk3568为例说明,Buffer接入VDI开发过程主要包含以下步骤:
- 实现Buffer VDI接口
芯片厂商应实现idisplay_buffer_vdi.h中定义的接口,接口定义如下:
class DisplayBufferVdiImpl : public IDisplayBufferVdi {
public:
DisplayBufferVdiImpl();
virtual ~DisplayBufferVdiImpl();
virtual int32_t AllocMem(const AllocInfo& info, BufferHandle*& handle) const override;
virtual void FreeMem(const BufferHandle& handle) const override;
virtual void *Mmap(const BufferHandle& handle) const override;
virtual int32_t Unmap(const BufferHandle& handle) const override;
virtual int32_t FlushCache(const BufferHandle& handle) const override;
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;
};
using CreateDisplayBufferVdiFunc = IDisplayBufferVdi* (*)();
using DestroyDisplayBufferVdiFunc = void (*)(IDisplayBufferVdi* vdi);
extern "C" IDisplayBufferVdi* CreateDisplayBufferVdi();
extern "C" void DestroyDisplayBufferVdi(IDisplayBufferVdi* vdi);
- 编译共享库
实现上述接口后,编译一个名为libdisplay_buffer_vdi_impl.z.so的共享库。参考如下编译,BUILD.gn文件见device/soc/rockchip/rk3568/hardware/display/BUILD.gn
,获取路径为:rk3568/hardware/display/BUILD.gn · OpenHarmony/device_soc_rockchip - Gitee.com。
ohos_shared_library("libdisplay_buffer_vdi_impl") {
sources = [ "src/display_gralloc/display_buffer_vdi_impl.cpp" ]
public_configs = [ ":libdisplay_buffer_vdi_impl_config" ]
include_dirs = [
"./src/display_gralloc",
"${root_path}/drivers/peripheral/base",
"${root_path}/drivers/interface/display/composer/hdifd_parcelable",
"${root_path}/drivers/interface/display/buffer",
"${root_path}/drivers/peripheral/display/utils/include",
"${root_path}/drivers/peripheral/display/buffer/hdi_service/include",
]
output_name = "libdisplay_buffer_vdi_impl"
cflags = [
"-DGRALLOC_GBM_SUPPORT",
"-Wno-macro-redefined",
]
deps = [ ":libdisplay_buffer_vendor" ]
external_deps = [
"c_utils:utils",
"drivers_interface_display:display_buffer_idl_headers",
"drivers_interface_display:display_composer_idl_headers",
"hdf_core:libhdf_utils",
"hilog:libhilog",
"ipc:ipc_single",
]
install_enable = true
install_images = [ chipset_base_dir ]
innerapi_tags = [ "passthrough" ]
subsystem_name = "hdf"
part_name = "rockchip_products"
}
BUILD.gn文件编写好后,可以在项目的根目录执行如下命令进行编译:
./build.sh -p rk3568 -T display_buffer_model
执行完成后,即可在目录out/rk3568/hdf/rockchip_products中找到名为libdisplay_buffer_vdi_impl.z.so的共享库。
开发实例
OpenHarmony中有一个默认VDI实现,芯片厂商可参考此实现。