Display Flush Area Size

Description

I’m having an issue with the area size passed into the display flush function.

I’m using a 480x320 display, dual frame buffers sized at 1/10th of the display (480x32), and am using a rotary encoder for input.

When the screen is first loaded to the display, the framebuffers loaded entirely and the area passed to the flush function is as expected:

area->x1 = 0
area->x2 = 479
area->y1 = 0
area->y2 = 31
...
480 x 32 pixels

But when the framework draws a button that has been brought into focus (or to un-focus a previously focused button), the area is not as expected. For example, when I define a 100x100 button, the area is as follows:

static lv_style_t styleDefault;
lv_style_init(&styleDefault);
lv_style_set_outline_width(&styleDefault, 0);
lv_style_set_border_width(&styleDefault, 0);
lv_style_set_radius(&styleDefault, 10);
lv_style_set_pad_all(&styleDefault, 0);	
lv_style_set_bg_color(&styleDefault, lv_palette_main(LV_PALETTE_RED));

static lv_style_t styleFocused;
lv_style_init(&styleFocused);
lv_style_set_outline_width(&styleFocused, 0);
lv_style_set_border_width(&styleFocused, 0);
lv_style_set_radius(&styleFocused, 10);
lv_style_set_pad_all(&styleFocused, 0);	
lv_style_set_bg_color(&styleFocused, lv_palette_main(LV_PALETTE_GREEN));

_homeBackground = lv_obj_create(_homeScreen);
lv_obj_set_size(_homeBackground, 480, 320);
lv_obj_set_style_bg_color(_homeBackground, lv_palette_main(LV_PALETTE_BLUE), LV_STATE_DEFAULT | LV_PART_MAIN);
lv_obj_center(_homeBackground);

static lv_obj_t* button1 = NULL;
button1 = lv_button_create(_homeBackground);
lv_obj_remove_flag(button1, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_style(button1, &styleDefault, LV_STATE_DEFAULT | LV_PART_MAIN);
lv_obj_add_style(button1, &styleFocused, LV_STATE_FOCUSED | LV_PART_MAIN);
lv_obj_set_size(button1, 100, 100);
lv_obj_align_to(button1, _homeBackground, LV_ALIGN_CENTER, -75, 0);
lv_group_add_obj(lv_group_get_default(), button1);

static lv_obj_t* button2 = NULL;
button2 = lv_button_create(_homeBackground);
lv_obj_remove_flag(button2, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_style(button2, &styleDefault, LV_STATE_DEFAULT | LV_PART_MAIN);
lv_obj_add_style(button2, &styleFocused, LV_STATE_FOCUSED | LV_PART_MAIN);
lv_obj_set_size(button2, 100, 100);
lv_obj_align_to(button2, _homeBackground, LV_ALIGN_CENTER, 75, 0);
lv_group_add_obj(lv_group_get_default(), button2);

The flush function passes an object larger than the 100x100 box and draws the box incorrectly on the display. The two boxes are redrawn as two triangles, leading me to believe that the invalidated area is 1-2 pixels larger than the pixel data in the framebuffer.

area->x1 = 111
area->x2 = 219
area->y1 = 106
area->y2 = 214
...
108 x 108 pixels

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

GD32F303ZK MCU, custom PCB, Keil uVision AC6

What LVGL version are you using?

v9.2.2 in Keil uVision

What do you want to achieve?

I need some help understanding the flush function or how my flush callback could be handling the area incorrectly.

What have you tried so far?

I have reduced my flush function down to the the default and simplified example code found from the documentation:

static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)
{
    disp_writeBlock(area->x1, area->x2, area->y1, area->y2);

    for(int32_t y = area->y1; y <= area->y2; y++) {
        for(int32_t x = area->x1; x <= area->x2; x++) {
            DISPLAY_WRITE_DATA(*color_p);
            color_p++;
        }
    }

    lv_disp_flush_ready(disp_drv);
}

It seems to me like the area passed in is not aligning with the pixel map such that the right edge pixel data is being drawn incrementally farther in from the left side of the box, creating the diagonal line as shown.

The actual size of the box is not important - the box will be drawn properly with pad and borders, etc, if the area matched the pixel map. Thanks in advance for your thoughts and suggestions.

  • Taylor

In your lv_conf.h assure that LV_DRAW_BUF_STRIDE_ALIGN is 1 or disp_flush will add some bytes on every row to align the buffer

That was it. Thank you!