diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-06-28 17:05:15 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-06-28 17:05:15 +0400 |
commit | 0d7dbbb6e1fc0bb85d236ca1e04ff966f4ad39c9 (patch) | |
tree | 2bce40d958d1ac50361d6d3c58aab714dbb0a55b /source/blender/blenfont/intern/blf_glyph.c | |
parent | ca33bea285c1ffe74e9f6d3c6b28d7b26ebc84ab (diff) |
Fix #35884: crash opening .blend with generated color grid image and preview render.
Printing text on the color grid image would initialize font glyphs from a thread at
the same time as the UI, causing conflicts. The freetype glyph renderer needs to be
mutex locked because it uses a shared buffer internally even when rendering for
different fonts. Also needed to change the image generate function to use the render
monospace font to avoid conflicts in blenfont.
What's still weak in the blenfont API is that there is no distinction between a font
and a thread using that font to render with some particular size, style, etc.
Diffstat (limited to 'source/blender/blenfont/intern/blf_glyph.c')
-rw-r--r-- | source/blender/blenfont/intern/blf_glyph.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 4812f8f23f7..55424145b43 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -48,6 +48,7 @@ #include "BLI_listbase.h" #include "BLI_rect.h" +#include "BLI_threads.h" #include "BIF_gl.h" #include "BLF_api.h" @@ -224,6 +225,19 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) if (g) return g; + /* glyphs are dynamically created as needed by font rendering. this means that + * to make font rendering thread safe we have to do locking here. note that this + * must be a lock for the whole library and not just per font, because the font + * renderer uses a shared buffer internally */ + BLI_spin_lock(font->ft_lib_mutex); + + /* search again after locking */ + g = blf_glyph_search(font->glyph_cache, c); + if (g) { + BLI_spin_unlock(font->ft_lib_mutex); + return g; + } + if (font->flags & BLF_HINTING) flags &= ~FT_LOAD_NO_HINTING; @@ -231,8 +245,11 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO); else err = FT_Load_Glyph(font->face, (FT_UInt)index, flags); - if (err) + + if (err) { + BLI_spin_unlock(font->ft_lib_mutex); return NULL; + } /* get the glyph. */ slot = font->face->glyph; @@ -251,8 +268,10 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) err = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL); } - if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) + if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) { + BLI_spin_unlock(font->ft_lib_mutex); return NULL; + } g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add"); g->c = c; @@ -289,6 +308,9 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) key = blf_hash(g->c); BLI_addhead(&(font->glyph_cache->bucket[key]), g); + + BLI_spin_unlock(font->ft_lib_mutex); + return g; } |