I am trying to synchronize my logic with the display updates. This requires me to know when the calls I’ve made to draw to the screen have actually been processed. An example of this could be sounding a beep in sync with an icon blinking on the screen.
My LV_DISP_DEF_REFR_PERIOD is set to 30 ms, and we call lv_tick_inc(10)
every 10 ms. Yet, I’ve noticed that when I do significant updates, (such as updating a large image with lv_img_set_src()
then calling lv_obj_invalidate()
on that object) it can take around 250ms before my update appears on the display. That would be OK if I could tell when the updates were completed. Other updates like lv_obj_add_flag(myObj, LV_OBJ_FLAG_HIDDEN)
seem to be processed very quickly. This makes it very hard to synchronize.
Is there anything I can do to determine when the display has actually updated?
I’ve tried using lv_refr_now(NULL)
and monitoring lv_scr_act()->scr_layout_inv
and even tying it to my display driver in where we call lv_disp_flush_ready()
but I can’t seem to find a flow that tells me when the drawing is fully flushed.
Does anyone have any tips?
calling invalidate doesn’t update the display it just sets a marker so the next time task_handler is called it will update the display.
Thanks. I noticed that behavior. However, is there anything I can look at after my call to lv_task_handler()
to see if it’s really done? Or should it be expected to be done? I do not seem to see the update on the screen after that task runs. I even verified the lv_tick_inc
had been called. But it does update eventually. Maybe it’s the chunking the buffers to the display, or maybe the rendering requires multiple tasks.
You don’t need to check programmatically. It will be updated if you invalidated it.
The only way for me to know what is going on is you would have to post your code.
I agree it is updated after invalidating it. I also need to synchronize external behaviors with my display, though. So I need some mechanism to know when it finishes. Sometimes it is nearly instantaneous but other times it takes up to 250 ms. Is there anything I can look at when the entire screen is rendered to the hardware?
Thanks for the help on this. Your replies lead me to believe you had never seen these types of lags, so I double-checked my code. The “slow” updates were in a customized drawing method to the canvas. I didn’t want to invalidate on every pixel (default LVGL implementation) but inadvertently left the final invalidate
out of one of the paths. So it was a subsequent write that was invalidating. So now, I don’t see any long lags in drawing. I consider it “drawn” after I call lv_task_handler()
and everything is in tight sync now.
We might be able to get some better performance. If you answer these couple of questions it would help with being able to get some more speed out of your setup.
What is the hardware you are using, display IC model and The MCU model?
What is the connection topology for the display (SPI, I8080, RGB)?
What is the display size, w x h?
What is the color depth of the display (16 bit, 24 bit, etc…)?
How many frame buffers are you using?
What is the size you are setting for the frame buffer(s)?