FB Q&A
Q1: 使用disp dev0的情况下,FB需要画鼠标和UI,这时如果想做一个表示录像中的红点,要不断闪烁,可以新增fbdev实现吗?
FB在disp dev0上可以通过设置FB_HWLAYER_ID配两个 FB_DEVICE,一个 FB_HWLAYER_ID = 0 ,另一个 FB_HWLAYER_ID = 1,分别对应GOP 0/1,也只有这2个GOP; FB_HWLAYER_ID = 0 这个已经给鼠标使用,FB_HWLAYER_ID = 1已经用来做了一层UI,所以目前情况不能新增fbdev了。这个需求可以通过往buffer写入不同数据来实现,参考drawrect函数接口。
Q2: FB 设定的颜色类型和HDMI设定的颜色类型需一致
-
fbdev.ini 中的FB_HWLAYER_OUTPUTCOLOR(GOP 输出的颜色空间设定 (0: RGB 1: YUV))
-
MI_HDMI_Attr_t结构体中的eColorType
typedef enum { E_MI_HDMI_COLOR_TYPE_RGB444 = 0, E_MI_HDMI_COLOR_TYPE_YCBCR422, E_MI_HDMI_COLOR_TYPE_YCBCR444, E_MI_HDMI_COLOR_TYPE_YCBCR420, E_MI_HDMI_COLOR_TYPE_MAX } MI_HDMI_ColorType_e;
Q3: 如何调整FB使用的内存空间?
FB的内存使用空间,由config.ini里面的FB_BUFFER_LEN所指定,需要更大的FB内存空间,可通过调节FB_BUFFER_LEN大小(计算单位为:KB)
Q4:设置1366x768@60分辨率时FB报错u32DisplayWidth alignment err,require 8
这是因为FB有硬件限制,FB_WIDTH 要 16/BytesPrePixel 对齐,这里用的ARGB1555格式,所以需要8对齐。
按如下修改即可正常。(注意FB只可以放大不能缩小,所以这里要向下对齐)
MI_FB_DisplayLayerAttr_t stDisplayAttr; memset(&stDisplayAttr, 0, sizeof(MI_FB_DisplayLayerAttr_t)); stDisplayAttr.u32SetAttrMask = E_MI_FB_DISPLAYLAYER_ATTR_MASK_SCREEN_SIZE | E_MI_FB_DISPLAYLAYER_ATTR_MASK_BUFFER_SIZE | E_MI_FB_DISPLAYLAYER_ATTR_MASK_DISP_SIZE | E_MI_FB_DISPLAYLAYER_ATTR_MASK_DISP_POS; stDisplayAttr.u32Xpos = 0; stDisplayAttr.u32YPos = 0; stDisplayAttr.u32dstWidth = width; stDisplayAttr.u32dstHeight = height; stDisplayAttr.u32DisplayWidth = width/8*8; //width stDisplayAttr.u32DisplayHeight = height; stDisplayAttr.u32ScreenWidth = width; stDisplayAttr.u32ScreenHeight = height; stDisplayAttr.eFbColorFmt = E_MI_FB_COLOR_FMT_ARGB1555; stDisplayAttr.eFbOutputColorSpace = E_MI_FB_OUTPUT_RGB; if (ioctl(g_fbFd, FBIOSET_DISPLAYLAYER_ATTRIBUTES, &stDisplayAttr)) { perror("Error: failed to FBIOSET_DISPLAYLAYER_ATTRIBUTES"); return; }
Q5:如何设置FB的分辨率对齐?
宽的对齐方式: 16 / BytesPrePixel ,其中BytesPrePixel 取决于你使用的像素格式 argb1555 BytesPrePixel = 2 , 对齐方式为 (16 / 2 = 8)8字节对齐 argb8888 BytesPrePixel = 4 , 对齐方式为 (16 / 4 = 4)4字节对齐
dst width(stDisplayAttr.u32dstWidth)不需要对齐;displaywidth(stDisplayAttr.u32DisplayWidth)需要对齐,height都不需要对齐。xres需要对齐,yres不需要对齐。
Q6:如何开关UI?
打开UI:echo GUI_SHOW 0 on > /proc/mi_modules/fb/mi_fb0
关闭UI:echo GUI_SHOW 0 off > /proc/mi_modules/fb/mi_fb0
Q7:是否支持两个UI层?
支持。一共支持三个gui层,前两个都是gui + cursor层,后面一个为gui层,具体怎么使用需要进行配置,配置方法请参考api文档说明。
我们默认使用两个:fb0和fb1,其中fb0配置为gui + cursor层,fb1为gui层。
Q8:初始化fb时,报如下错误,画面没有显示。
[MI ERR ]: MI_FB_IMPL_SetCursorAttr[3577]: fb:0 invalid cursor attr(xpos:100, ypos:100, hotSpotX:0, hotSpotY:0, alpha
错误原因是因为fb设置鼠标的属性失败,导致后面的fb没有启动起来。日志中的image的w为256,这个数值已经超过了支持标准,修改该参数为64后不再报该错误了。
以下是参数设置不正确的代码示例:
MI_FB_CursorAttr_t stCursorAttr; stCursorAttr.stCursorImageInfo.u32Width = 256; //大于128了,需要修改为小于128 stCursorAttr.stCursorImageInfo.u32Height = 64; ...... if (-1 == ioctl(frameBufferFd, FBIOSET_CURSOR_ATTRIBUTE, &stCursorAttr)) { printf("set cursor attribute failed\n"); }
注意:fb支持的图标的宽度和高度的最大值为128。
Q9:如何dump FB当前显示的UI?
-
cp /dev/fb0 /customer/fb0.yuv
-
dd if=/dev/fb0 of=/customer/fb0.yuv
使用yuv工具查看fb0.yuv就可以看到当前fb画的UI。
Q10:如何修改FB的内存大小?
-
进入boot,修改bootargs里面分配给fb的内存大小。如:
setenv bootargs ubi.mtd=ubia,2048 root=/dev/mtdblock5 rootfstype=squashfs ro init=/linuxrc LX_MEM=0x80000000 mma_heap=mma_heap_name0,miu=0,sz=0x40000000 mma_heap=mma_heap_fb,miu=0, sz=0x1020000 mma_memblock_remove=0 cma=2M mtdparts=nand0:1536k@1280k (BOOT),1536k(BOOT_BAK),256k(ENV),5m(KERNEL),5m(RECOVERY),6m(rootfs),1m (MISC),109056k(ubia)
只需要修改(sz=0x1020000)数据大小,其它部分的内容不需要修改,修改后保存(saveenv),重启设置生效。
这样处理的原因是:
参考kernel\include\uapi\linux\fb.h
struct fb_fix_screeninfo { char id[16]; /* identification string eg "TT Builtin" */ unsigned long smem_start; /* Start of frame buffer mem */ /* (physical address) */ ...... };
931是使用32位的kernel(950是64位kernel),所以这里smem_start(unsigned long)也是32位地址;而931通过mma分配的是64bit地址,所以要单独layout 一个fb 的mmap heap,目的是让它固定访问在4G (32位)的地址空间内,以保证fb访问正确的地址空间。
-
修改/misc/config.ini 中FB_DEVICE_0的 FB_BUFFER_LEN字段的内容,如:
FB_BUFFER_LEN = 16384
设置成功后,重启生效。
注意:bootargs中设置的fb的值大小,应该要大于等于/misc/config.ini 配置的所有使用到的fb device的FB_BUFFER_LEN的与所要使用到的cursor的个数 * 128k的和。
例:
FB_DEVICE_0的FB_BUFFER_LEN 配置 8M; FB_DEVICE_1的FB_BUFFER_LEN 配置 8M。且在程序中都有使用FB_DEVICE_0和FB_DEVICE_1以及它们对应的FB_CURSOR_0和FB_CURSOR_1
则bootargs的值则应该设置为:0x1040000 (即:8M + 8M+2*128k)