Description
I’m using an arc in a digital gauge UI design and it seems even small changes in the value of the arc cause the entire area taken up by the arc to be redrawn even though I’m using direct render mode.
What MCU/Processor/Board and compiler are you using?
STM32F7
What LVGL version are you using?
9.2
Code to reproduce
Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.
The code block(s) should be formatted like:
void create_screen_main() {
lv_obj_t *obj = lv_obj_create(0);
objects.main = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 480, 480);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_arc_create(parent_obj);
objects.obj0 = obj;
lv_obj_set_pos(obj, 103, 104);
lv_obj_set_size(obj, 274, 273);
lv_arc_set_value(obj, 25);
lv_arc_set_bg_end_angle(obj, 60);
}
}
}
int main() {
lv_init();
lv_tick_set_cb(HAL_GetTick);
lv_display_t* display = lv_display_create(480, 480);
lv_display_set_buffers(display, (void*) LVGL_GRAM_ADDR, NULL, 480*480*2, LV_DISP_RENDER_MODE_DIRECT);
lv_display_set_flush_cb(display, my_flush_cb);
ui_init();
uint32_t tick = 0;
uint16_t scale = 0;
while(1) {
if (HAL_GetTick() > tick + 20) {
if (scale > 100) {
scale = 0;
}
lv_arc_set_value(objects.obj0, scale);
//lv_label_set_text(objects.obj11, num);
scale += 1;
tick = HAL_GetTick();
lv_timer_handler();
}
}
}
Screenshot and/or video
For debuggin purposes I’m using the simple UI as above. Even with this one when I debug my code and hit a breakpoint in the flush callback I can notice that the area being re-drawn is the entire area taken up by the arc (not just the arc itself) which is significantly affecting the refresh rate.
In direct render mode I would expect that only the new small blue section of the arc as it moves would be drawn but for some reason its redrawing the entire rectangular area of the arc and I don’t understand why. This is my flush callback function:
void my_flush_cb(lv_display_t* display, const lv_area_t* area, uint8_t* map) {
if (!lv_display_flush_is_last(display)) {
return;
}
HAL_LTDC_SetAddress(&hltdc, (uint32_t) map, 0);
lv_display_flush_ready(display);
}
I’m using double buffering with LTDC so I’m just swapping the buffer start address of the LTDC peripheral. Whilst debugging I find that area->x1 = 90 area->x2 = 200, area->y1=90 and area->y2 = 200 when in reality only a small area of the area is actually changing. Any help would be greatly appreciated!
Thank you in advance.