Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parts of the screens aren't redrawn #156

Open
olivluca opened this issue Apr 7, 2024 · 5 comments
Open

Parts of the screens aren't redrawn #156

olivluca opened this issue Apr 7, 2024 · 5 comments

Comments

@olivluca
Copy link

olivluca commented Apr 7, 2024

More than a bug report this is a plea for help: I made a simple display here using an esp32-2432S028R board.
It's an mqtt client that changes the text and color of some labels and/or shows/hides elements based on the topics received. It also switches betweeen a normal screen and an error screen.
Sometimes parts of the screen aren't refreshed, if I periodically invalidate the screen the issue is "fixed" but it slows everything down considerably.
This is the first time I use lvgl, squareline studio and this library, so maybe I'm missing something.
In the video the "Reset" button is shown based on a topic, the text of the label "E" depends on the same topic, the "17" and the scrolling label depend on a different topic. When I set the topics to 0 the labels text is empy and the button is hidden, however, as you can see, the texts take a while to disappear while the button stays there (but it's actually hidden since I cannot click on it).

trumadisplay.mp4

other times when I hide a spinner, parts of the spinner are still shown.

@olivluca
Copy link
Author

olivluca commented Apr 8, 2024

I actually think it's a bug in lvgl.
For the time being I just do this:

  //hack to try and fix the missing redraws of the screen
  //without this hacks, parts of the screen won't be redrawn
  //showing elements, or parts of element, that shouldn't be there
  //it works but it slows everything down.
  //I could use a longer delay, but then the scrolling label
  //will become jumpy, this way at least the scrolling is 
  //always slow with no sudden jumps
  
  if(millis()-refreshdelay>100) {
    refreshdelay=millis();
    lv_obj_invalidate(lv_scr_act());
  } 

@rzeldent
Copy link
Owner

Yes, looks like something in LVGL but this is rare. What I noticed is that the button at the button is touching the label. Maybe this works better if there is some more space around the button? Have you tried moving it around?
Are you setting the button to hidden and not just the internal text?

@olivluca
Copy link
Author

No it's not touching the label
imatge
and, yes, I'm setting the button to hidden
https://github.com/olivluca/TrumaDisplay/blob/3f15713f63e3ff83792d82b17cc9bf8bd8dabec3/src/main.cpp#L447
https://github.com/olivluca/TrumaDisplay/blob/3f15713f63e3ff83792d82b17cc9bf8bd8dabec3/src/main.cpp#L91

but it's not just the button, other parts aren't redrawn either (e.g., the spinner when hidden is partially shown, or text in some of the labels, etc.).
Anyway, calling lv_obj_invalidate(lv_scr_act()); every 100ms works around the issue, and even if the scrolling text isn't as smooth as without the lv_obj_invalidate, I prefer it this way: if I call it less often (say, every 500ms), there would be noticeable jumps in the scrolling.

@rzeldent
Copy link
Owner

Why not set the flag always?

void Show(lv_obj_t * obj, boolean show) {
show? lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN) : lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
}

@olivluca
Copy link
Author

olivluca commented Apr 17, 2024

Because internally lvgl changes a lot of state even if it's not necessary. e.g if I set (or clear) the hidden flag it invalidates the object, even if it already had (or hadn't) the flag set

void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f)
....
    if(f & LV_OBJ_FLAG_HIDDEN) {
        lv_obj_invalidate(obj);
        if(lv_obj_is_layout_positioned(obj)) {
            lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
            lv_obj_mark_layout_as_dirty(obj);
        }
    }

See, it doesn't check if the flag changed, it only checks the new value.
It should do no harm but it's a useless waste of resources (it's also a waste of resources to continually invalidate the screen, but since there is no other way to completely redraw the screen...)
In any case, it's not the cause of my lack of redraw problem (it did the same even before these optimizations).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants