I’m currently trying to improve the performance/experience when using the RGB peripheral on the ESP32-S3 with LVGL (also see this related issue on the ESP-IDF repository).
By configuring the ESP-IDF RGB display driver to
relax_on_idle and making some small tweaks to the ESP-IDF for now, I’m able to make sure that LVGL decides when a frame is “clocked out” to the RGB panel.
This means that in the
lvgl_flush_cb I simply copy the data to the buffer used by the RGB peripheral.
false, I immediately call the
If it returns
true, I tell the RGB peripheral to start transmitting the frame and call
lv_disp_flush_ready from the callback/interrupt I get from the RGB peripheral when the transmission is done.
I do this to prevent “tearing”, which can be caused by writing to the same buffer as is currently being “clocked out” to the panel.
This works rather well for screens that have a continuous animation going on.
Unfortunately for screens that do not have an animation going on, the RGB panel starts blinking because the time in between frames is too much.
I can solve this by restarting the transmission of the frame myself when I get the callback/interrupt from the peripheral, but then I have to prevent LVGL from calling
lvgl_flush_cb. I’m not aware of a function to “pause” rendering for a while, other than not calling
lv_disp_flush_ready after the flush callback is called.
ESP32-S3 with RGB interface
Postpone the rendering while a frame is being transmitted, or have LVGL call
lvgl_flush_cb more often, even if there are no updates.
I tried simply “caching” the arguments to
lvgl_flush_cb, but the pointers I receive as arguments are not valid outside of the callback (at least, when I tried this, I got garbage on my screen).