lvgl
lvgl copied to clipboard
Is it possible to access the draw buffer directly without using lv_display_set_flush_cb?
Introduce the problem
LVGL 9.3.0(master)
such as
...
disp = lv_display_create(640, 480);
//lv_display_set_flush_cb(disp, flush_cb);
lv_indev_set_display(indev, disp);
lv_display_set_color_format(disp, LV_COLOR_FORMAT_ARGB8888);
lv_display_set_buffers(disp, buf, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
while(1)
{
lv_tick_inc(33);
lv_timer_handler();
SDL_UpdateTexture(menu, NULL, buf, 640 * 4);
lv_display_flush_ready(disp);
...
}
I tried it, and it gets stuck in lv_timer_handler when the display has input events or animations are running. The reason I don't use callbacks is simply to keep the code simple and intuitive enough. If this is not feasible, it doesn't matter. I just want to explore some possibilities. Thank you guys so much.
BTW, can lv_indev also be achieved through non-callback methods? I didn't find the relevant API.
Proposal
No response
@kisvegabor Can I create this pull request to implement flushing display buffer without callback?
diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c
index 33aed28aa..86a2976b6 100644
--- a/src/core/lv_refr.c
+++ b/src/core/lv_refr.c
@@ -1260,6 +1260,9 @@ static void draw_buf_flush(lv_display_t * disp)
if(disp->flush_cb) {
call_flush_cb(disp, &disp->refreshed_area, layer->draw_buf->data);
}
+ else {
+ lv_display_flush_ready(disp);
+ }
/*If there are 2 buffers swap them. With direct mode swap only on the last area*/
if(lv_display_is_double_buffered(disp) && (disp->render_mode != LV_DISPLAY_RENDER_MODE_DIRECT || flushing_last)) {
if(disp->buf_act == disp->buf_1) {
Hi,
Calling SDL_UpdateTexture(menu, NULL, buf, 640 * 4); 30 times in a sec even if nothing happened on the screen (i.e. no rendering happened) seems wasteful. Isn't it a problem in your case?
Hi,
Calling
SDL_UpdateTexture(menu, NULL, buf, 640 * 4);30 times in a sec even if nothing happened on the screen (i.e. no rendering happened) seems wasteful. Isn't it a problem in your case?
Hi, I'm working on PC and use LVGL as build-in UI in my game, so no worries about performance. and the reason why I don't use callbacks is because I use Luajit to call LVGL function. using c callback in Luajit will have unexpected performance loss. such as:
LVGL.lv_display_set_flush_cb(t.disp, function(disp, area, px_map)
cb(px_map)
LVGL.lv_display_flush_ready(disp)
end)
I see. As a workaround, would it wok if you set an empty flush_wait_cb with lv_display_set_flush_wait_cb? This way LVGL will use the wait_cb instead of lv_display_flush_ready.
I see. As a workaround, would it wok if you set an empty
flush_wait_cbwithlv_display_set_flush_wait_cb? This way LVGL will use the wait_cb instead oflv_display_flush_ready.
First, Thank you for your solution, you are running a great project, hats off to you!!! I have used a simple patch to implement callback-free refresh, but as I got to know lvgl better, I realized that all animations are implemented by callbacks, but luajit will blacklist the FFI function that calls the c callback, which will cause the lua code block where the function is located to not be traced, they will fallback to interpreted mode, which is very slow. So I have to think of other ways. Finally, I would be very grateful if you could take a time at #7358. If LVGL can bind animation/timer to display, it will be very easy to create different components in different displays, refresh them as needed, and copy them to SDL Texture for show.
First, Thank you for your solution, you are running a great project, hats off to you!!!
Thank you, in the name of all the contributors :slightly_smiling_face:
Finally, I would be very grateful if you could take a time at https://github.com/lvgl/lvgl/issues/7358. If LVGL can bind animation/timer to display, it will be very easy to create different components in different displays, refresh them as needed, and copy them to SDL Texture for show.
Looking into it now.