Useless whole screen refresh


After updating lvgl in my project from v6 to v7.3, I saw huge lags in refreshing the chart, when I was touching the screen -even the zones that belong to lv_scr_act()-
I found that it’s because of the whole screen refresh the lvgl tries to do. so why this whole screen refresh is happening? How can prevent this useless refreshing?

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

stm32f429, cubeide, gcc

What LVGL version are you using?


What do you want to achieve?

prevent useless whole screen refresh.

You can try disabling click events on objects that don’t need them (like lv_scr_act() and container objects) to reduce the number of refreshes. I believe the extra refreshes are caused by objects’ states changing.

Do you mean by this function? :

lv_obj_set_click(obj, en)

But when there is no visual changes, why should it wants to refresh the whole screen.
I also have to say that I have a transparent object which covered the whole screen, and in its click event I close menus - if there is an open one.- so what should I do about this?

Yes, that’s the case. When you click something it will go to focused state. It’d be quite hard to tell whether the object was changed visually or not. (I have some ideas to do this but it needs some restructuring)

I’m not sure which theme you use but lv_theme_material applies a transition when the object goes to focuses state. During the transition animation the object is redrawn several times. You can disable this transitions by adding the LV_THEME_MATERIAL_FLAG_NO_TRANSITION to LV_THEME_DEFAULT_FLAG in lv_conf.h.

Unfortunately, It didn’t help.

/*Always enable at least on theme*/

/* No theme, you can apply your styles as you need
 * No flags. Set LV_THEME_DEFAULT_FLAG 0 */
 #define LV_USE_THEME_EMPTY       1

/*Simple to the create your theme based on it
 * No flags. Set LV_THEME_DEFAULT_FLAG 0 */

/* A fast and impressive theme.
 * Flags:
 * LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
 * LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
 * */

/* Mono-color theme for monochrome displays.
 * texts and borders will be black and the background will be
 * white. Else the colors are inverted.
 * No flags. Set LV_THEME_DEFAULT_FLAG 0 */
 #define LV_USE_THEME_MONO        1

#define LV_THEME_DEFAULT_INCLUDE            <stdint.h>      /*Include a header for the init. function*/
#define LV_THEME_DEFAULT_INIT               lv_theme_material_init
#define LV_THEME_DEFAULT_COLOR_PRIMARY      lv_color_hex(0x01a2b1)
#define LV_THEME_DEFAULT_COLOR_SECONDARY    lv_color_hex(0x44d1b6)

Is it right?
I remember that in ver6, At first I wanted to implement this with transparent btn object, But I had the same problem. you told me, use a transparent object. And it was fine. But now in ver 7.3 seems we got to the problem again.:sleepy:

I can suggest only a little bit hacky solution. lv_obj_signal sets the new states if an event happens. You can replace it with a custom one where the state changes are removed.

Would it be useful to have a flag that disables state changes on an object? That could make it easier to optimize this sort of thing.

No… :confused:

These are good features. I need them. I just need to not refresh the object when it is not necessary. -when there is no change or it’s transparent e.g in focused state.-

I commented this line:

lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);

in lv_obj_set_state function. It seems ok, except that I missed the visual effect I want in some other places.
So It seems that the bottleneck is here. maybe we can check a flag or any change in style or … to not call this function when it’s not necessary. what do you think?

Let’s talk about it. It’s a very important problem. I’m so curious why it didn’t make any problem for others. I’m ready to help.

1 Like

It’s only noticeable on platforms where a full screen refresh takes a lot of time. Anyone who’s scrolling fullscreen objects won’t see an issue since the whole screen gets redrawn anyways.

I agree that it needs improving.

1 Like

In the most simple case, we need to compare all properties of state A with B. If there is no change no need to redraw. It should be done on every virtual part of the object too. (e.g. slider knob also goes to pressed state).
It’s about 100 queries per state per part. E.g. 100 x 2 states x 2 parts = 400 queries.
However, some optimization can be applied:

  • break on the first difference: if there is a change in the styles probably we will quickly find it if the most relevant properties are checked first.
  • exclude not visible properties: e.g. if border_widht is zero, border_color is irrelevant.

So we can add a well-optimized function to tests the difference between 2 states. If it says there is no difference between the 2 states just set the state and return without refresh.

What do you think?

Provided that we can get that function to run faster than a refresh does, I see no problem with this. An alternative option is to add a flag that requires users to manually refresh the styles on a state change.

Sounds great, but as you said, I’m afraid it would decrease the overall performance, especially in small objects or in objects with more than one part. Maybe we should test and see how it is.

It’s good idea. If the @kisvegabor idea didn’t work well I think it’s a good alternative.

As another idea, what about this:
What If we save the need to refresh in bitfields for every state.
Forexample, Consider a byte for a pressed state that each bits shows if it needs a refresh when changed to another states. And these flags are set whenever the style of the object is getting set.
I think, it’s more complicated than the @kisvegabor 's method, but seems faster to me.

I think it shouldn’t be that slow because most of the style properties need to be get for drawing too. And after getting properties there is the drawing which takes most of the time.

I’ve just realized that we can cover most of the properties by using lv_obj_init_draw_rect_dsc (and similars for label, image and line) and compare only the draw descriptors. These functions are already well optimized.

1 Like

OK, if say so.
Let’s see how it is.

I’ll add it this week.

Thank you very much Gabor. :pray:


I pushed it to the dev branch, but can’t test it on embedded hardware yet. It workes well in the simulator.

Can you try it out?

1 Like

Thanks, yes of course.
I will try it out ASAP, and let you know the result.

Yeah, It seems great. thanks, again🌺

At first, I saw no difference, after looking to the lv_obj_set_state I found you implement it for LV_USE_ANIMATION == 1.
Will you implement it for the other state too?

Yes - perfect. But it works for only enabled use animation.In my project I don’t use animation because I have slow display communication. So I need it also for LV_USE_ANIMATION == 0.