reworks VDB to work with true double buffering
This commit is contained in:
@@ -515,7 +515,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
|
||||
/* Redraw the object */
|
||||
obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
|
||||
//tick_wait_ms(100); /*DEBUG: Wait after every object draw to see the order of drawing*/
|
||||
//usleep(5 * 1000); /*DEBUG: Wait after every object draw to see the order of drawing*/
|
||||
|
||||
|
||||
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
|
||||
|
||||
@@ -23,12 +23,6 @@
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum {
|
||||
LV_VDB_STATE_FREE = 0, /*Not used*/
|
||||
LV_VDB_STATE_ACTIVE, /*Being used to render*/
|
||||
LV_VDB_STATE_FLUSH, /*Flushing pixels from it*/
|
||||
};
|
||||
typedef uint8_t lv_vdb_state_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
@@ -38,9 +32,8 @@ typedef uint8_t lv_vdb_state_t;
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
/*Simple VDB*/
|
||||
static volatile lv_vdb_state_t vdb_state = LV_VDB_STATE_ACTIVE;
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
# if LV_VDB_ADR == 0
|
||||
/*If the buffer address is not specified simply allocate it*/
|
||||
static uint8_t vdb_buf[LV_VDB_SIZE_IN_BYTES];
|
||||
@@ -49,9 +42,11 @@ static lv_vdb_t vdb = {.buf = (lv_color_t *)vdb_buf};
|
||||
/*If the buffer address is specified use that address*/
|
||||
static lv_vdb_t vdb = {.buf = (lv_color_t *)LV_VDB_ADR};
|
||||
# endif
|
||||
#else /*LV_VDB_DOUBLE != 0*/
|
||||
|
||||
/*LV_VDB_DOUBLE != 0*/
|
||||
#else
|
||||
/*Double VDB*/
|
||||
static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE};
|
||||
static uint8_t vdb_active = 0;
|
||||
# if LV_VDB_ADR == 0
|
||||
/*If the buffer address is not specified simply allocate it*/
|
||||
static uint8_t vdb_buf1[LV_VDB_SIZE_IN_BYTES];
|
||||
@@ -63,6 +58,8 @@ static lv_vdb_t vdb[2] = {{.buf = (lv_color_t *)LV_VDB_ADR}, {.buf = (lv_color_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static volatile bool vdb_flushing = false;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -78,32 +75,14 @@ static lv_vdb_t vdb[2] = {{.buf = (lv_color_t *)LV_VDB_ADR}, {.buf = (lv_color_t
|
||||
lv_vdb_t * lv_vdb_get(void)
|
||||
{
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
/* Wait until VDB become ACTIVE from FLUSH by the
|
||||
* user call of 'lv_flush_ready()' in display drivers's flush function*/
|
||||
while(vdb_state != LV_VDB_STATE_ACTIVE);
|
||||
/* Wait until VDB is flushing.
|
||||
* (Until this user calls of 'lv_flush_ready()' in the display drivers's flush function*/
|
||||
while(vdb_flushing);
|
||||
|
||||
if(vdb.buf == (void *)LV_VDB_ADR_INV) {
|
||||
LV_LOG_ERROR("VDB address is invalid. Use `lv_vdb_set_adr` to set a valid address or use LV_VDB_ADR = 0 in lv_conf.h");
|
||||
return NULL;
|
||||
}
|
||||
return &vdb;
|
||||
#else
|
||||
/*If already there is an active do nothing*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) return &vdb[0];
|
||||
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) return &vdb[1];
|
||||
|
||||
/*Try to allocate a free VDB*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_FREE) {
|
||||
vdb_state[0] = LV_VDB_STATE_ACTIVE;
|
||||
return &vdb[0];
|
||||
}
|
||||
|
||||
if(vdb_state[1] == LV_VDB_STATE_FREE) {
|
||||
vdb_state[1] = LV_VDB_STATE_ACTIVE;
|
||||
return &vdb[1];
|
||||
}
|
||||
|
||||
return NULL; /*There wasn't free VDB (never happen)*/
|
||||
return &vdb[vdb_active];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -117,23 +96,30 @@ void lv_vdb_flush(void)
|
||||
LV_LOG_WARN("Invalid VDB pointer");
|
||||
return;
|
||||
}
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
vdb_state = LV_VDB_STATE_FLUSH; /*User call to 'lv_flush_ready()' will set to ACTIVE 'disp_flush'*/
|
||||
#else
|
||||
/* Wait the pending flush before starting this one
|
||||
* (Don't forget: 'lv_flush_ready()' has to be called when flushing is ready)*/
|
||||
while(vdb_state[0] == LV_VDB_STATE_FLUSH || vdb_state[1] == LV_VDB_STATE_FLUSH);
|
||||
|
||||
/*Turn the active VDB to flushing*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) vdb_state[0] = LV_VDB_STATE_FLUSH;
|
||||
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
|
||||
#endif
|
||||
/*Don't start a new flush while the previous is not finished*/
|
||||
#if LV_VDB_DOUBLE
|
||||
while(vdb_flushing);
|
||||
#endif /*LV_VDB_DOUBLE*/
|
||||
|
||||
vdb_flushing = true;
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_disp_flush(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf);
|
||||
|
||||
}
|
||||
#if LV_VDB_DOUBLE
|
||||
/*Make the other VDB active. The content of the current will be kept until the next flush*/
|
||||
vdb_active++;
|
||||
vdb_active &= 0x1;
|
||||
|
||||
/*If the screen is transparent initialize it when the new VDB is selected*/
|
||||
# if LV_COLOR_SCREEN_TRANSP
|
||||
memset(vdb[vdb_active].buf, 0x00, LV_VDB_SIZE_IN_BYTES);
|
||||
# endif /*LV_COLOR_SCREEN_TRANSP*/
|
||||
|
||||
#endif /*#if LV_VDB_DOUBLE*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address of VDB buffer(s) manually. To use this set `LV_VDB_ADR` (and `LV_VDB2_ADR`) to `LV_VDB_ADR_INV` in `lv_conf.h`.
|
||||
@@ -157,27 +143,12 @@ void lv_vdb_set_adr(void * buf1, void * buf2)
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_flush_ready(void)
|
||||
{
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
vdb_state = LV_VDB_STATE_ACTIVE;
|
||||
vdb_flushing = false;
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
/*If the screen is transparent initialize it when the flushing is ready*/
|
||||
#if LV_VDB_DOUBLE == 0 && LV_COLOR_SCREEN_TRANSP
|
||||
memset(vdb_buf, 0x00, LV_VDB_SIZE_IN_BYTES);
|
||||
#endif
|
||||
|
||||
#else
|
||||
if(vdb_state[0] == LV_VDB_STATE_FLUSH) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
memset(vdb_buf[0], 0x00, LV_VDB_SIZE_IN_BYTES);
|
||||
#endif
|
||||
vdb_state[0] = LV_VDB_STATE_FREE;
|
||||
}
|
||||
if(vdb_state[1] == LV_VDB_STATE_FLUSH) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
memset(vdb_buf[1], 0x00, LV_VDB_SIZE_IN_BYTES);
|
||||
#endif
|
||||
vdb_state[1] = LV_VDB_STATE_FREE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
Reference in New Issue
Block a user