feat(display): add flush_wait_cb
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user