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); |
} |