1. 项目背景与核心问题
最近在RK3568开发板上折腾一个工业控制项目,需要把默认的横屏显示改为竖屏。选择eglfs插件是因为它在嵌入式Linux环境下渲染效率高、画面流畅,比传统的X11方案更适合资源受限的场景。但在实际落地时遇到了几个棘手问题:
- X11依赖问题:开发板的eglfs必须在X11桌面运行时才能正常工作,这导致系统内存被冗余的桌面环境占用
- Qt版本兼容性:开发板预装的Qt 5.12.8与开发机上的Qt 5.15.10存在兼容性问题,导致旋转功能表现不一致
- 触摸坐标不同步:屏幕旋转后,触摸事件的坐标轴仍保持原始方向
- 驱动层修改无效:虽然在驱动层修改了坐标转换逻辑,但Qt应用层获取的触摸事件仍未同步旋转
关键提示:eglfs是Qt专门为嵌入式设备设计的平台插件,直接通过DRM/KMS与GPU交互,省去了X11/Wayland的中间层,理论上性能更好。但在实际部署时,不同硬件平台的兼容性问题需要特别注意。
2. 脱离X11的eglfs部署方案
2.1 环境准备与权限配置
要让eglfs脱离X11独立运行,首先需要确保DRM设备有正确的访问权限:
bash复制# 临时赋予普通用户访问权限(生产环境建议配置udev规则)
sudo chmod 666 /dev/dri/card0
sudo chmod 666 /dev/dri/renderD128
2.2 清理图形环境残留
很多开发板默认启动X11或Wayland,这些环境变量会干扰eglfs的正常工作:
bash复制# 清除显示相关的环境变量
unset DISPLAY
unset WAYLAND_DISPLAY
# 强制使用标准GBM后端
export LD_LIBRARY_PATH="/lib/aarch64-linux-gnu:$LD_LIBRARY_PATH"
export GBM_BACKEND="drm"
2.3 Qt版本兼容性处理
开发板预装Qt 5.12.8,而开发机使用Qt 5.15.10时需要注意:
- 在开发机上用Qt 5.15.10编译时,添加
-qt5-compat编译选项 - 避免使用Qt 5.15新增的API,特别是图形相关的接口
- 测试时直接使用开发板上的Qt库:
bash复制export QT_PLUGIN_PATH=/usr/lib/aarch64-linux-gnu/qt5/plugins export QML2_IMPORT_PATH=/usr/lib/aarch64-linux-gnu/qt5/qml
3. 屏幕旋转90度实现
3.1 通过环境变量控制旋转
Qt eglfs插件支持通过环境变量设置屏幕旋转:
bash复制# 顺时针旋转90度
export QT_QPA_EGLFS_ROTATION="90"
# 启动应用(必须使用eglfs平台插件)
./your_app -platform eglfs
3.2 旋转参数详解
QT_QPA_EGLFS_ROTATION支持以下取值:
0:默认方向(不旋转)90:顺时针旋转90度180:旋转180度270:顺时针旋转270度(等同于逆时针90度)
实测发现:旋转方向与显示面板的原始坐标系有关,不同硬件可能需要尝试不同值。
3.3 硬件加速验证
旋转后可以通过以下命令验证是否真正使用了硬件加速:
bash复制# 查看DRM设备状态
sudo cat /sys/kernel/debug/dri/0/state
# 检查GPU负载
sudo cat /sys/class/misc/mali0/device/utilization
4. 触摸坐标同步旋转方案
4.1 最佳实践:libinput校准矩阵
通过libinput的校准矩阵实现坐标变换是最稳定的方案:
-
创建udev规则文件:
bash复制sudo nano /etc/udev/rules.d/99-touch-rotate.rules -
添加以下内容(根据实际触摸设备名修改):
text复制
ATTRS{name}=="Goodix Capacitive TouchScreen", \ ENV{LIBINPUT_CALIBRATION_MATRIX}="0 -1 1 1 0 0" -
应用规则:
bash复制sudo udevadm control --reload-rules sudo udevadm trigger --attr-match=name="Goodix Capacitive TouchScreen"
4.2 矩阵运算原理解析
校准矩阵"0 -1 1 1 0 0"对应的数学变换是:
code复制x' = 0*x + (-1)*y + 1*1 = -y + 1
y' = 1*x + 0*y + 0*1 = x
这实现了:
- 新x坐标 = 原始y坐标取反 + 偏移量
- 新y坐标 = 原始x坐标
4.3 坐标范围验证
使用evtest工具验证触摸坐标:
bash复制sudo apt install evtest
sudo evtest /dev/input/event1
正常应该看到旋转后的坐标范围(如原屏幕600x1024变为1024x600)
5. 其他方案对比与问题排查
5.1 驱动层修改方案(不推荐)
虽然可以直接修改触摸驱动(如goodix.c)添加旋转逻辑:
c复制static inline void rotate_90(u32 *x, u32 *y, u32 max_x, u32 max_y) {
u32 tmp = *x;
*x = max_y - *y;
*y = tmp;
}
但存在以下问题:
- 需要维护自定义内核驱动
- 不同Qt版本可能处理输入事件的方式不同
- 系统升级时容易丢失修改
5.2 Qt应用层转换(临时方案)
可以在Qt应用中添加事件过滤器:
cpp复制bool MainWidget::eventFilter(QObject *obj, QEvent *ev) {
if (ev->type() == QEvent::TouchUpdate) {
QTouchEvent *te = static_cast<QTouchEvent*>(ev);
QList<QTouchEvent::TouchPoint> pts = te->touchPoints();
for (auto &pt : pts) {
QPointF pos = pt.pos();
// 坐标转换
qreal tmp = pos.y();
pos.setY(size().width() - pos.x());
pos.setX(tmp);
pt.setPos(pos);
}
}
return false;
}
缺点:
- 增加输入延迟
- 某些Qt Quick组件可能表现异常
- 需要为每种输入事件类型单独处理
5.3 常见问题排查指南
现象:触摸方向正确但点击位置偏移
- 检查
LIBINPUT_CALIBRATION_MATRIX参数是否正确 - 验证屏幕物理方向与旋转设置是否匹配
- 使用
xinput_calibrator重新校准(需安装)
现象:旋转后画面撕裂
- 检查DRM驱动是否支持页面翻转:
bash复制cat /sys/class/graphics/fb0/capabilities - 尝试启用垂直同步:
bash复制export QT_QPA_EGLFS_VSYNC=1
现象:触摸无响应
- 检查设备权限:
bash复制ls -l /dev/input/event* - 确认使用的输入子系统:
bash复制
dmesg | grep -i input
6. 系统优化与部署建议
6.1 永久生效配置
-
将环境变量写入
/etc/environment:text复制
QT_QPA_PLATFORM=eglfs QT_QPA_EGLFS_ROTATION=90 LIBINPUT_CALIBRATION_MATRIX="0 -1 1 1 0 0" -
创建systemd服务单元自动启动应用:
ini复制[Unit] Description=My Qt Application After=graphical.target [Service] Environment="QT_QPA_PLATFORM=eglfs" ExecStart=/opt/myapp/my_application Restart=always User=root [Install] WantedBy=multi-user.target
6.2 性能调优参数
bash复制# 启用DRM原子模式设置(需要内核支持)
export QT_QPA_EGLFS_KMS_ATOMIC=1
# 指定显示输出(多屏时)
export QT_QPA_EGLFS_KMS_CONFIG=/etc/qt-eglfs-kms.json
# 禁用光标(节省资源)
export QT_QPA_EGLFS_HIDECURSOR=1
6.3 触摸屏高级配置
对于特殊需求的触摸设备,可以创建配置文件/etc/udev/rules.d/98-touchscreen.rules:
text复制ACTION=="add", KERNEL=="event[0-9]*", \
ATTRS{name}=="Goodix Capacitive TouchScreen", \
ENV{ID_INPUT_TOUCHSCREEN}="1", \
ENV{LIBINPUT_CALIBRATION_MATRIX}="0 -1 1 1 0 0", \
ENV{WL_CALIBRATION}="0 -1 1 1 0 0"
7. 实测效果与经验总结
经过实际部署验证,采用libinput校准矩阵的方案最稳定可靠。以下是关键指标对比:
| 方案 | CPU占用率 | 触摸延迟 | 兼容性 | 维护成本 |
|---|---|---|---|---|
| 驱动层修改 | 低 | 低 | 差 | 高 |
| Qt应用层转换 | 中 | 高 | 好 | 中 |
| libinput矩阵(推荐) | 低 | 低 | 好 | 低 |
几点重要经验:
- 不同Linux内核版本对触摸设备的��理可能有差异,建议测试4.19+内核
- Qt 5.15+对eglfs的旋转支持更完善,但需要关注内存占用
- 工业环境下建议禁用所有非必要的服务,减少内存占用
- 批量部署前务必在不同批次硬件上进行验证
