将一组完整的画面分割为若干子画面分别送给不同的屏幕显示,可以支持下图的多种模式
基于RK3588 EVB开发板实现4屏拼接,RK3588 EVB开发有多个显示接口:
这里选用2个HDMI+1个type-c接口的DP+1个MIPI DSI 四个接口来实现4屏拼接功能,如下图:
这四个显示接口的dts配置可以看文章《Rockchip RK3588 kernel dts解析之显示模块》
多屏拼接的代码实现在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/modetest
output 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 connected HDMI-A-1 700x390 26 408
modes:
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 418
modes:
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 420
modes:
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 422
modes:
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>
<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>
<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 encoders
411 0 disconnected HDMI-A-1 0x0 0 410
.
.
.
421 0 disconnected HDMI-A-2 0x0 0 420
.
.
.
431 430 connected DSI-1 0x0 1 430
.
.
.
434 0 disconnected DP-1 0x0 0 433
.
.
.
440 0 disconnected DP-2 0x0 0 439
.
.
.
# 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