1. 需求(问题)描述
移植Qt5.5.1 with egl 到嵌入式开发平台,现在要更改屏幕的分辨率,目前是1280x720,需要更改至1920x1080。
2. Try 1
直接更改Qt的环境变量:
export QT_QPA_EGLFS_HEIGHT='1080'
export QT_QPA_EGLFS_WIDTH='1920'
运行程序,报错如下:
EGL Error : Could not create the egl surface: error = 0x300b
Aborted
错误显示,无法创建egl。Qt读到1920x1080的环境变量,拿着这个配置向系统申请创建这么大的egl surface,无奈系统无情地拒绝了Qt。
2.1 分析原因
虽然Qt软件知道这个分辨率,但是系统不知道啊。所以应该要告诉系统,我的分辨率配置。
3. Try 2
怎么更改系统的配置?前辈告诉我说,需要在设备初始化的地方设置,而linux对于显示,有两部分:一个是hdmi硬件设备,另一个是fb设备。在官方例子里找到hdmi初始化的代码,fb设备的初始化在linux里面,统一是调用读写设备的函数
ioctl()来实现。
把这两部分代码加到Qt app的main函数刚刚启动的地方,运行。为了检验是不是的确修改了设备的配置,我还在代码里通过QScreen读取显示设备的大小。另外,由于一切
设备在linux中,都是以文件的形式存在,所以,可以用这个命令:
cat /proc/umap/hdmi0
cat /proc/umap/hifb0
来查看设备的当前配置。
然而,这回的问题是,程序没有报错,然而屏幕并没有渲染出Qt界面。
最痛苦的,莫过于,没有报错的异常情况。
3.1 分析原因
我辣知道什么原因!!在对底层细节不甚清楚的情况下,有没法跟之前的问题一样,查看Qt源代码,毕竟这个错误并不是Qt内部的错误,只能求助于
官方例子。找能运行的代码,改分辨率,各种改,看会不会重现Qt这个程序的错误。
4. Try 3
找到了,原来使用egl进行图形渲染的时候,不能设置fb,或者说设置地不对,以致与影响了egl渲染。Qt5.5.1使用gpu来渲染界面,即借助egl直接对显示器进行渲染,并没有涉及fb设备。
调用这句话:
hi_egl_setup(0, 0, width, height, sampling, 1);
来对egl进行设置,这个函数里面有对hdmi设置的地方。它默认是1280x720。
如果需要修改,则要改两个地方:
1. hi_egl_setup()输入参数。
2. stPubAttr.enIntfSync = VO_OUTPUT_1080P60 和 stPubAttr.enIntfType = VO_INTF_HDMI。
5. Solution
最终解决方案是,修改3个地方:
1. Qt的环境变量,告诉Qt应用程序需要的分辨率。
2. egl初始化,让egl知道要常见多大的surface。
3. hdmi硬件,设置硬件底层的分辨率配置。这个配置设置后,可以从显示器里看到分辨率的改变。