Use V8.1.0 double buffer flashing? How to fix it?


I am using V8.1.0, and the display driver uses double buffering (modify the buffer address to refresh the display). Running the “lv_demo_music” template will cause a splash screen problem.

What MCU/Processor/Board and compiler are you using?

F1C100S(Run freertos),MDK

What have you tried so far?

  1. I tried to record the entire flashing process with my mobile phone. The flashing is like adding a mask to the screen.
  2. I have tried many versions, in 7.2.0 7.11.0 8.0 8.1, this problem will appear on the development board.
  3. I tried to test the F1C100S refresh frame rate, 800*480 RGB565 can reach 60Hz.
  4. I try to solve this problem by waiting 20ms after setting the buffer address, but I think this is very unreasonable.

Code to reproduce

This is my display driver code:

void lv_port_disp_init(void)
    /* Example for 3) also set disp_drv.full_refresh = 1 below*/
    static lv_disp_draw_buf_t draw_buf_dsc_3;
    static __align(32) lv_color_t buf_3_1[800 * 480];            /*A screen sized buffer*/
    static __align(32) lv_color_t buf_3_2[800 * 480];            /*An other screen sized buffer*/
    lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, 800 * 480);   /*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 = 800;
    disp_drv.ver_res = 480;

    /*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_3;

    /*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*/

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*/
    atk_fb_set_present(lcd_fb, 0, color_p); /* Set buffer address */

Screenshot and/or video

My STM32F4+LTDC Double buffer setup had the same problem like you. Also Adding a delay after setting buffer address could help this. I thought the proper way to solve this is adding VSYNC functionality.
But in my project setting address for double buffering performed much slow than Copying, so impl vsync for me is not needed.

Spent a few hours with this issue as well on 8.3, also running a double full sized frame buffer setup for double buffering and swapping frame buffer pointers in flush_cb.

After digging into the issue it seems like returning from flush_cb to _lv_disp_refr_timer before the LCD controller asserts VSYNC can cause issues like the tearing seen in the video above.

Solution is to add a slight delay before returning from flush_cb, this can be done via a delay or by checking for the VSYNC signal being asserted.