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

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 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 wait_for_flushing(lv_display_t * disp);
/**********************
* 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*/
/*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;
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*/
/*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.
*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.
* Else we would draw into the buffer while it's still being transferred to the display*/
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(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
* and other buffer already contains the new rendered image. */
if(lv_display_is_double_buffered(disp)) {
while(disp->flushing);
wait_for_flushing(disp_refr);
}
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;
}
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;
}

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;
}
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)
{
if(disp == NULL) disp = lv_display_get_default();

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_wait_cb_t)(struct _lv_display_t * disp);
/**********************
* 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)
*/
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.
* If set to other than `LV_COLOR_FORMAT_NATIVE` the layer's `buffer_convert` function will be used

View File

@@ -70,6 +70,12 @@ struct _lv_display_t {
* called when finished*/
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)*/
volatile int flushing;