fix(draw_sw): fix letter outline multi-threading issues (#8003)

This commit is contained in:
Gabor Kiss-Vamosi
2025-04-03 14:11:47 +02:00
committed by GitHub
parent 153a169fee
commit 1ff8ea1da0
6 changed files with 49 additions and 21 deletions
@@ -43,8 +43,9 @@ void lv_example_freetype_2_vector_font(uint32_t font_size, uint32_t border_width
/*Create a label with the new style*/
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_obj_add_style(label, &style, 0);
lv_label_set_text(label, "Hello world\nI'm a font created with FreeType");
lv_obj_center(label);
lv_label_set_text(label,
"Hello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\n"
"I'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\nHello world\nI'm a font created with FreeType\n");
}
+2
View File
@@ -790,6 +790,8 @@ void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y)
void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data)
{
if(task_list == NULL) return;
lv_vector_draw_task * task = lv_ll_get_head(task_list);
lv_vector_draw_task * next_task = NULL;
+1 -1
View File
@@ -152,7 +152,7 @@ void lv_draw_sw_transform(const lv_area_t * dest_area, const void * src_buf,
* @param t pointer to a draw task
* @param dsc the draw descriptor
*/
void lv_draw_sw_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc);
void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc);
#endif
/**
+31 -16
View File
@@ -11,9 +11,10 @@
#include "../../draw/lv_draw_private.h"
#include "lv_draw_sw.h"
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG
#include "../../libs/freetype/lv_freetype_private.h"
#include "../lv_draw_vector_private.h"
#endif
@@ -35,6 +36,15 @@
/**********************
* TYPEDEFS
**********************/
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG
typedef struct {
lv_vector_path_t * inside_path; /*The regular glyph*/
lv_vector_path_t * outside_path; /*A bigger glyph that goes in the background for the letter outline*/
lv_vector_path_t * cur_path;
} lv_draw_sw_letter_outlines_t;
#endif /* LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG */
/**********************
* STATIC PROTOTYPES
@@ -43,7 +53,7 @@
static void /* LV_ATTRIBUTE_FAST_MEM */ draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc,
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG
static void freetype_outline_event_cb(lv_event_t * e);
static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc);
@@ -100,7 +110,7 @@ void lv_draw_sw_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const
LV_PROFILER_DRAW_BEGIN;
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG
static bool is_init = false;
if(!is_init) {
lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, t);
@@ -179,7 +189,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly
break;
}
break;
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG
case LV_FONT_GLYPH_FORMAT_VECTOR: {
draw_letter_outline(t, glyph_draw_dsc);
}
@@ -195,13 +205,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly
}
}
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC
typedef struct {
lv_vector_path_t * inside_path; /*The regular glyph*/
lv_vector_path_t * outside_path; /*A bigger glyph that goes in the background for the letter outline*/
lv_vector_path_t * cur_path;
} lv_draw_sw_letter_outlines_t;
#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG
/*
* Renders the vectors paths representing a glyph with ThorVG
@@ -291,10 +295,21 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_
lv_memcpy(&old_area, &t->clip_area, sizeof(lv_area_t));
lv_memcpy(&t->clip_area, &buf_area, sizeof(lv_area_t));
lv_draw_vector(vector_dsc);
LV_ASSERT_NULL(layer.draw_task_head);
lv_draw_sw_vector(t, (lv_draw_vector_task_dsc_t *) layer.draw_task_head->draw_dsc);
/*Can't call lv_draw_vector() as it would create a new draw task while
*the main thread also can create draw tasks. So create a dummy draw task
*manually to draw the outline*/
if(vector_dsc->tasks.task_list) {
vector_dsc->tasks.base.layer = vector_dsc->layer;
lv_draw_task_t dummy_t;
lv_memzero(&dummy_t, sizeof(lv_draw_task_t));
dummy_t.area = vector_dsc->layer->_clip_area;
dummy_t._real_area = vector_dsc->layer->_clip_area;
dummy_t.clip_area = vector_dsc->layer->_clip_area;
dummy_t.target_layer = vector_dsc->layer;
dummy_t.type = LV_DRAW_TASK_TYPE_VECTOR;
dummy_t.draw_dsc = &vector_dsc->tasks;
lv_draw_sw_vector(&dummy_t, dummy_t.draw_dsc);
}
/*Restore previous draw area of the entire text label*/
lv_memcpy(&t->clip_area, &old_area, sizeof(lv_area_t));
@@ -319,7 +334,7 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_
}
/* Build the inside and outside vector paths for a glyph based
* on the recieved outline events emitted by lv_freetype_outline.c */
* on the received outline events emitted by lv_freetype_outline.c */
static void freetype_outline_event_cb(lv_event_t * e)
{
+3 -1
View File
@@ -464,7 +464,8 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_draw_sw_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc)
void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc)
{
if(dsc->task_list == NULL)
return;
@@ -503,6 +504,7 @@ void lv_draw_sw_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc
lv_ll_t * task_list = dsc->task_list;
lv_vector_for_each_destroy_tasks(task_list, _task_draw_cb, &state);
dsc->task_list = NULL;
if(tvg_canvas_draw(canvas) == TVG_RESULT_SUCCESS) {
tvg_canvas_sync(canvas);
+9 -1
View File
@@ -3,7 +3,10 @@
* Do not edit, your changes will be lost.
*/
#pragma once
#ifndef TVG_CONFIG_H
#define TVG_CONFIG_H
#include "../../lv_conf_internal.h"
#define THORVG_SW_RASTER_SUPPORT 1
@@ -13,4 +16,9 @@
#define THORVG_VERSION_STRING "0.15.3"
#if LV_DRAW_SW_DRAW_UNIT_CNT > 1
#define THORVG_THREAD_SUPPORT
#endif
#endif /*TVG_CONFIG_H*/