硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3883|回复: 8
收起左侧

[LVGL] LVGL最最最新的屏幕绘制接口如何让实现

[复制链接]

19

主题

129

回帖

186

积分

初级会员

积分
186
QQ
发表于 2019-10-31 11:50:53 | 显示全部楼层 |阅读模式
昨天下载了最最最新的LVGL源程序,移植了一把,显示的不对应该还是显示的接口没有处理好
下面是注册显示驱动器的代码
001.PNG
他们提供的F429探索板demo的程序是新建了tft和touchpad源文件及头文件,然后重新注册一个显示驱动,在这里面设置显示以及读取触摸的回调函数

例如tft
void tft_init(void)
{
        static lv_color_t disp_buf1[TFT_HOR_RES * 40];
        static lv_disp_buf_t buf;
        lv_disp_buf_init(&buf, disp_buf1, NULL, TFT_HOR_RES * 40);

        lv_disp_drv_init(&disp_drv);
       
        /*Set the resolution of the display*/
        disp_drv.hor_res = 480;
        disp_drv.ver_res = 272;

        disp_drv.buffer = &buf;
        disp_drv.flush_cb = tft_flush;
        disp_drv.set_px_cb = tft_set_px;

        lv_disp_drv_register(&disp_drv);
}

标红的就是刷新以及填充像素的接口,这里是不使用硬件加速器的情况,否则跟硬件相关性太大了,不便移植

读取触摸很好理解,跟之前版本没什么变化

但是显示器这俩回调函数入口函数被实在看不懂什么意思

描述如下:
    /** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
     * called when finished */
    void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);

    /** OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
     * E.g. round `y` to, 8, 16 ..) on a monochrome display*/
    void (*rounder_cb)(struct _disp_drv_t * disp_drv, lv_area_t * area);

    /** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
     * Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
     * @note Much slower then drawing with supported color formats. */
    void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
                      lv_color_t color, lv_opa_t opa);

    /** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
     * number of flushed pixels */
    void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);


比较常用的就是较大的字体的两个了
这是demo里面的例子
/**
* Flush a color buffer
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_p pointer to an array of colors
*/
static void tft_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
        /*Return if the area is out the screen*/
        if(area->x2 < 0) return;
        if(area->y2 < 0) return;
        if(area->x1 > lcddev.width - 1) return;
        if(area->y1 > lcddev.height - 1) return;

        /*Truncate the area to the screen*/
        int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
        int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
        int32_t act_x2 = area->x2 > lcddev.width - 1 ? lcddev.width - 1 : area->x2;
        int32_t act_y2 = area->y2 > lcddev.height - 1 ? lcddev.height - 1 : area->y2;

        ...
}
尝试直接把color_p的full挨个填充到区域内是有问题的,值显示了一个小的条,而且可以看出是访问越界那种五彩斑斓的错误数据

找到了库里面的画点的调用

/**
* Put a pixel in the Virtual Display Buffer
* @param x pixel x coordinate
* @param y pixel y coordinate
* @param mask_p fill only on this mask (truncated to VDB area)
* @param color pixel color
* @param opa opacity of the area (0..255)
*/
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
{

    if(opa < LV_OPA_MIN) return;
    if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;

    /*Pixel out of the mask*/
    if(x < mask_p->x1 || x > mask_p->x2 || y < mask_p->y1 || y > mask_p->y2) {
        return;
    }

    lv_disp_t * disp    = lv_refr_get_disp_refreshing();
    lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
    uint32_t vdb_width  = lv_area_get_width(&vdb->area);

    /*Make the coordinates relative to VDB*/
    x -= vdb->area.x1;
    y -= vdb->area.y1;

    if(disp->driver.set_px_cb) {
        disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);
    } else {
        bool scr_transp = false;
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
        scr_transp = disp->driver.screen_transp;
#endif

        lv_color_t * vdb_px_p = vdb->buf_act;
        vdb_px_p += y * vdb_width + x;

        if(scr_transp == false) {
            if(opa == LV_OPA_COVER) {
                *vdb_px_p = color;
            } else {
                *vdb_px_p = lv_color_mix(color, *vdb_px_p, opa);
            }
        } else {
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
            *vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).ch.alpha, color, opa);
#endif
        }
    }
}


可以看到是首先调用的是填充像素函数
实现一下
static void tft_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
                      lv_color_t color, lv_opa_t opa)


这里的x,y可以理解应该是填充像素的位置,opa可以通过
if(opa < LV_OPA_MIN) return;
    if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;

得出应该是透明度吧,在极限值的时候显示底色还是直接显示颜色,即跳过不必要的计算
disp_drv应该是显示驱动器,看样子可以支持好多不同类型或者多个屏幕吧
buf应该是填充像素的缓存吧
buf_w是填充的宽度吧,不太明白

不知道大家有没有什么指导意见,欢迎一起讨论下

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
发表于 2019-10-31 14:03:33 | 显示全部楼层
帮顶下。
回复

使用道具 举报

19

主题

129

回帖

186

积分

初级会员

积分
186
QQ
 楼主| 发表于 2019-11-1 17:21:20 | 显示全部楼层
本帖最后由 lovelessing... 于 2019-11-2 08:57 编辑

昨天刚刚更新de TIM图片20191101172101.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
发表于 2019-11-2 08:41:32 | 显示全部楼层

最新的不就是6.0么,都发布几个月了。
回复

使用道具 举报

19

主题

129

回帖

186

积分

初级会员

积分
186
QQ
 楼主| 发表于 2019-11-2 08:59:22 | 显示全部楼层
eric2013 发表于 2019-11-2 08:41
最新的不就是6.0么,都发布几个月了。

前天刚更新的,主要我得先回几个字等审核过去之后编辑才可以配图,截图是几小时之前更新的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
发表于 2019-11-2 09:46:25 | 显示全部楼层
lovelessing... 发表于 2019-11-2 08:59
前天刚更新的,主要我得先回几个字等审核过去之后编辑才可以配图,截图是几小时之前更新的

不要跟这GITHUB溜,都是little更新,等他们网站正式版发布了再溜。

他更新的有问题,过几天又修改了,你岂不是累瘫。
回复

使用道具 举报

19

主题

129

回帖

186

积分

初级会员

积分
186
QQ
 楼主| 发表于 2019-11-2 10:28:59 | 显示全部楼层
eric2013 发表于 2019-11-2 09:46
不要跟这GITHUB溜,都是little更新,等他们网站正式版发布了再溜。

他更新的有问题,过几天又修改了, ...

好的,再看看6.0吧
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107220
QQ
发表于 2019-11-2 10:32:28 | 显示全部楼层

6已经做好了,参考移植即可

Littlevgl GUI相关总结(基于v6.0)-(包含模拟器及oled移植)
http://www.armbbs.cn/forum.php?m ... 4702&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

3

主题

26

回帖

35

积分

新手上路

积分
35
发表于 2019-11-2 15:02:38 | 显示全部楼层
不使能GPU的话移植很简单的,提供打点函数就可以了
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

    int32_t x;
    int32_t y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            /* Put a pixel to the display. For example: */
            /* put_px(x, y, *color_p)*/
                                                *(u16*)(LCD_FRAME_BUF_ADDR+(x+y*480)*2) = *(u16*)color_p;
            color_p++;
        }
        }
               
//    CUSTOM_DrawBitmap16bpp(0,area->x1,area->y1,(void *)color_p,area->x2,area->y2,480*2);
               
    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-22 03:09 , Processed in 0.297381 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表