feat(display): add flush_wait_cb

This commit is contained in:
Gabor Kiss-Vamosi
2023-10-31 19:02:50 +01:00
parent 9404faa132
commit 01f2949acc
4 changed files with 50 additions and 4 deletions
+22 -4
View File
@@ -44,6 +44,7 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj);
static uint32_t get_max_row(lv_display_t * disp, lv_coord_t area_w, lv_coord_t area_h); static uint32_t get_max_row(lv_display_t * disp, lv_coord_t area_w, lv_coord_t area_h);
static void draw_buf_flush(lv_display_t * disp); static void draw_buf_flush(lv_display_t * disp);
static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
static void wait_for_flushing(lv_display_t * disp);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -384,7 +385,7 @@ void _lv_display_refr_timer(lv_timer_t * tmr)
/*With double buffered direct mode synchronize the rendered areas to the other buffer*/ /*With double buffered direct mode synchronize the rendered areas to the other buffer*/
/*We need to wait for ready here to not mess up the active screen*/ /*We need to wait for ready here to not mess up the active screen*/
while(disp_refr->flushing); wait_for_flushing(disp_refr);
uint32_t i; uint32_t i;
for(i = 0; i < disp_refr->inv_p; i++) { for(i = 0; i < disp_refr->inv_p; i++) {
@@ -470,7 +471,7 @@ static void refr_sync_areas(void)
/*With double buffered direct mode synchronize the rendered areas to the other buffer*/ /*With double buffered direct mode synchronize the rendered areas to the other buffer*/
/*We need to wait for ready here to not mess up the active screen*/ /*We need to wait for ready here to not mess up the active screen*/
while(disp_refr->flushing) {} wait_for_flushing(disp_refr);
/*The buffers are already swapped. /*The buffers are already swapped.
*So the active buffer is the off screen buffer where LVGL will render*/ *So the active buffer is the off screen buffer where LVGL will render*/
@@ -653,7 +654,7 @@ static void refr_area_part(lv_layer_t * layer)
/* In single buffered mode wait here until the buffer is freed. /* In single buffered mode wait here until the buffer is freed.
* Else we would draw into the buffer while it's still being transferred to the display*/ * Else we would draw into the buffer while it's still being transferred to the display*/
if(!lv_display_is_double_buffered(disp_refr)) { if(!lv_display_is_double_buffered(disp_refr)) {
while(disp_refr->flushing); wait_for_flushing(disp_refr);
} }
/*If the screen is transparent initialize it when the flushing is ready*/ /*If the screen is transparent initialize it when the flushing is ready*/
if(lv_color_format_has_alpha(disp_refr->color_format)) { if(lv_color_format_has_alpha(disp_refr->color_format)) {
@@ -984,7 +985,7 @@ static void draw_buf_flush(lv_display_t * disp)
* If we need to wait here it means that the content of one buffer is being sent to display * If we need to wait here it means that the content of one buffer is being sent to display
* and other buffer already contains the new rendered image. */ * and other buffer already contains the new rendered image. */
if(lv_display_is_double_buffered(disp)) { if(lv_display_is_double_buffered(disp)) {
while(disp->flushing); wait_for_flushing(disp_refr);
} }
disp->flushing = 1; disp->flushing = 1;
@@ -1036,3 +1037,20 @@ static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t *
LV_PROFILER_END; LV_PROFILER_END;
} }
static void wait_for_flushing(lv_display_t * disp)
{
LV_PROFILER_BEGIN;
LV_LOG_TRACE("begin");
if(disp->flush_wait_cb) {
disp->flush_wait_cb(disp);
}
else {
while(disp->flushing);
}
LV_LOG_TRACE("end");
LV_PROFILER_END;
}
+9
View File
@@ -398,6 +398,15 @@ void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb
disp->flush_cb = flush_cb; disp->flush_cb = flush_cb;
} }
void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb)
{
if(disp == NULL) disp = lv_display_get_default();
if(disp == NULL) return;
disp->flush_wait_cb = wait_cb;
}
void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format) void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format)
{ {
if(disp == NULL) disp = lv_display_get_default(); if(disp == NULL) disp = lv_display_get_default();
+13
View File
@@ -85,6 +85,7 @@ typedef enum {
typedef void (*lv_display_flush_cb_t)(struct _lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); typedef void (*lv_display_flush_cb_t)(struct _lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
typedef void (*lv_display_flush_wait_cb_t)(struct _lv_display_t * disp);
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@@ -249,6 +250,18 @@ void lv_display_set_draw_buffers(lv_display_t * disp, void * buf1, void * buf2,
* @param flush_cb the flush callback (`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display) * @param flush_cb the flush callback (`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display)
*/ */
void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb); void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb);
/**
* Set a callback to be used while LVGL is waiting flushing to be finished.
* It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc.
* If not set the `disp->flushing` flag is used which can be cleared with `lv_display_flush_ready()`
* @param disp pointer to a display
* @param wait_cb a callback to call while LVGL is waiting for flush ready.
* If NULL `lv_display_flush_ready()` can be used to signal that flushing is ready.
*/
void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb);
/** /**
* Set the color format of the display. * Set the color format of the display.
* If set to other than `LV_COLOR_FORMAT_NATIVE` the layer's `buffer_convert` function will be used * If set to other than `LV_COLOR_FORMAT_NATIVE` the layer's `buffer_convert` function will be used
+6
View File
@@ -70,6 +70,12 @@ struct _lv_display_t {
* called when finished*/ * called when finished*/
lv_display_flush_cb_t flush_cb; lv_display_flush_cb_t flush_cb;
/**
* Used to wait while flushing is ready.
* It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc.
* If not set `flushing` flag is used which can be cleared with `lv_display_flush_ready()`*/
lv_display_flush_wait_cb_t flush_wait_cb;
/*1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ Read-Modify-Write issue might occur)*/ /*1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ Read-Modify-Write issue might occur)*/
volatile int flushing; volatile int flushing;