lvgl_双buffer-TJpgDec解码-gfx加速绘图

1. lvgl_sigmastar

  • lvgl_sigmastar版和lvgl官方版的主要区别为:
    sigmastar版有双buffer操作的接口,lvgl也提供接口但是没有具体实现,需要根据实际情况进行补全
    //sigmastar刷新回调
    disp_drv.flush_cb = sstar_flush_cb;
    //lvgl刷新回调
    disp_drv.flush_cb = fbdev_flush;

sigmastar版绘图为GFX绘图引擎,sigmastar平台提供。官方版默认sw软件绘图。

    //sigmastar硬件绘图回调
    draw_sw_ctx->blend = sstar_gfx_blend_cb;
    //lvgl软件绘图回调
    draw_sw_ctx->blend = lv_draw_sw_blend_basic;

2. lvgl的jpg显示流程图

在这里插入图片描述

3. lvgl_sigmastar的双buffer实现逻辑

参考资料

  • 调用fbdev_init获取底层驱动信息
    fbdev_init主要通过fb0获取vinfo(屏显信息)和finfo(图层信息),及fbp(内存映射指针)
  • 创建和初始化disp_drv与disp_buf
    根据fb0的数据填充disp_drvdisp_buf,以及绑定sigmastar的刷新回调disp_drv.flush_cb = sstar_flush_cb

3.1 双buffer实现大体逻辑图

lvgl在每次更新fbdev后,都会主动切换lvgl的缓存帧,实现的主要函数为:sstar_flush_cbdraw_buf_flush

在这里插入图片描述

3.2 sstar_flush_cb帧切换

  • sstar_flush_cb的逻辑为:
void sstar_flush_cb(struct _lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    LV_LOG_TRACE("%s-> Calling flush_cb on (%d;%d)(%d;%d) area with color_p:%p image pointer\033[0m\n",
            color_p == disp_drv->draw_buf->buf1 ? "\033[0;35m" : "\033[0;36m",
            area->x1, area->y1, area->x2, area->y2, (void *)color_p);
    //sstar_gfx_wait();
    if (disp_drv->full_refresh) {                       //  先判断是否整体刷新 lvgl双buffer下full_refresh设置1
        sstar_fbdev_flush(color_p);                     //  显存地址切换,通过color_p来判断是否更新lcd驱动的显存地址
        lv_disp_flush_ready(disp_drv);                  //  通知lcd驱动更新刷新显示
        return;
    }
    if (disp_drv->draw_buf->flushing_last) {
        sstar_fbdev_flush(color_p);
    }
    ``````````
    ``````````
    lv_disp_flush_ready(disp_drv);
}

3.3 draw_buf_flush切换的活动buf

通过sstar_flush_cb函数可以看到颜色数据通过color_p 传递出来,那么lvgl怎么知道将解析的颜色数据丢到那个buf呢?
lv_disp_draw_buf_init初始化时,默认设置活动buf为buf1。

    void lv_disp_draw_buf_init(lv_disp_draw_buf_t * draw_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt)
{
    lv_memset_00(draw_buf, sizeof(lv_disp_draw_buf_t));

    draw_buf->buf1    = buf1;
    draw_buf->buf2    = buf2;
    draw_buf->buf_act = draw_buf->buf1;
    draw_buf->size    = size_in_px_cnt;
}

sstar_flush_cb更新fbdev数据并显示后,对draw_buf->buf_act进行切换。

 // Flush the content of the draw buffer
static void draw_buf_flush(lv_disp_t * disp)
{
    lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);

    ```````
    ```````
    if(disp->driver->flush_cb) {        //调用sstar_flush_cb ,通知lcd显示
            /*Rotate the buffer to the display's native orientation if necessary*/
            if(disp->driver->rotated != LV_DISP_ROT_NONE && disp->driver->sw_rotate) {
                draw_buf_rotate(draw_ctx->buf_area, draw_ctx->buf);
            }
            else {
                call_flush_cb(disp->driver, draw_ctx->buf_area, draw_ctx->buf);
            }
        }
 
    if(draw_buf->buf1 && draw_buf->buf2 && (!disp->driver->direct_mode || flushing_last)) {
        if(draw_buf->buf_act == draw_buf->buf1)
            draw_buf->buf_act = draw_buf->buf2;
        else
            draw_buf->buf_act = draw_buf->buf1;
    }
}

更新绘画区域,lvgl直接操作draw_ctx->buf进行填充,调用flush回调传入draw_ctx->buf

static void lv_refr_area(const lv_area_t * area_p)
{
    lv_draw_ctx_t * draw_ctx = disp_refr->driver->draw_ctx;
    draw_ctx->buf = disp_refr->driver->draw_buf->buf_act;

}

call_flush_cb(disp->driver, draw_ctx->buf_area, draw_ctx->buf);

3.4 lvgl显存切换逻辑

sstar_flush_cb---》sstar_fbdev_flush
sstar_fbdev_flush下,判断color_p是否和framebuffer为同一块地址开始,framebuffer为内存映射首地址即buf1地址,也就是判断color_p是在buf1还是在buf2上,如果在buf1,更新显存偏移量。参考资料

        uint32_t yoffset = (char*)color_p == framebuffer ? 0 : vinfo.yres;
            if (yoffset == vinfo.yoffset) {
                return;
            }
            vinfo.yoffset = yoffset;
            if (-1 == ioctl(fd, FBIOPAN_DISPLAY, &vinfo)) {
                printf("BUG_ON: FBIOPAN_DISPLAY.\n");
                exit(-1);
            }

在这里插入图片描述

3.5 lvgl官网版的双buffer无效原因

lvgl自带的fbdev_flush为简单的将颜色数据拷贝到内存上,所以lvgl设置双buffer,但是没有实际对双buffer的使用。

void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
    ````````
    ````````
    /*32 bit per pixel*/
    if(vinfo.bits_per_pixel == 32) {
        uint32_t * fbp32 = (uint32_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 4;
            memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
            color_p += w;
        }
    }
      lv_disp_flush_ready(drv);
}

4. lvgl_sigmastar的gfx(硬件加速绘图)

具体使用:
draw_sw_ctx->blend = sstar_gfx_blend_cb;
GFX(Graphic Engine)硬件为用户画UI提供快速的图形绘制功能。

主要功能: 矩形色彩填充
位图搬移(支持缩放、旋转、镜像翻转、格式转换、alpha混合叠加、ColorKey等操作)

gfx的工作流程:通过快速处理clip和DstRect的重叠部分,处理完后可指定物理内地址输出
在这里插入图片描述

矩形色彩填充
位图搬移(支持缩放、旋转、镜像翻转、格式转换、alpha混合叠加、ColorKey等操作)

gfx的工作流程:通过快速处理clip和DstRect的重叠部分,处理完后可指定物理内地址输出
[外链图片转存中…(img-Urpsw4WV-1709692778993)]

  • 22
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值