mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 12:47:51 +08:00
fix(draw_sw): fix letter outline multi-threading issues (#8003)
This commit is contained in:
committed by
GitHub
parent
153a169fee
commit
1ff8ea1da0
@@ -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");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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*/
|
||||
|
||||
Reference in New Issue
Block a user