天天看点

[问题记录]海思hifb设置Framebuffer的屏幕分辨率失败的问题(FBIOPUT_VSCREENINFO)

关于hifb修改屏幕分辨率的命令失败的问题,网上能查到的资料不多,因此现在就把自己调试时遇到的问题做一个记录。

首先认真阅读HiFB API参考.pdf文档,当中有对接口进行了描述,

如命令FBIOPUT_VSCREENINFO中注意中有一点:在压缩使能时,如果改变实际分辨率,需要先关闭压缩。

问题描述:通过FBIOGET_VSCREENINFO命令修改屏幕分辨率失败,接口报错提示参数非法或操作不允许。

排查过程:

1、屏幕分辨率默认为1280*720(hi3519平台),改小为720*576正常,改大则不行,报参数非法,因此怀疑是否支持分辨率;

2、通过接口获取能力集发现最大分辨率可到3840*2160,排除分辨率不支持的可能;

3、修改分辨率为1280*720,报操作不允许,即修改已设置的值也报错;

4、通过查资料发现是fb0分配的显存大小太小,因此需要根据分辨率来修改显存大小,分配显存大小计算方式参考HiFB开发指南.pdf

大体计算方式是:size = w * h * bit * mode;w、h为分辨率,bit是一个像素点占的字节数,mode是buffer模式,是否双buffer

5、修改load脚本(load3519)分配显存大小,insmod hifb.ko video="hifb:vram0_size:16200",还是提示操作不允许,查看

media-mem确实已分配成功;

6、调用FBIOGET_VSCREENINFO后,修改分辨率在调用FBIOPUT_VSCREENINFO设置,问题解决。

至于为什么要先获取再设置,我猜测是如果没有先获取,除了分辨率之外的其他参数的值是不确定或者为0,这样设置时就不能保证

每一个参数都是正确的。所以,最好是先获取,然后修改我们要配置的参数。海思提供的参考程序也是获取->修改->设置。

关于原理性的知识如下,以下内容为转载,方便以后查看:

HIFB层的简介(我们主要处理的是图形层数据)

1:Hisilicon Framebuffer是海思平台用于管理叠加图形层的模块,增加层间colorkey,层间colorkey mask,层间alpha,原点偏移等功能。HIFB一个子设备号对应一个叠加层,HIFB可以管理多个图形叠加层(意思就是说。HIFB可以支持多个子设备,支持多路输出)。

2:HIFB支持的标准功能:

a:将物理显存映射到虚拟内存中。

b:像操作普通文件一样操作物理显存。

c:设置像素分辨率,和像素格式,,每个叠加图形层的支持的最大分辨率和像素格式可以通过支持能力接口获取。

d:从物理显存的任何位置进行读写,显示等操作

e:在叠加图形层支持索引格式的情况下,支持设置和获取256色的调色板

增加的功能:

f:设置获取ALPHa和colorkey值

g:设置当前叠加图形层的其实位置(相对于屏幕原点的偏移)。以及叠加图形层的显示,隐藏状态。

5:

h:通过模块参数配置Hifb的物理显存大小和管理叠加图形层的数目。

I:添加抗闪烁功能,获取预乘模式的状态,压缩模式,获取内存检测状态,图形层刷新类型(2buffer类型)。

:::2buffer图形刷新类型是分配两个buffer,一个用来显示,一个用来绘制。

3:模块加载:默写linux framebuffer不支持运行期间更改分辨率,颜色深度,时序等显示属性,,因此linux在内核启动或者模块加载时,通过参数将相应选项传递给linux framebuffer,可以在内核加载器中配置内核启动参数,

HIFB驱动在加载时只能设置物理显存大小。(物理显存大小一经设置就不能改变)video=“hifb:vram0_size:xxx, vram1_size:xxx,…”其中,vramn_size:xxx 表示对叠加图形层n配置xxx K 字节的物理显存。

先加载fb.ko,然后加载hifb.ko参数。

对于标准Fb模式来说:

Vramn_size * 1024 >= xres_virtual * yres_virtual * bpp;

其中:xres_virtual * yres_virtual是虚拟分辨率,bpp是每个像素所占字节数。

******vramn_size 必须是PAGE_SIZE(4K byte)的倍数,否则HiFB 驱动强制将其设为PAGE_SIZE的

倍数,向上取整

默认参数值配置Hi3536

video="hifb:vram0_size:32400,

vram1_size:8100,vram2_size:1620,vram3_size:32,vram4_size:32" softcursor="off"

4:HIFB开发步奏:

a:调用open打开指定设备Hifb设备。

b:调用ioctl,函数设置hifb的像素格式以及屏幕高宽等参数。

c:调用ioctl函数获取Hifb所分配的物理显存大小,跨度等固定信息。可以使用层间colorkey(把一副图片的颜色扣掉叠加到另一张图片上),层间Alpha点(透明度参数),原点便宜等

d:物理显存映射到虚拟内存

e:完成具体的绘制任务。

f:解除显存映射

::::::::::::::::::

由于修改虚拟分辨率将改变Hifb的固定信息fb_fix_screeninfo::line_length(跨度),为保证绘制程序能够正确执行,推荐先设置HiFB的可变信息fb_var_screeninfo,再获取HiFB的固定信息fb_fix_screeninfo::line_length。.:

5:视频输出主要由设备层,视频层和图形层组成。

按设备层的配置输出一定的时序驱动与之相连的显示设备输出视频图形,同时设备层决定了设备分辨率。

设备层的操作都要关上视频层和图形层,在对设备层进行操作,这样才能显示正确的视频和图形。

所以在open(“dev/fbn”)之前先配置并且开启设备层。

每个设备层支持若干时序输出,,用户需要调用相关的接口使能设备层,然后操作图形层,才能看到结果。

SDK使用VOU 模块控制设备层。SDK的VOU模块提供设备层和视频层控制接口,其中操作设备层的接口包括:

HI_MPI_VO_Enable/HI_MPI_VO_Disable/HI_MPI_VO_SetPubAttr/HI_MPI_VO_GetPubAttr。