Chromium Code Reviews| Index: src/fonts/SkFontMgr_fontconfig.cpp |
| diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp |
| index bd4c8ddc1db2a275b51c4d0b586efadcbf183b0d..af460b0180ffe086bb5570accaa77fe071780e4a 100644 |
| --- a/src/fonts/SkFontMgr_fontconfig.cpp |
| +++ b/src/fonts/SkFontMgr_fontconfig.cpp |
| @@ -12,6 +12,34 @@ |
| #include "SkMath.h" |
| #include "SkString.h" |
| #include "SkTDArray.h" |
| +#include "SkThread.h" |
| + |
| +namespace { |
| + |
| +// See skia:1497 for background. |
| + |
| +#if FC_VERSION < 21091 |
|
bungeman-skia
2014/03/31 17:25:51
I'm not sure that it makes sense to use the versio
mtklein
2014/03/31 17:37:36
Duh, fixed.
|
| + |
| +// Fontconfig is not threadsafe. We sadly need to manually synchronize all Fc...() calls. |
| +SK_DECLARE_STATIC_MUTEX(gFCMutex); |
| +static bool gFCSafeToUse; |
| + |
| +struct FCLocker { |
| + FCLocker() { gFCMutex.acquire(); gFCSafeToUse = true; } |
| + ~FCLocker() { gFCSafeToUse = false; gFCMutex.release(); } |
| +}; |
| + |
| +#else |
| + |
| +// Fontconfig is threadsafe. Noops for locking. |
| +static const bool gFCSafeToUse = true; |
| +struct FCLocker { |
| + FCLocker() {} // Stifles unused variable warnings. |
| +}; |
| + |
| +#endif |
| + |
| +} // namespace |
| // for now we pull these in directly. eventually we will solely rely on the |
| // SkFontConfigInterface instance. |
| @@ -40,6 +68,7 @@ static bool is_lower(char c) { |
| } |
| static int get_int(FcPattern* pattern, const char field[]) { |
| + SkASSERT(gFCSafeToUse); |
| int value; |
| if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) { |
| value = SK_MinS32; |
| @@ -48,6 +77,7 @@ static int get_int(FcPattern* pattern, const char field[]) { |
| } |
| static const char* get_name(FcPattern* pattern, const char field[]) { |
| + SkASSERT(gFCSafeToUse); |
| const char* name; |
| if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch) { |
| name = ""; |
| @@ -56,6 +86,7 @@ static const char* get_name(FcPattern* pattern, const char field[]) { |
| } |
| static bool valid_pattern(FcPattern* pattern) { |
| + SkASSERT(gFCSafeToUse); |
| FcBool is_scalable; |
| if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch || !is_scalable) { |
| return false; |
| @@ -208,6 +239,8 @@ protected: |
| } |
| virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE { |
| + FCLocker lock; |
| + |
| FcPattern* pattern = FcPatternCreate(); |
| FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| @@ -284,6 +317,7 @@ protected: |
| virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
| unsigned styleBits) const SK_OVERRIDE { |
| + FCLocker lock; |
| return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName, |
| (SkTypeface::Style)styleBits); |
| } |