mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-28 22:30:49 +08:00
fix(render): make parallel rendering work based on Nuttx Simulator (#4764)
Signed-off-by: YanXiaowei <yanxiaowei@xiaomi.com> Co-authored-by: YanXiaowei <yanxiaowei@xiaomi.com>
This commit is contained in:
+7
-11
@@ -147,17 +147,17 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t)
|
|||||||
void lv_draw_dispatch(void)
|
void lv_draw_dispatch(void)
|
||||||
{
|
{
|
||||||
LV_PROFILER_BEGIN;
|
LV_PROFILER_BEGIN;
|
||||||
bool one_taken = false;
|
bool render_running = false;
|
||||||
lv_display_t * disp = lv_display_get_next(NULL);
|
lv_display_t * disp = lv_display_get_next(NULL);
|
||||||
while(disp) {
|
while(disp) {
|
||||||
lv_layer_t * layer = disp->layer_head;
|
lv_layer_t * layer = disp->layer_head;
|
||||||
while(layer) {
|
while(layer) {
|
||||||
bool ret = lv_draw_dispatch_layer(disp, layer);
|
if(lv_draw_dispatch_layer(disp, layer))
|
||||||
if(ret) one_taken = true;
|
render_running = true;
|
||||||
layer = layer->next;
|
layer = layer->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!one_taken) {
|
if(!render_running) {
|
||||||
lv_draw_dispatch_request();
|
lv_draw_dispatch_request();
|
||||||
}
|
}
|
||||||
disp = lv_display_get_next(disp);
|
disp = lv_display_get_next(disp);
|
||||||
@@ -223,7 +223,7 @@ bool lv_draw_dispatch_layer(struct _lv_display_t * disp, lv_layer_t * layer)
|
|||||||
t = t_next;
|
t = t_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool one_taken = false;
|
bool render_running = false;
|
||||||
|
|
||||||
/*This layer is ready, enable blending its buffer*/
|
/*This layer is ready, enable blending its buffer*/
|
||||||
if(layer->parent && layer->all_tasks_added && layer->draw_task_head == NULL) {
|
if(layer->parent && layer->all_tasks_added && layer->draw_task_head == NULL) {
|
||||||
@@ -261,17 +261,13 @@ bool lv_draw_dispatch_layer(struct _lv_display_t * disp, lv_layer_t * layer)
|
|||||||
lv_draw_unit_t * u = _draw_info.unit_head;
|
lv_draw_unit_t * u = _draw_info.unit_head;
|
||||||
while(u) {
|
while(u) {
|
||||||
int32_t taken_cnt = u->dispatch_cb(u, layer);
|
int32_t taken_cnt = u->dispatch_cb(u, layer);
|
||||||
if(taken_cnt < 0) {
|
if(taken_cnt >= 0) render_running = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(taken_cnt > 0) one_taken = true;
|
|
||||||
u = u->next;
|
u = u->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return one_taken;
|
return render_running;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_draw_dispatch_wait_for_request(void)
|
void lv_draw_dispatch_wait_for_request(void)
|
||||||
|
|||||||
+7
-3
@@ -117,9 +117,13 @@ typedef struct _lv_draw_unit_t {
|
|||||||
* A draw task should be assign only if the draw unit can draw it too
|
* A draw task should be assign only if the draw unit can draw it too
|
||||||
* @param draw_unit pointer to the draw unit
|
* @param draw_unit pointer to the draw unit
|
||||||
* @param layer pointer to a layer on which the draw task should be drawn
|
* @param layer pointer to a layer on which the draw task should be drawn
|
||||||
* @return >=0: The number of taken draw task
|
* @return >=0: The number of taken draw task:
|
||||||
* -1: There where no available draw tasks at all.
|
* 0 means the task has not yet been completed.
|
||||||
* Also means to no call the dispatcher of the other draw units as there is no draw task to take
|
* 1 means a new task has been accepted.
|
||||||
|
* -1: The draw unit wanted to work on a task but couldn't do that
|
||||||
|
* due to some errors (e.g. out of memory).
|
||||||
|
* It signals that LVGL should call the dispatcher later again
|
||||||
|
* to let draw unit try to start the rendering again.
|
||||||
*/
|
*/
|
||||||
int32_t (*dispatch_cb)(struct _lv_draw_unit_t * draw_unit, struct _lv_layer_t * layer);
|
int32_t (*dispatch_cb)(struct _lv_draw_unit_t * draw_unit, struct _lv_layer_t * layer);
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,14 @@ static int32_t lv_draw_sw_delete(lv_draw_unit_t * draw_unit)
|
|||||||
{
|
{
|
||||||
#if LV_USE_OS
|
#if LV_USE_OS
|
||||||
lv_draw_sw_unit_t * draw_sw_unit = (lv_draw_sw_unit_t *) draw_unit;
|
lv_draw_sw_unit_t * draw_sw_unit = (lv_draw_sw_unit_t *) draw_unit;
|
||||||
|
|
||||||
|
LV_LOG_INFO("cancel software rendering thread");
|
||||||
|
draw_sw_unit->exit_status = true;
|
||||||
|
|
||||||
|
if(draw_sw_unit->inited) {
|
||||||
|
lv_thread_sync_signal(&draw_sw_unit->sync);
|
||||||
|
}
|
||||||
|
|
||||||
return lv_thread_delete(&draw_sw_unit->thread);
|
return lv_thread_delete(&draw_sw_unit->thread);
|
||||||
#else
|
#else
|
||||||
LV_UNUSED(draw_unit);
|
LV_UNUSED(draw_unit);
|
||||||
@@ -128,7 +136,7 @@ static int32_t lv_draw_sw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * laye
|
|||||||
|
|
||||||
#if LV_USE_OS
|
#if LV_USE_OS
|
||||||
/*Let the render thread work*/
|
/*Let the render thread work*/
|
||||||
lv_thread_sync_signal(&draw_sw_unit->sync);
|
if(draw_sw_unit->inited) lv_thread_sync_signal(&draw_sw_unit->sync);
|
||||||
#else
|
#else
|
||||||
execute_drawing(draw_sw_unit);
|
execute_drawing(draw_sw_unit);
|
||||||
|
|
||||||
@@ -148,12 +156,21 @@ static void render_thread_cb(void * ptr)
|
|||||||
lv_draw_sw_unit_t * u = ptr;
|
lv_draw_sw_unit_t * u = ptr;
|
||||||
|
|
||||||
lv_thread_sync_init(&u->sync);
|
lv_thread_sync_init(&u->sync);
|
||||||
|
u->inited = true;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
while(u->task_act == NULL) {
|
while(u->task_act == NULL) {
|
||||||
|
if(u->exit_status) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
lv_thread_sync_wait(&u->sync);
|
lv_thread_sync_wait(&u->sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(u->exit_status) {
|
||||||
|
LV_LOG_INFO("ready to exit software rendering thread");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
execute_drawing(u);
|
execute_drawing(u);
|
||||||
|
|
||||||
/*Cleanup*/
|
/*Cleanup*/
|
||||||
@@ -163,6 +180,10 @@ static void render_thread_cb(void * ptr)
|
|||||||
/*The draw unit is free now. Request a new dispatching as it can get a new task*/
|
/*The draw unit is free now. Request a new dispatching as it can get a new task*/
|
||||||
lv_draw_dispatch_request();
|
lv_draw_dispatch_request();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u->inited = false;
|
||||||
|
lv_thread_sync_delete(&u->sync);
|
||||||
|
LV_LOG_INFO("exit software rendering thread");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ typedef struct {
|
|||||||
#if LV_USE_OS
|
#if LV_USE_OS
|
||||||
lv_thread_sync_t sync;
|
lv_thread_sync_t sync;
|
||||||
lv_thread_t thread;
|
lv_thread_t thread;
|
||||||
|
volatile bool inited;
|
||||||
|
volatile bool exit_status;
|
||||||
#endif
|
#endif
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
} lv_draw_sw_unit_t;
|
} lv_draw_sw_unit_t;
|
||||||
|
|||||||
@@ -51,8 +51,12 @@ lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*c
|
|||||||
|
|
||||||
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
lv_result_t lv_thread_delete(lv_thread_t * thread)
|
||||||
{
|
{
|
||||||
LV_UNUSED(thread);
|
int ret = pthread_join(thread->thread, NULL);
|
||||||
/*How?*/
|
if(ret != 0) {
|
||||||
|
LV_LOG_WARN("Error: %d", ret);
|
||||||
|
return LV_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
return LV_RESULT_OK;
|
return LV_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user