您尚未登录。

楼主 # 2021-12-16 16:21:18

smiletiger
会员
注册时间: 2021-07-28
已发帖子: 74
积分: 30

f1c100s跑rttt+lvgl画面有撕裂感

f1c100s跑rttt+lvgl画面有撕裂感,已经启用了双缓冲模式,
flush函数如下,在这个函数print发现每次这个函数的area并不是液晶屏的尺寸,而是控件的尺寸,不是说定义了2个全尺寸的缓冲区之后每次都会全屏刷新的吗,
static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
   
    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)*/
            ((uint16_t *)lcd_layer0.vram)[y * lcd_layer0.width + x] = color_p->full;
            color_p++;
        }
 
}

离线

#1 2021-12-16 17:16:51

armstrong
会员
注册时间: 2019-04-10
已发帖子: 214
积分: 193.5

Re: f1c100s跑rttt+lvgl画面有撕裂感

启用全尺寸双缓存,需要这个标志
display_driver.full_refresh = 1;  /* 双完整帧缓存模式需要置1 */

离线

#2 2021-12-16 17:22:54

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,081
积分: 1043.5

Re: f1c100s跑rttt+lvgl画面有撕裂感

双缓冲不代表不撕裂。要做到不撕裂,还得在驱动那里实现vsync同步。否则你LCD刷到一半的时候,你缓存里的数据改了,LCD控制器是不知道的

离线

#3 2021-12-16 17:22:57

armstrong
会员
注册时间: 2019-04-10
已发帖子: 214
积分: 193.5

Re: f1c100s跑rttt+lvgl画面有撕裂感

不过,仅靠软件上是不能解决撕裂感的。双缓存的前后台切换需要与硬件的帧同步信号(游戏里叫垂直同步)配合才行。

离线

#4 2021-12-16 17:31:16

armstrong
会员
注册时间: 2019-04-10
已发帖子: 214
积分: 193.5

Re: f1c100s跑rttt+lvgl画面有撕裂感

lvgl\examples\porting\lv_port_disp_template.c

void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();

    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/

    /**
     * LVGL requires a buffer where it internally draws the widgets.
     * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
     * The buffer has to be greater than 1 display row
     *
     * There are 3 buffering configurations:
     * 1. Create ONE buffer:
     *      LVGL will draw the display's content here and writes it to your display
     *
     * 2. Create TWO buffer:
     *      LVGL will draw the display's content to a buffer and writes it your display.
     *      You should use DMA to write the buffer's content to the display.
     *      It will enable LVGL to draw the next part of the screen to the other buffer while
     *      the data is being sent form the first buffer. It makes rendering and flushing parallel.
     *
     * 3. Double buffering
     *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
     *      This way LVGL will always provide the whole rendered screen in `flush_cb`
     *      and you only need to change the frame buffer's address.
     */

    /* Example for 1) */
    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 2) */
    static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_1, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 3) also set disp_drv.full_refresh = 1 below*/
    static lv_disp_draw_buf_t draw_buf_dsc_3;
    static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
    static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*An other screen sized buffer*/
    lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/

    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = 480;
    disp_drv.ver_res = 320;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_1;

    /*Required for Example 3)*/
    //disp_drv.full_refresh = 1

    /* Fill a memory array with a color if you have GPU.
     * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
     * But if you have a different GPU you can use with this callback.*/
    //disp_drv.gpu_fill_cb = gpu_fill;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}

离线

楼主 #5 2021-12-17 09:19:46

smiletiger
会员
注册时间: 2021-07-28
已发帖子: 74
积分: 30

Re: f1c100s跑rttt+lvgl画面有撕裂感

我仔细看了一下源代码,好像如果液晶屏旋转90度也就是从竖屏改成横屏,全尺寸双缓冲就不支持了..............哭...

离线

楼主 #6 2021-12-17 09:23:16

smiletiger
会员
注册时间: 2021-07-28
已发帖子: 74
积分: 30

Re: f1c100s跑rttt+lvgl画面有撕裂感

@armstrong
static void lv_refr_vdb_rotate(lv_area_t * area, lv_color_t * color_p)
{
    lv_disp_drv_t * drv = &disp_refr->driver;
    if(lv_disp_is_true_double_buf(disp_refr) && drv->sw_rotate) {
        LV_LOG_ERROR("cannot rotate a true double-buffered display!");


这个是lvtl7.11的源代码,而且7.11里面没有display_driver.full_refresh = 1;  /* 双完整帧缓存模式需要置1 */这个功能,

不知道8.0以上能不能支持旋转90的双缓冲

离线

#7 2021-12-26 00:48:01

grantho
会员
注册时间: 2020-03-21
已发帖子: 59
积分: 40.5

Re: f1c100s跑rttt+lvgl画面有撕裂感

现在也是,7.11,旋转90度只能单缓存,而且经常卡死,不知道什么原因

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn