From 559d09c14073687da9a9373429b2f2888f8c5b6c Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Sun, 26 Feb 2023 17:55:04 +0200 Subject: [TextServer] Add mutex for FreeType face creation/deletion operations. (cherry picked from commit c950a1ab9479e53f8b91d457f44cea9246e24e4e) --- modules/text_server_adv/text_server_adv.cpp | 81 ++++++++++++++++------------- modules/text_server_adv/text_server_adv.h | 2 + modules/text_server_fb/text_server_fb.cpp | 81 ++++++++++++++++------------- modules/text_server_fb/text_server_fb.h | 2 + 4 files changed, 96 insertions(+), 70 deletions(-) (limited to 'modules') diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 3463cb5d9d..3cf6288fef 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -386,6 +386,8 @@ int64_t TextServerAdvanced::_get_features() const { void TextServerAdvanced::_free_rid(const RID &p_rid) { _THREAD_SAFE_METHOD_ if (font_owner.owns(p_rid)) { + MutexLock ftlock(ft_mutex); + FontAdvanced *fd = font_owner.get_or_null(p_rid); { MutexLock lock(fd->mutex); @@ -1321,45 +1323,48 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f // Init dynamic font. #ifdef MODULE_FREETYPE_ENABLED int error = 0; - if (!ft_library) { - error = FT_Init_FreeType(&ft_library); - if (error != 0) { - memdelete(fd); - ERR_FAIL_V_MSG(false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'."); - } + { + MutexLock ftlock(ft_mutex); + if (!ft_library) { + error = FT_Init_FreeType(&ft_library); + if (error != 0) { + memdelete(fd); + ERR_FAIL_V_MSG(false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'."); + } #ifdef MODULE_SVG_ENABLED - FT_Property_Set(ft_library, "ot-svg", "svg-hooks", get_tvg_svg_in_ot_hooks()); + FT_Property_Set(ft_library, "ot-svg", "svg-hooks", get_tvg_svg_in_ot_hooks()); #endif - } - - memset(&fd->stream, 0, sizeof(FT_StreamRec)); - fd->stream.base = (unsigned char *)p_font_data->data_ptr; - fd->stream.size = p_font_data->data_size; - fd->stream.pos = 0; - - FT_Open_Args fargs; - memset(&fargs, 0, sizeof(FT_Open_Args)); - fargs.memory_base = (unsigned char *)p_font_data->data_ptr; - fargs.memory_size = p_font_data->data_size; - fargs.flags = FT_OPEN_MEMORY; - fargs.stream = &fd->stream; + } - int max_index = 0; - FT_Face tmp_face = nullptr; - error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); - if (tmp_face && error == 0) { - max_index = tmp_face->num_faces - 1; - } - if (tmp_face) { - FT_Done_Face(tmp_face); - } + memset(&fd->stream, 0, sizeof(FT_StreamRec)); + fd->stream.base = (unsigned char *)p_font_data->data_ptr; + fd->stream.size = p_font_data->data_size; + fd->stream.pos = 0; + + FT_Open_Args fargs; + memset(&fargs, 0, sizeof(FT_Open_Args)); + fargs.memory_base = (unsigned char *)p_font_data->data_ptr; + fargs.memory_size = p_font_data->data_size; + fargs.flags = FT_OPEN_MEMORY; + fargs.stream = &fd->stream; + + int max_index = 0; + FT_Face tmp_face = nullptr; + error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); + if (tmp_face && error == 0) { + max_index = tmp_face->num_faces - 1; + } + if (tmp_face) { + FT_Done_Face(tmp_face); + } - error = FT_Open_Face(ft_library, &fargs, CLAMP(p_font_data->face_index, 0, max_index), &fd->face); - if (error) { - FT_Done_Face(fd->face); - fd->face = nullptr; - memdelete(fd); - ERR_FAIL_V_MSG(false, "FreeType: Error loading font: '" + String(FT_Error_String(error)) + "'."); + error = FT_Open_Face(ft_library, &fargs, CLAMP(p_font_data->face_index, 0, max_index), &fd->face); + if (error) { + FT_Done_Face(fd->face); + fd->face = nullptr; + memdelete(fd); + ERR_FAIL_V_MSG(false, "FreeType: Error loading font: '" + String(FT_Error_String(error)) + "'."); + } } if (p_font_data->msdf) { @@ -1788,6 +1793,8 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f } _FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontAdvanced *p_font_data) { + MutexLock ftlock(ft_mutex); + for (const KeyValue &E : p_font_data->cache) { memdelete(E.value); } @@ -1894,6 +1901,8 @@ int64_t TextServerAdvanced::_font_get_face_count(const RID &p_font_rid) const { fargs.flags = FT_OPEN_MEMORY; fargs.stream = &stream; + MutexLock ftlock(ft_mutex); + FT_Face tmp_face = nullptr; error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); if (error == 0) { @@ -2285,6 +2294,7 @@ void TextServerAdvanced::_font_clear_size_cache(const RID &p_font_rid) { ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); + MutexLock ftlock(ft_mutex); for (const KeyValue &E : fd->cache) { memdelete(E.value); } @@ -2296,6 +2306,7 @@ void TextServerAdvanced::_font_remove_size_cache(const RID &p_font_rid, const Ve ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); + MutexLock ftlock(ft_mutex); if (fd->cache.has(p_size)) { memdelete(fd->cache[p_size]); fd->cache.erase(p_size); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index f092fa8cca..ce08cf7694 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -616,6 +616,8 @@ class TextServerAdvanced : public TextServerExtension { _FORCE_INLINE_ void _add_featuers(const Dictionary &p_source, Vector &r_ftrs); + Mutex ft_mutex; + // HarfBuzz bitmap font interface. static hb_font_funcs_t *funcs; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 15124ad488..8687726287 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -113,6 +113,8 @@ int64_t TextServerFallback::_get_features() const { void TextServerFallback::_free_rid(const RID &p_rid) { _THREAD_SAFE_METHOD_ if (font_owner.owns(p_rid)) { + MutexLock ftlock(ft_mutex); + FontFallback *fd = font_owner.get_or_null(p_rid); { MutexLock lock(fd->mutex); @@ -760,45 +762,48 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f // Init dynamic font. #ifdef MODULE_FREETYPE_ENABLED int error = 0; - if (!ft_library) { - error = FT_Init_FreeType(&ft_library); - if (error != 0) { - memdelete(fd); - ERR_FAIL_V_MSG(false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'."); - } + { + MutexLock ftlock(ft_mutex); + if (!ft_library) { + error = FT_Init_FreeType(&ft_library); + if (error != 0) { + memdelete(fd); + ERR_FAIL_V_MSG(false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'."); + } #ifdef MODULE_SVG_ENABLED - FT_Property_Set(ft_library, "ot-svg", "svg-hooks", get_tvg_svg_in_ot_hooks()); + FT_Property_Set(ft_library, "ot-svg", "svg-hooks", get_tvg_svg_in_ot_hooks()); #endif - } - - memset(&fd->stream, 0, sizeof(FT_StreamRec)); - fd->stream.base = (unsigned char *)p_font_data->data_ptr; - fd->stream.size = p_font_data->data_size; - fd->stream.pos = 0; - - FT_Open_Args fargs; - memset(&fargs, 0, sizeof(FT_Open_Args)); - fargs.memory_base = (unsigned char *)p_font_data->data_ptr; - fargs.memory_size = p_font_data->data_size; - fargs.flags = FT_OPEN_MEMORY; - fargs.stream = &fd->stream; + } - int max_index = 0; - FT_Face tmp_face = nullptr; - error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); - if (tmp_face && error == 0) { - max_index = tmp_face->num_faces - 1; - } - if (tmp_face) { - FT_Done_Face(tmp_face); - } + memset(&fd->stream, 0, sizeof(FT_StreamRec)); + fd->stream.base = (unsigned char *)p_font_data->data_ptr; + fd->stream.size = p_font_data->data_size; + fd->stream.pos = 0; + + FT_Open_Args fargs; + memset(&fargs, 0, sizeof(FT_Open_Args)); + fargs.memory_base = (unsigned char *)p_font_data->data_ptr; + fargs.memory_size = p_font_data->data_size; + fargs.flags = FT_OPEN_MEMORY; + fargs.stream = &fd->stream; + + int max_index = 0; + FT_Face tmp_face = nullptr; + error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); + if (tmp_face && error == 0) { + max_index = tmp_face->num_faces - 1; + } + if (tmp_face) { + FT_Done_Face(tmp_face); + } - error = FT_Open_Face(ft_library, &fargs, CLAMP(p_font_data->face_index, 0, max_index), &fd->face); - if (error) { - FT_Done_Face(fd->face); - fd->face = nullptr; - memdelete(fd); - ERR_FAIL_V_MSG(false, "FreeType: Error loading font: '" + String(FT_Error_String(error)) + "'."); + error = FT_Open_Face(ft_library, &fargs, CLAMP(p_font_data->face_index, 0, max_index), &fd->face); + if (error) { + FT_Done_Face(fd->face); + fd->face = nullptr; + memdelete(fd); + ERR_FAIL_V_MSG(false, "FreeType: Error loading font: '" + String(FT_Error_String(error)) + "'."); + } } if (p_font_data->msdf) { @@ -909,6 +914,8 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f } _FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontFallback *p_font_data) { + MutexLock ftlock(ft_mutex); + for (const KeyValue &E : p_font_data->cache) { memdelete(E.value); } @@ -1012,6 +1019,8 @@ int64_t TextServerFallback::_font_get_face_count(const RID &p_font_rid) const { fargs.flags = FT_OPEN_MEMORY; fargs.stream = &stream; + MutexLock ftlock(ft_mutex); + FT_Face tmp_face = nullptr; error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face); if (error == 0) { @@ -1393,6 +1402,7 @@ void TextServerFallback::_font_clear_size_cache(const RID &p_font_rid) { ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); + MutexLock ftlock(ft_mutex); for (const KeyValue &E : fd->cache) { memdelete(E.value); } @@ -1404,6 +1414,7 @@ void TextServerFallback::_font_remove_size_cache(const RID &p_font_rid, const Ve ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); + MutexLock ftlock(ft_mutex); if (fd->cache.has(p_size)) { memdelete(fd->cache[p_size]); fd->cache.erase(p_size); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 12ed21ee95..d9e471154d 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -531,6 +531,8 @@ class TextServerFallback : public TextServerExtension { void _realign(ShapedTextDataFallback *p_sd) const; + Mutex ft_mutex; + protected: static void _bind_methods(){}; -- cgit v1.2.3