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:
bjsylvia
2023-11-10 20:31:36 +08:00
committed by GitHub
parent ffe2c1528e
commit 17d1da62af
5 changed files with 44 additions and 17 deletions
+7 -11
View File
@@ -147,17 +147,17 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t)
void lv_draw_dispatch(void)
{
LV_PROFILER_BEGIN;
bool one_taken = false;
bool render_running = false;
lv_display_t * disp = lv_display_get_next(NULL);
while(disp) {
lv_layer_t * layer = disp->layer_head;
while(layer) {
bool ret = lv_draw_dispatch_layer(disp, layer);
if(ret) one_taken = true;
if(lv_draw_dispatch_layer(disp, layer))
render_running = true;
layer = layer->next;
}
if(!one_taken) {
if(!render_running) {
lv_draw_dispatch_request();
}
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;
}
bool one_taken = false;
bool render_running = false;
/*This layer is ready, enable blending its buffer*/
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;
while(u) {
int32_t taken_cnt = u->dispatch_cb(u, layer);
if(taken_cnt < 0) {
break;
}
if(taken_cnt > 0) one_taken = true;
if(taken_cnt >= 0) render_running = true;
u = u->next;
}
}
}
return one_taken;
return render_running;
}
void lv_draw_dispatch_wait_for_request(void)
+7 -3
View File
@@ -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
* @param draw_unit pointer to the draw unit
* @param layer pointer to a layer on which the draw task should be drawn
* @return >=0: The number of taken draw task
* -1: There where no available draw tasks at all.
* Also means to no call the dispatcher of the other draw units as there is no draw task to take
* @return >=0: The number of taken draw task:
* 0 means the task has not yet been completed.
* 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);
+22 -1
View File
@@ -95,6 +95,14 @@ static int32_t lv_draw_sw_delete(lv_draw_unit_t * draw_unit)
{
#if LV_USE_OS
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);
#else
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
/*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
execute_drawing(draw_sw_unit);
@@ -148,12 +156,21 @@ static void render_thread_cb(void * ptr)
lv_draw_sw_unit_t * u = ptr;
lv_thread_sync_init(&u->sync);
u->inited = true;
while(1) {
while(u->task_act == NULL) {
if(u->exit_status) {
break;
}
lv_thread_sync_wait(&u->sync);
}
if(u->exit_status) {
LV_LOG_INFO("ready to exit software rendering thread");
break;
}
execute_drawing(u);
/*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*/
lv_draw_dispatch_request();
}
u->inited = false;
lv_thread_sync_delete(&u->sync);
LV_LOG_INFO("exit software rendering thread");
}
#endif
+2
View File
@@ -36,6 +36,8 @@ typedef struct {
#if LV_USE_OS
lv_thread_sync_t sync;
lv_thread_t thread;
volatile bool inited;
volatile bool exit_status;
#endif
uint32_t idx;
} lv_draw_sw_unit_t;
+6 -2
View File
@@ -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_UNUSED(thread);
/*How?*/
int ret = pthread_join(thread->thread, NULL);
if(ret != 0) {
LV_LOG_WARN("Error: %d", ret);
return LV_RESULT_INVALID;
}
return LV_RESULT_OK;
}