1# Display VDI 接入指南 2 3## 概述 4显示VDI(Vendor Device Interface)接口是为了方便芯片厂商接入OpenHarmony显示驱动框架模型而提供的接口。 5显示VDI接口分为Composer和Buffer部分: 6- Composer:负责图层(Layer)合成和显示。 7- Buffer:负责申请和释放SurfaceBuffer。 8 9### Composer部分 10 11**图 1** Display Composer HDI架构 12 13  14 15该框架模型内部分为三层,依次为框架层、HDI实现层、和Vendor驱动层。各层基本概念如下: 16 17+ 框架层:对接HDI实现层的控制、图层的显示和合成,管理显示模块各个硬件设备等功能。 18+ HDI实现层:实现OHOS(OpenHarmony Operation System)Composer HDI接口。 19+ Vendor驱动层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配。 20 21### Buffer部分 22 23**图 2** Display Buffer HDI架构 24 25  26 27该框架模型内部分为三层,依次为框架层、HDI实现层、和Vendor驱动层。各层基本概念如下: 28 29+ 框架层:对接HDI实现层的控制、图形buffer的申请和释放。 30+ HDI实现层:实现OHOS(OpenHarmony Operation System)Buffer HDI接口。 31+ Vendor驱动层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配。 32 33 34## 开发指导 35 36### Composer部分 37 38#### 接口说明 39 40注:以下接口列举的为VDI接口,接口声明见文件`/drivers/peripheral/display/composer/hdi_service/include/idisplay_composer_vdi.h`,获取路径为:[https://gitee.com/openharmony/drivers_peripheral/tree/master/display/composer](https://gitee.com/openharmony/drivers_peripheral/tree/master/display/composer)。 41- idisplay_composer_vdi.h 42 43 | 功能描述 | 接口名称 | 44 | ---------------------------- | ------------------------------------------------------------ | 45 | 注册热插拔事件回调 | int32_t RegHotPlugCallback(HotPlugCallback cb, void* data) | 46 | 获取显示设备能力集 | int32_t GetDisplayCapability(uint32_t devId, DisplayCapability& info) | 47 | 获取显示设备支持的显示模式信息 | int32_t GetDisplaySupportedModes(uint32_t devId, std::vector\<DisplayModeInfo\>& modes) | 48 | 获取显示设备当前的显示模式 | int32_t GetDisplayMode(uint32_t devId, uint32_t& modeId) | 49 | 设置显示设备的显示模式 | int32_t SetDisplayMode(uint32_t devId, uint32_t modeId) | 50 | 获取显示设备当前的电源状态 | int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus& status) | 51 | 设置显示设备当前的电源状态 | int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status) | 52 | 获取显示设备当前的背光值 | int32_t GetDisplayBacklight(uint32_t devId, uint32_t& level) | 53 | 设置显示设备当前的背光值 | int32_t SetDisplayBacklight(uint32_t devId, uint32_t level) | 54 | 获取显示设备属性值 | int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t& value) | 55 | 获取显示设备合成类型有变化的layer | int32_t GetDisplayCompChange(uint32_t devId, std::vector\<uint32_t\>& layers, std::vector\<int32_t\>& types) | 56 | 设置显示设备的裁剪区域 | int32_t SetDisplayClientCrop(uint32_t devId, const IRect& rect) | 57 | 设置显示设备的显示缓存 | int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle& buffer, int32_t fence) | 58 | 设置显示设备的显示脏区 | int32_t SetDisplayClientDamage(uint32_t devId, std::vector\<IRect\>& rects) | 59 | 使能垂直同步信号 | int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled) | 60 | 注册VBlank事件回调 | int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback cb, void* data) | 61 | 获取显示图层fence | int32_t GetDisplayReleaseFence(uint32_t devId, std::vector\<uint32_t\>& layers, std::vector\<int32_t\>& fences) | 62 | 创建虚拟显示设备 | int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t& format, uint32_t& devId) | 63 | 销毁虚拟显示设备 | int32_t DestroyVirtualDisplay(uint32_t devId) | 64 | 设置虚拟屏的输出缓存 | int32_t SetVirtualDisplayBuffer(uint32_t devId, const BufferHandle& buffer, const int32_t fence) | 65 | 设置显示设备属性值 | int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value) | 66 | 提交合成送显请求 | int32_t Commit(uint32_t devId, int32_t& fence) | 67 | 打开图层 | int32_t CreateLayer(uint32_t devId, const LayerInfo& layerInfo, uint32_t& layerId) | 68 | 关闭图层 | int32_t DestroyLayer(uint32_t devId, uint32_t layerId) | 69 | 准备要送显的图层 | int32_t PrepareDisplayLayers(uint32_t devId, bool& needFlushFb) | 70 | 设置图层alpha值 | int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, const LayerAlpha& alpha) | 71 | 设置图层区域 | int32_t SetLayerRegion(uint32_t devId, uint32_t layerId, const IRect& rect) | 72 | 设置图层裁剪区域 | int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, const IRect& rect) | 73 | 设置图层Z轴次序 | int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder) | 74 | 设置图层预乘 | int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul) | 75 | 设置图层转换模式 | int32_t SetLayerTransformMode(uint32_t devId, uint32_t layerId, TransformType type) | 76 | 设置图层刷新区域 | int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, const std::vector\<IRect\>& rects) | 77 | 设置一个图层的可见区域 | int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, std::vector\<IRect\>& rects) | 78 | 设置一个层的缓冲区 | int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle& buffer, int32_t fence) | 79 | 设置客户端期望的组合类型 | int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type) | 80 | 设置混合类型 | int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type) | 81 | 设置图层蒙版信息 | int32_t SetLayerMaskInfo(uint32_t devId, uint32_t layerId, const MaskInfo maskInfo) | 82 | 设置纯色图层 | int32_t SetLayerColor(uint32_t devId, uint32_t layerId, const LayerColor& layerColor) | 83 84#### 开发步骤 85下面以rk3568为例说明,Composer接入VDI开发过程主要包含以下步骤: 86 871. 实现Composer VDI接口 88 89芯片厂商应实现idisplay_composer_vdi.h中定义的接口,接口定义如下: 90 91```c++ 92 class DisplayComposerVdiImpl : public IDisplayComposerVdi { 93 public: 94 DisplayComposerVdiImpl(); 95 virtual ~DisplayComposerVdiImpl(); 96 virtual int32_t RegHotPlugCallback(HotPlugCallback cb, void* data) override; 97 virtual int32_t GetDisplayCapability(uint32_t devId, DisplayCapability& info) override; 98 virtual int32_t GetDisplaySupportedModes(uint32_t devId, std::vector<DisplayModeInfo>& modes) override; 99 virtual int32_t GetDisplayMode(uint32_t devId, uint32_t& modeId) override; 100 virtual int32_t SetDisplayMode(uint32_t devId, uint32_t modeId) override; 101 virtual int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus& status) override; 102 virtual int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status) override; 103 virtual int32_t GetDisplayBacklight(uint32_t devId, uint32_t& level) override; 104 virtual int32_t SetDisplayBacklight(uint32_t devId, uint32_t level) override; 105 virtual int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t& value) override; 106 virtual int32_t GetDisplayCompChange(uint32_t devId, std::vector<uint32_t>& layers, 107 std::vector<int32_t>& types) override; 108 virtual int32_t SetDisplayClientCrop(uint32_t devId, const IRect& rect) override; 109 virtual int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle& buffer, int32_t fence) override; 110 virtual int32_t SetDisplayClientDamage(uint32_t devId, std::vector<IRect>& rects) override; 111 virtual int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled) override; 112 virtual int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback cb, void* data) override; 113 virtual int32_t GetDisplayReleaseFence(uint32_t devId, std::vector<uint32_t>& layers, 114 std::vector<int32_t>& fences) override; 115 virtual int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t& format, uint32_t& devId) override; 116 virtual int32_t DestroyVirtualDisplay(uint32_t devId) override; 117 virtual int32_t SetVirtualDisplayBuffer(uint32_t devId, const BufferHandle& buffer, const int32_t fence) override; 118 virtual int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value) override; 119 virtual int32_t Commit(uint32_t devId, int32_t& fence) override; 120 virtual int32_t CreateLayer(uint32_t devId, const LayerInfo& layerInfo, uint32_t& layerId) override; 121 virtual int32_t DestroyLayer(uint32_t devId, uint32_t layerId) override; 122 virtual int32_t PrepareDisplayLayers(uint32_t devId, bool& needFlushFb) override; 123 virtual int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, const LayerAlpha& alpha) override; 124 virtual int32_t SetLayerRegion(uint32_t devId, uint32_t layerId, const IRect& rect) override; 125 virtual int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, const IRect& rect) override; 126 virtual int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder) override; 127 virtual int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul) override; 128 virtual int32_t SetLayerTransformMode(uint32_t devId, uint32_t layerId, TransformType type) override; 129 virtual int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, const std::vector<IRect>& rects) override; 130 virtual int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, std::vector<IRect>& rects) override; 131 virtual int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, 132 const BufferHandle& buffer, int32_t fence) override; 133 virtual int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type) override; 134 virtual int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type) override; 135 virtual int32_t SetLayerMaskInfo(uint32_t devId, uint32_t layerId, const MaskInfo maskInfo) override; 136 virtual int32_t SetLayerColor(uint32_t devId, uint32_t layerId, const LayerColor& layerColor) override; 137 }; 138 using CreateComposerVdiFunc = IDisplayComposerVdi* (*)(); 139 using DestroyComposerVdiFunc = void (*)(IDisplayComposerVdi* vdi); 140 extern "C" IDisplayComposerVdi* CreateComposerVdi(); 141 extern "C" void DestroyComposerVdi(IDisplayComposerVdi* vdi); 142``` 143 1442. 编译共享库 145 146实现上述接口后,编译一个名为libdisplay_composer_vdi_impl.z.so的共享库。参考如下编译,BUILD.gn文件见`device/soc/rockchip/rk3568/hardware/display/BUILD.gn`,获取路径为:[https://gitee.com/openharmony/device_soc_rockchip/blob/master/rk3568/hardware/display/BUILD.gn](https://gitee.com/openharmony/device_soc_rockchip/blob/master/rk3568/hardware/display/BUILD.gn)。 147 148``` 149 ohos_shared_library("libdisplay_composer_vdi_impl") { 150 sources = [ "src/display_device/display_composer_vdi_impl.cpp" ] 151 152 include_dirs = [ 153 "src/display_device", 154 "${root_path}/drivers/peripheral/display/utils/include", 155 "${root_path}/drivers/interface/display/composer", 156 "${root_path}/drivers/peripheral/display/composer/hdi_service/include", 157 "${root_path}/drivers/interface/display/composer/hdifd_parcelable", 158 ] 159 160 deps = [ ":display_composer_vendor" ] 161 162 external_deps = [ 163 "c_utils:utils", 164 "drivers_interface_display:display_composer_idl_headers", 165 "graphic_chipsetsdk:buffer_handle", 166 "hilog:libhilog", 167 "ipc:ipc_single", 168 ] 169 170 install_enable = true 171 install_images = [ chipset_base_dir ] 172 subsystem_name = "hdf" 173 part_name = "rockchip_products" 174 } 175``` 176BUILD.gn文件编写好后,可以在项目的根目录执行如下命令进行编译: 177 178``` 179 ./build.sh -p rk3568 -T display_composer_model 180``` 181执行完成后,即可在目录out/rk3568/hdf/rockchip_products中找到名为libdisplay_composer_vdi_impl.z.so的共享库。 182 183#### 开发实例 184 185OpenHarmony中有一个默认VDI实现,芯片厂商可参考此实现。见`drivers/peripheral/display/composer/vdi_base`,获取路径为:[https://gitee.com/openharmony/drivers_peripheral/tree/master/display/composer/vdi_base](https://gitee.com/openharmony/drivers_peripheral/tree/master/display/composer/vdi_base)。 186 187### Buffer部分 188 189#### 接口说明 190 191注:以下接口列举的为VDI接口,接口声明见文件`/drivers/peripheral/display/buffer/hdi_service/include/idisplay_buffer_vdi.h`,获取路径为:[https://gitee.com/openharmony/drivers_peripheral/tree/master/display/buffer](https://gitee.com/openharmony/drivers_peripheral/tree/master/display/buffer)。 192- idisplay_composer_vdi.h 193 194 | 功能描述 | 接口名称 | 195 | ---------------------------- | ------------------------------------------------------------ | 196 | 申请Buffer | int32_t AllocMem(const AllocInfo& info, BufferHandle*& handle) | 197 | 释放Buffer | void FreeMem(const BufferHandle& handle) | 198 | 将Buffer映射到内存 | void* Mmap(const BufferHandle& handle) | 199 | 解除Buffer内存映射 | int32_t Unmap(const BufferHandle& handle) | 200 | 刷新Buffer缓存 | int32_t FlushCache(const BufferHandle& handle) | 201 | 废弃Buffer缓存 | int32_t InvalidateCache(const BufferHandle& handle) | 202 | 判断是否能申请请求的buffer | int32_t IsSupportedAlloc(const std::vector<VerifyAllocInfo>& infos, std::vector<bool>& supporteds) | 203 | 注册Buffer | int32_t RegisterBuffer(const BufferHandle& handle) | 204 | 获取Buffer的元数据 | int32_t GetMetadata(const BufferHandle& handle, uint32_t key, std::vector<uint8_t>& value) | 205 | 列出所有元数据的key | int32_t ListMetadataKeys(const BufferHandle& handle, std::vector<uint32_t>& keys) | 206 | 清除指定key的元数据信息 | int32_t EraseMetadataKey(const BufferHandle& handle, uint32_t key) | 207 208#### 开发步骤 209下面以rk3568为例说明,Buffer接入VDI开发过程主要包含以下步骤: 210 2111. 实现Buffer VDI接口 212 213芯片厂商应实现idisplay_buffer_vdi.h中定义的接口,接口定义如下: 214 215```c++ 216 class DisplayBufferVdiImpl : public IDisplayBufferVdi { 217 public: 218 DisplayBufferVdiImpl(); 219 virtual ~DisplayBufferVdiImpl(); 220 221 virtual int32_t AllocMem(const AllocInfo& info, BufferHandle*& handle) const override; 222 virtual void FreeMem(const BufferHandle& handle) const override; 223 virtual void *Mmap(const BufferHandle& handle) const override; 224 virtual int32_t Unmap(const BufferHandle& handle) const override; 225 virtual int32_t FlushCache(const BufferHandle& handle) const override; 226 virtual int32_t InvalidateCache(const BufferHandle& handle) const override; 227 virtual int32_t IsSupportedAlloc(const std::vector<VerifyAllocInfo>& infos, 228 std::vector<bool>& supporteds) const override; 229 virtual int32_t RegisterBuffer(const BufferHandle& handle) override; 230 virtual int32_t SetMetadata(const BufferHandle& handle, uint32_t key, const std::vector<uint8_t>& value) override; 231 virtual int32_t GetMetadata(const BufferHandle& handle, uint32_t key, std::vector<uint8_t>& value) override; 232 virtual int32_t ListMetadataKeys(const BufferHandle& handle, std::vector<uint32_t>& keys) override; 233 virtual int32_t EraseMetadataKey(const BufferHandle& handle, uint32_t key) override; 234 }; 235 using CreateDisplayBufferVdiFunc = IDisplayBufferVdi* (*)(); 236 using DestroyDisplayBufferVdiFunc = void (*)(IDisplayBufferVdi* vdi); 237 extern "C" IDisplayBufferVdi* CreateDisplayBufferVdi(); 238 extern "C" void DestroyDisplayBufferVdi(IDisplayBufferVdi* vdi); 239``` 240 2412. 编译共享库 242 243实现上述接口后,编译一个名为libdisplay_buffer_vdi_impl.z.so的共享库。参考如下编译,BUILD.gn文件见`device/soc/rockchip/rk3568/hardware/display/BUILD.gn`,获取路径为:[https://gitee.com/openharmony/device_soc_rockchip/blob/master/rk3568/hardware/display/BUILD.gn](https://gitee.com/openharmony/device_soc_rockchip/blob/master/rk3568/hardware/display/BUILD.gn)。 244 245``` 246 ohos_shared_library("libdisplay_buffer_vdi_impl") { 247 sources = [ "src/display_gralloc/display_buffer_vdi_impl.cpp" ] 248 249 public_configs = [ ":libdisplay_buffer_vdi_impl_config" ] 250 251 include_dirs = [ 252 "./src/display_gralloc", 253 "${root_path}/drivers/peripheral/base", 254 "${root_path}/drivers/interface/display/composer/hdifd_parcelable", 255 "${root_path}/drivers/interface/display/buffer", 256 "${root_path}/drivers/peripheral/display/utils/include", 257 "${root_path}/drivers/peripheral/display/buffer/hdi_service/include", 258 ] 259 260 output_name = "libdisplay_buffer_vdi_impl" 261 cflags = [ 262 "-DGRALLOC_GBM_SUPPORT", 263 "-Wno-macro-redefined", 264 ] 265 deps = [ ":libdisplay_buffer_vendor" ] 266 267 external_deps = [ 268 "c_utils:utils", 269 "drivers_interface_display:display_buffer_idl_headers", 270 "drivers_interface_display:display_composer_idl_headers", 271 "hdf_core:libhdf_utils", 272 "hilog:libhilog", 273 "ipc:ipc_single", 274 ] 275 276 install_enable = true 277 install_images = [ chipset_base_dir ] 278 innerapi_tags = [ "passthrough" ] 279 subsystem_name = "hdf" 280 part_name = "rockchip_products" 281 } 282``` 283 284BUILD.gn文件编写好后,可以在项目的根目录执行如下命令进行编译: 285 286``` 287 ./build.sh -p rk3568 -T display_buffer_model 288``` 289执行完成后,即可在目录out/rk3568/hdf/rockchip_products中找到名为libdisplay_buffer_vdi_impl.z.so的共享库。 290 291#### 开发实例 292 293OpenHarmony中有一个默认VDI实现,芯片厂商可参考此实现。见`drivers/peripheral/display/buffer/vdi_base`,获取路径为:[https://gitee.com/openharmony/drivers_peripheral/tree/master/display/buffer/vdi_base](https://gitee.com/openharmony/drivers_peripheral/tree/master/display/buffer/vdi_base)。