基于RK3588开发板实现多屏拼接
基于RK3588开发板实现多屏拼接
多屏拼接功能说明
将一组完整的画面分割为若干子画面分别送给不同的屏幕显示,可以支持下图的多种模式
硬件环境
基于RK3588 EVB开发板实现4屏拼接,RK3588 EVB开发有多个显示接口:
- 2个HDMI接口
- 1个type-c接口的DP
- 1个DP转VGA的接口
- 2个MIPI DSI接口
通过vop的split 模式可以实现6个屏同时异显输出1080P的分辨率,vop的split 介绍可以看专门的介绍文章《RK3588 VOP-SPLIT分屏模式介绍》。
这里选用2个HDMI+1个type-c接口的DP+1个MIPI DSI 四个接口来实现4屏拼接功能,如下图:
这四个显示接口的dts配置可以看文章《Rockchip RK3588 kernel dts解析之显示模块》
drmhwc2多屏拼接配置
多屏拼接的代码实现在drmhwc2,根据配置文件来配置对应的拼接模式,具体配置如下:
配置文件位于:hardware/rockchip/hwcomposer/drmhwc2/HwComposerEnv.xml
完整编译后会安装到设备 /vendor/etc/HwComposerEnv.xml 位置
下面是按水平2x2模式拼接4个屏幕:
系统渲染的分辨率设置为 5760x2160,那么对应Connector 显示的图像区域如下图:
根据上图,就能够很容易的得出4个 Connector 的 Src Info坐标:
ConnectorType-TypeId | SrcX | SrcY | SrcW | SrcH |
---|---|---|---|---|
HDMI-A-1 | 0 | 0 | 3840 | 1080 |
HDMI-A-2 | 3840 | 0 | 1920 | 1080 |
DP-0 | 0 | 1080 | 3840 | 1080 |
DSI-0 | 3840 | 1080 | 1920 | 1080 |
根据上面的信息hardware/rockchip/hwcomposer/drmhwc2/HwComposerEnv.xml的配置如下
<?xml version="1.0" encoding="utf-8"?><!-- HwComposerEnv module xml --><HwComposerEnv Version="1.1.1" > <DsiplayMode Mode="1" FbWidth="5760" FbHeight="2160" ConnectorCnt="4"> <Connector> <!-- Example 1 - Slicing-6x1 1920x1080: Type-TypeId can be obtained through the following process: adb shell modetest -c > modetest-connector.log Tips:Android_SDK_project: mmm external/libdrm/tests/modetestoutput modetest to $OUT/data/nativetest64/modetest/modetest The modetest-connector log has the following fields: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Connectors: id encoder status name size (mm)modes encoders 409 408 connectedHDMI-A-1 700x390 26 408modes: index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot #0 3840x1080 60.00 3840 4016 4104 4400 1080 1084 1089 1125 297000 flags: phsync, pvsync; type: preferred (...) 419 418 connected HDMI-A-2 510x290 10 418modes: index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot #0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver (...) 421 420 connected HDMI-A-3 510x290 10 420modes: index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot #0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver (...) 423 422 connected DP-1 1020x290 12 422modes: index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot #1 3840x1080 60.00 3840 4016 4104 4400 1080 1084 1089 1125 297000 flags: phsync, pvsync; type: driver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Type-TypeId = HDMI-A-1 Type-TypeId = HDMI-A-2 Type-TypeId = DP-1 Type-TypeId = DSI-1 --> <Type>HDMI-A</Type> <TypeId>1</TypeId> <SrcX>0</SrcX> <!-- Framebuffer x 0ffset --> <SrcY>0</SrcY> <!-- Framebuffer y 0ffset --> <SrcW>3840</SrcW> <!-- Framebuffer Width --> <SrcH>1080</SrcH> <!-- Framebuffer Height--> <DstX>0</DstX> <!-- unuse , reserved --> <DstY>0</DstY> <!-- unuse , reserved --> <DstW>0</DstW> <!-- unuse , reserved --> <DstH>0</DstH> <!-- unuse , reserved --> </Connector> <Connector> <Type>HDMI-A</Type> <TypeId>2</TypeId> <SrcX>3840</SrcX> <!-- Framebuffer x 0ffset --> <SrcY>0</SrcY> <!-- Framebuffer y 0ffset --> <SrcW>1920</SrcW> <!-- Framebuffer Width --> <SrcH>1080</SrcH> <!-- Framebuffer Height--> <DstX>0</DstX> <!-- unuse , reserved--> <DstY>0</DstY> <!-- unuse , reserved--> <DstW>0</DstW> <!-- unuse , reserved--> <DstH>0</DstH> <!-- unuse , reserved--> </Connector> <Connector> <Type>DP</Type> <TypeId>1</TypeId> <SrcX>0</SrcX> <!-- Framebuffer x 0ffset --> <SrcY>1080</SrcY> <!-- Framebuffer y 0ffset --> <SrcW>3840</SrcW> <!-- Framebuffer Width --> <SrcH>1080</SrcH> <!-- Framebuffer Height--> <DstX>0</DstX> <!-- unuse , reserved--> <DstY>0</DstY> <!-- unuse , reserved--> <DstW>0</DstW> <!-- unuse , reserved--> <DstH>0</DstH> <!-- unuse , reserved--> </Connector> <Connector> <Type>DSI</Type> <TypeId>1</TypeId> <SrcX>3840</SrcX> <!-- Framebuffer x 0ffset --> <SrcY>1080</SrcY> <!-- Framebuffer y 0ffset --> <SrcW>1920</SrcW> <!-- Framebuffer Width --> <SrcH>1080</SrcH> <!-- Framebuffer Height--> <DstX>0</DstX> <!-- unuse , reserved--> <DstY>0</DstY> <!-- unuse , reserved--> <DstW>0</DstW> <!-- unuse , reserved--> <DstH>0</DstH> <!-- unuse , reserved--> </Connector> </DsiplayMode></HwComposerEnv>
HwComposerEnv.xml配置说明
DsiplayMode
<DsiplayMode Mode="1" FbWidth="5760" FbHeight="2160" ConnectorCnt="4">
Mode 设置为1=Slicing,拼接模式
FbWidth / FbHeight,系统渲染分辨率,完整的图像尺寸,具体数值通过以下方式计算得来:
FbWidth = 3840 + 1920 = 5760 // 2x2 布局的拼接屏幕FbHeight= 1080 + 1080 = 2160 // 2x2 布局的拼接屏幕ConnectorCnt = 4 // 为系统内部注册的Connector数量
Connector
<Connector> <Type>HDMI-A</Type> <TypeId>1</TypeId> <SrcX>0</SrcX> <!-- Framebuffer x 0ffset --> <SrcY>0</SrcY> <!-- Framebuffer y 0ffset --> <SrcW>3840</SrcW> <!-- Framebuffer Width --> <SrcH>1080</SrcH> <!-- Framebuffer Height--> <DstX>0</DstX> <!-- unuse , reserved --> <DstY>0</DstY> <!-- unuse , reserved --> <DstW>0</DstW> <!-- unuse , reserved --> <DstH>0</DstH> <!-- unuse , reserved --> </Connector>
Connector Type 与 TypeId 信息可通过 modetest 工具获得,modetest工具可以通过源码编译获得的具体操作如下:
#modetest 编译mmm external/libdrm/tests/modetest#modetest 输出目录$OUT/data/nativetest64/modetest/modetest # 64位$OUT/data/nativetest/modetest/modetest # 32位#获取Drm Driver注册的所有Connector信息adb shell modetest -c > modetest-connector.log
在设备里面执行modetest - c获取ConnectorType 与 TypeId 信息
rk3588_s:/ # modetest - c ...Connectors:id encoder status name size (mm)modes encoders411 0disconnected HDMI-A-1 0x0 0410...421 0disconnected HDMI-A-2 0x0 0420...431 430 connectedDSI-1 0x0 1430... 434 0disconnected DP-1 0x0 0433... 440 0disconnected DP-2 0x0 0439...# ConnectorType 与 TypeId 从 Connector name 描述中获取:HDMI-A-1 / HDMI-A-2 / DP-1/DSI-1# 对应关系如下:# HDMI-A-1:ConnectorType = HDMI-A , TypeId = 1# HDMI-A-2:ConnectorType = HDMI-A , TypeId = 2# DSI-1:ConnectorType = DSI , TypeId = 1# DP-1 :ConnectorType = DP , TypeId = 1