aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports/SkFontConfigInterface_direct.cpp
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2016-05-02 11:54:13 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-02 11:54:13 -0700
commit0265707c191a31dfde08dd1cd7011c1fe5b8e643 (patch)
tree919635b2cf13cc3c639126c42e6098130e2e2c30 /src/ports/SkFontConfigInterface_direct.cpp
parentc5091b5b6c4b8a7aef8c12db9ea2a85e907b01c4 (diff)
Clean up SkFontConfigInterface implementation.
Renames some classes to avoid confusion with FontConfig. Removed direct calls to FontConfig instead of calling FCI. Moves the globals and factory to one (optional) file. Moves font management code from typeface to font manager. Adds index to fonts created from streams. Associates FCI typefaces with the FCI instance which provides its identity. Simplifies the singleton initialization. Review-Url: https://codereview.chromium.org/1936213002
Diffstat (limited to 'src/ports/SkFontConfigInterface_direct.cpp')
-rw-r--r--src/ports/SkFontConfigInterface_direct.cpp56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
index d384f707b1..d6fa96a46c 100644
--- a/src/ports/SkFontConfigInterface_direct.cpp
+++ b/src/ports/SkFontConfigInterface_direct.cpp
@@ -24,6 +24,56 @@
#include <fontconfig/fontconfig.h>
#include <unistd.h>
+#ifdef SK_DEBUG
+# include "SkTLS.h"
+#endif
+
+namespace {
+
+// Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
+// See https://bug.skia.org/1497 for background.
+SK_DECLARE_STATIC_MUTEX(gFCMutex);
+
+#ifdef SK_DEBUG
+void* CreateThreadFcLocked() { return new bool(false); }
+void DeleteThreadFcLocked(void* v) { delete static_cast<bool*>(v); }
+# define THREAD_FC_LOCKED \
+ static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked))
+#endif
+
+struct FCLocker {
+ // Assume FcGetVersion() has always been thread safe.
+
+ FCLocker() {
+ if (FcGetVersion() < 21091) {
+ gFCMutex.acquire();
+ } else {
+ SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED);
+ SkASSERT(false == *threadLocked);
+ SkDEBUGCODE(*threadLocked = true);
+ }
+ }
+
+ ~FCLocker() {
+ AssertHeld();
+ if (FcGetVersion() < 21091) {
+ gFCMutex.release();
+ } else {
+ SkDEBUGCODE(*THREAD_FC_LOCKED = false);
+ }
+ }
+
+ static void AssertHeld() { SkDEBUGCODE(
+ if (FcGetVersion() < 21091) {
+ gFCMutex.assertHeld();
+ } else {
+ SkASSERT(true == *THREAD_FC_LOCKED);
+ }
+ ) }
+};
+
+} // namespace
+
size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const {
size_t size = sizeof(fID) + sizeof(fTTCIndex);
size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, width, italic
@@ -448,7 +498,7 @@ static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
#define kMaxFontFamilyLength 2048
SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() {
- SkAutoMutexAcquire ac(mutex_);
+ FCLocker lock;
FcInit();
@@ -532,7 +582,7 @@ bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
return false;
}
- SkAutoMutexAcquire ac(mutex_);
+ FCLocker lock;
FcPattern* pattern = FcPatternCreate();
@@ -649,7 +699,7 @@ static bool find_name(const SkTDArray<const char*>& list, const char* str) {
}
SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
- SkAutoMutexAcquire ac(mutex_);
+ FCLocker lock;
FcPattern* pat = FcPatternCreate();
SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat);