diff --git a/dm/DM.cpp b/dm/DM.cpp index d2b9da35af..506913747e 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -18,7 +18,6 @@ #include "include/ports/SkTypeface_win.h" #include "include/private/SkChecksum.h" #include "include/private/SkHalf.h" -#include "include/private/SkMutex.h" #include "include/private/SkSpinlock.h" #include "include/private/SkTHash.h" #include "src/core/SkColorSpacePriv.h" @@ -182,11 +181,11 @@ static void info(const char* fmt) { } } -SK_DECLARE_STATIC_MUTEX(gFailuresMutex); static SkTArray gFailures; static void fail(const SkString& err) { - SkAutoMutexAcquire lock(gFailuresMutex); + static SkSpinlock mutex; + SkAutoSpinlock lock(mutex); SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); gFailures.push_back(err); } diff --git a/dm/DMJsonWriter.cpp b/dm/DMJsonWriter.cpp index e08ca0b2af..f0d6a8d1cc 100644 --- a/dm/DMJsonWriter.cpp +++ b/dm/DMJsonWriter.cpp @@ -20,10 +20,14 @@ namespace DM { SkTArray gBitmapResults; -SK_DECLARE_STATIC_MUTEX(gBitmapResultLock); +static SkMutex& bitmap_result_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} + void JsonWriter::AddBitmapResult(const BitmapResult& result) { - SkAutoMutexAcquire lock(&gBitmapResultLock); + SkAutoMutexExclusive lock(bitmap_result_mutex()); gBitmapResults.push_back(result); } @@ -57,7 +61,7 @@ void JsonWriter::DumpJson(const char* dir, } { - SkAutoMutexAcquire lock(&gBitmapResultLock); + SkAutoMutexExclusive lock(bitmap_result_mutex()); writer.beginArray("results"); for (int i = 0; i < gBitmapResults.count(); i++) { writer.beginObject(); diff --git a/include/private/SkMutex.h b/include/private/SkMutex.h index cb7ad7a767..a9af46fdc1 100644 --- a/include/private/SkMutex.h +++ b/include/private/SkMutex.h @@ -14,32 +14,6 @@ #include "include/private/SkThreadAnnotations.h" #include "include/private/SkThreadID.h" -#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name; - -class SkBaseMutex { -public: - constexpr SkBaseMutex() = default; - - void acquire() { - fSemaphore.wait(); - SkDEBUGCODE(fOwner = SkGetThreadID();) - } - - void release() { - this->assertHeld(); - SkDEBUGCODE(fOwner = kIllegalThreadID;) - fSemaphore.signal(); - } - - void assertHeld() { - SkASSERT(fOwner == SkGetThreadID()); - } - -protected: - SkBaseSemaphore fSemaphore{1}; - SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) -}; - class SK_CAPABILITY("mutex") SkMutex { public: constexpr SkMutex() = default; @@ -64,34 +38,6 @@ private: SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) }; -class SkAutoMutexAcquire { -public: - template - SkAutoMutexAcquire(T* mutex) : fMutex(mutex) { - if (mutex) { - mutex->acquire(); - } - fRelease = [](void* mutex) { ((T*)mutex)->release(); }; - } - - template - SkAutoMutexAcquire(T& mutex) : SkAutoMutexAcquire(&mutex) {} - - ~SkAutoMutexAcquire() { this->release(); } - - void release() { - if (fMutex) { - fRelease(fMutex); - } - fMutex = nullptr; - } - -private: - void* fMutex; - void (*fRelease)(void*); -}; -#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) - class SK_SCOPED_CAPABILITY SkAutoMutexExclusive { public: SkAutoMutexExclusive(SkMutex& mutex) SK_ACQUIRE(mutex) : fMutex(mutex) { fMutex.acquire(); } @@ -103,4 +49,4 @@ private: #define SkAutoMutexExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexExclusive) -#endif//SkMutex_DEFINED +#endif // SkMutex_DEFINED diff --git a/include/private/SkSemaphore.h b/include/private/SkSemaphore.h index 145047799b..29bbca6fa9 100644 --- a/include/private/SkSemaphore.h +++ b/include/private/SkSemaphore.h @@ -12,10 +12,12 @@ #include "include/private/SkOnce.h" #include -class SkBaseSemaphore { +class SkSemaphore { public: - constexpr SkBaseSemaphore(int count = 0) - : fCount(count), fOSSemaphore(nullptr) {} + constexpr SkSemaphore(int count = 0) : fCount(count), fOSSemaphore(nullptr) {} + + // Cleanup the underlying OS semaphore. + ~SkSemaphore(); // Increment the counter n times. // Generally it's better to call signal(n) instead of signal() n times. @@ -28,9 +30,6 @@ public: // If the counter is positive, decrement it by 1 and return true, otherwise return false. bool try_wait(); - // SkBaseSemaphore has no destructor. Call this to clean it up. - void cleanup(); - private: // This implementation follows the general strategy of // 'A Lightweight Semaphore with Partial Spinning' @@ -51,13 +50,7 @@ private: OSSemaphore* fOSSemaphore; }; -class SkSemaphore : public SkBaseSemaphore { -public: - using SkBaseSemaphore::SkBaseSemaphore; - ~SkSemaphore() { this->cleanup(); } -}; - -inline void SkBaseSemaphore::signal(int n) { +inline void SkSemaphore::signal(int n) { int prev = fCount.fetch_add(n, std::memory_order_release); // We only want to call the OS semaphore when our logical count crosses @@ -75,7 +68,7 @@ inline void SkBaseSemaphore::signal(int n) { } } -inline void SkBaseSemaphore::wait() { +inline void SkSemaphore::wait() { // Since this fetches the value before the subtract, zero and below means that there are no // resources left, so the thread needs to wait. if (fCount.fetch_sub(1, std::memory_order_acquire) <= 0) { diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp index a528430307..1208937d37 100644 --- a/src/core/SkResourceCache.cpp +++ b/src/core/SkResourceCache.cpp @@ -449,13 +449,16 @@ void SkResourceCache::checkMessages() { /////////////////////////////////////////////////////////////////////////////// -SK_DECLARE_STATIC_MUTEX(gMutex); static SkResourceCache* gResourceCache = nullptr; +static SkMutex& resource_cache_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} -/** Must hold gMutex when calling. */ +/** Must hold resource_cache_mutex() when calling. */ static SkResourceCache* get_cache() { - // gMutex is always held when this is called, so we don't need to be fancy in here. - gMutex.assertHeld(); + // resource_cache_mutex() is always held when this is called, so we don't need to be fancy in here. + resource_cache_mutex().assertHeld(); if (nullptr == gResourceCache) { #ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE gResourceCache = new SkResourceCache(SkDiscardableMemory::Create); @@ -467,67 +470,67 @@ static SkResourceCache* get_cache() { } size_t SkResourceCache::GetTotalBytesUsed() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->getTotalBytesUsed(); } size_t SkResourceCache::GetTotalByteLimit() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->getTotalByteLimit(); } size_t SkResourceCache::SetTotalByteLimit(size_t newLimit) { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->setTotalByteLimit(newLimit); } SkResourceCache::DiscardableFactory SkResourceCache::GetDiscardableFactory() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->discardableFactory(); } SkCachedData* SkResourceCache::NewCachedData(size_t bytes) { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->newCachedData(bytes); } void SkResourceCache::Dump() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); get_cache()->dump(); } size_t SkResourceCache::SetSingleAllocationByteLimit(size_t size) { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->setSingleAllocationByteLimit(size); } size_t SkResourceCache::GetSingleAllocationByteLimit() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->getSingleAllocationByteLimit(); } size_t SkResourceCache::GetEffectiveSingleAllocationByteLimit() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->getEffectiveSingleAllocationByteLimit(); } void SkResourceCache::PurgeAll() { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->purgeAll(); } bool SkResourceCache::Find(const Key& key, FindVisitor visitor, void* context) { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); return get_cache()->find(key, visitor, context); } void SkResourceCache::Add(Rec* rec, void* payload) { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); get_cache()->add(rec, payload); } void SkResourceCache::VisitAll(Visitor visitor, void* context) { - SkAutoMutexAcquire am(gMutex); + SkAutoMutexExclusive am(resource_cache_mutex()); get_cache()->visitAll(visitor, context); } diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index 698d0d4531..2dd2b3a7b2 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -95,10 +95,13 @@ SkScalerContext::~SkScalerContext() {} /** * In order to call cachedDeviceLuminance, cachedPaintLuminance, or - * cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue + * cachedMaskGamma the caller must hold the mask_gamma_cache_mutex and continue * to hold it until the returned pointer is refed or forgotten. */ -SK_DECLARE_STATIC_MUTEX(gMaskGammaCacheMutex); +static SkMutex& mask_gamma_cache_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} static SkMaskGamma* gLinearMaskGamma = nullptr; static SkMaskGamma* gMaskGamma = nullptr; @@ -107,12 +110,12 @@ static SkScalar gPaintGamma = SK_ScalarMin; static SkScalar gDeviceGamma = SK_ScalarMin; /** - * The caller must hold the gMaskGammaCacheMutex and continue to hold it until + * The caller must hold the mask_gamma_cache_mutex() and continue to hold it until * the returned SkMaskGamma pointer is refed or forgotten. */ static const SkMaskGamma& cached_mask_gamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) { - gMaskGammaCacheMutex.assertHeld(); + mask_gamma_cache_mutex().assertHeld(); if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) { if (nullptr == gLinearMaskGamma) { gLinearMaskGamma = new SkMaskGamma; @@ -133,7 +136,7 @@ static const SkMaskGamma& cached_mask_gamma(SkScalar contrast, SkScalar paintGam * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend. */ SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContextRec& rec) { - SkAutoMutexAcquire ama(gMaskGammaCacheMutex); + SkAutoMutexExclusive ama(mask_gamma_cache_mutex()); const SkMaskGamma& maskGamma = cached_mask_gamma(rec.getContrast(), rec.getPaintGamma(), @@ -145,7 +148,7 @@ SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContextRec& size_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, int* width, int* height) { - SkAutoMutexAcquire ama(gMaskGammaCacheMutex); + SkAutoMutexExclusive ama(mask_gamma_cache_mutex()); const SkMaskGamma& maskGamma = cached_mask_gamma(contrast, paintGamma, deviceGamma); @@ -158,7 +161,7 @@ size_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, bool SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, uint8_t* data) { - SkAutoMutexAcquire ama(gMaskGammaCacheMutex); + SkAutoMutexExclusive ama(mask_gamma_cache_mutex()); const SkMaskGamma& maskGamma = cached_mask_gamma(contrast, paintGamma, deviceGamma); diff --git a/src/core/SkSemaphore.cpp b/src/core/SkSemaphore.cpp index 15e7c65ec4..aacc4a1d10 100644 --- a/src/core/SkSemaphore.cpp +++ b/src/core/SkSemaphore.cpp @@ -11,7 +11,7 @@ #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) #include - // We've got to teach TSAN that there is a happens-before edge beteween + // We've got to teach TSAN that there is a happens-before edge between // semaphore_signal() and semaphore_wait(). #if __has_feature(thread_sanitizer) extern "C" void AnnotateHappensBefore(const char*, int, void*); @@ -21,7 +21,7 @@ static void AnnotateHappensAfter (const char*, int, void*) {} #endif - struct SkBaseSemaphore::OSSemaphore { + struct SkSemaphore::OSSemaphore { semaphore_t fSemaphore; OSSemaphore() { @@ -41,7 +41,7 @@ } }; #elif defined(SK_BUILD_FOR_WIN) - struct SkBaseSemaphore::OSSemaphore { + struct SkSemaphore::OSSemaphore { HANDLE fSemaphore; OSSemaphore() { @@ -61,7 +61,7 @@ // It's important we test for Mach before this. This code will compile but not work there. #include #include - struct SkBaseSemaphore::OSSemaphore { + struct SkSemaphore::OSSemaphore { sem_t fSemaphore; OSSemaphore() { sem_init(&fSemaphore, 0/*cross process?*/, 0/*initial count*/); } @@ -77,21 +77,21 @@ /////////////////////////////////////////////////////////////////////////////// -void SkBaseSemaphore::osSignal(int n) { +SkSemaphore::~SkSemaphore() { + delete fOSSemaphore; +} + +void SkSemaphore::osSignal(int n) { fOSSemaphoreOnce([this] { fOSSemaphore = new OSSemaphore; }); fOSSemaphore->signal(n); } -void SkBaseSemaphore::osWait() { +void SkSemaphore::osWait() { fOSSemaphoreOnce([this] { fOSSemaphore = new OSSemaphore; }); fOSSemaphore->wait(); } -void SkBaseSemaphore::cleanup() { - delete fOSSemaphore; -} - -bool SkBaseSemaphore::try_wait() { +bool SkSemaphore::try_wait() { int count = fCount.load(std::memory_order_relaxed); if (count > 0) { return fCount.compare_exchange_weak(count, count-1, std::memory_order_acquire); diff --git a/src/core/SkTypefaceCache.cpp b/src/core/SkTypefaceCache.cpp index c4bc953341..bb4a08dd56 100644 --- a/src/core/SkTypefaceCache.cpp +++ b/src/core/SkTypefaceCache.cpp @@ -62,20 +62,23 @@ SkFontID SkTypefaceCache::NewFontID() { return nextID++; } -SK_DECLARE_STATIC_MUTEX(gMutex); +static SkMutex& typeface_cache_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} void SkTypefaceCache::Add(sk_sp face) { - SkAutoMutexAcquire ama(gMutex); + SkAutoMutexExclusive ama(typeface_cache_mutex()); Get().add(std::move(face)); } sk_sp SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) { - SkAutoMutexAcquire ama(gMutex); + SkAutoMutexExclusive ama(typeface_cache_mutex()); return Get().findByProcAndRef(proc, ctx); } void SkTypefaceCache::PurgeAll() { - SkAutoMutexAcquire ama(gMutex); + SkAutoMutexExclusive ama(typeface_cache_mutex()); Get().purgeAll(); } diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp index 9d497c9ad8..7ee44deb9d 100644 --- a/src/pathops/SkPathOpsDebug.cpp +++ b/src/pathops/SkPathOpsDebug.cpp @@ -557,11 +557,11 @@ static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) { SkDebugf("}\n"); } -SK_DECLARE_STATIC_MUTEX(gTestMutex); - void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp, const char* testName) { - SkAutoMutexAcquire ac(gTestMutex); + static SkMutex& mutex = *(new SkMutex); + + SkAutoMutexExclusive ac(mutex); show_function_header(testName); ShowOnePath(a, "path", true); ShowOnePath(b, "pathB", true); @@ -574,10 +574,9 @@ void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp #if DEBUG_COIN -SK_DECLARE_STATIC_MUTEX(gCoinDictMutex); - void SkOpGlobalState::debugAddToGlobalCoinDicts() { - SkAutoMutexAcquire ac(&gCoinDictMutex); + static SkMutex& mutex = *(new SkMutex); + SkAutoMutexExclusive ac(mutex); SkPathOpsDebug::gCoinSumChangedDict.add(fCoinChangedDict); SkPathOpsDebug::gCoinSumVisitedDict.add(fCoinVisitedDict); } diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index 4421a517df..825ae7b197 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -226,8 +226,6 @@ static const bool gOutInverse[kReverseDifference_SkPathOp + 1][2][2] = { #include "include/private/SkMutex.h" -SK_DECLARE_STATIC_MUTEX(debugWorstLoop); - SkOpGlobalState debugWorstState(nullptr, nullptr SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); void ReportPathOpsDebugging() { @@ -357,8 +355,9 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result } wrapper.assemble(); // if some edges could not be resolved, assemble remaining #if DEBUG_T_SECT_LOOP_COUNT + static SkMutex& debugWorstLoop = *(new SkMutex); { - SkAutoMutexAcquire autoM(debugWorstLoop); + SkAutoMutexExclusive autoM(debugWorstLoop); if (!gVerboseFinalize) { gVerboseFinalize = &ReportPathOpsDebugging; } diff --git a/src/ports/SkFontConfigInterface.cpp b/src/ports/SkFontConfigInterface.cpp index 5569c69175..0ec9c9a547 100644 --- a/src/ports/SkFontConfigInterface.cpp +++ b/src/ports/SkFontConfigInterface.cpp @@ -10,11 +10,14 @@ #include "include/ports/SkFontConfigInterface.h" #include "include/private/SkMutex.h" -SK_DECLARE_STATIC_MUTEX(gFontConfigInterfaceMutex); +static SkMutex& font_config_interface_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} static SkFontConfigInterface* gFontConfigInterface; sk_sp SkFontConfigInterface::RefGlobal() { - SkAutoMutexAcquire ac(gFontConfigInterfaceMutex); + SkAutoMutexExclusive ac(font_config_interface_mutex()); if (gFontConfigInterface) { return sk_ref_sp(gFontConfigInterface); @@ -23,7 +26,7 @@ sk_sp SkFontConfigInterface::RefGlobal() { } void SkFontConfigInterface::SetGlobal(sk_sp fc) { - SkAutoMutexAcquire ac(gFontConfigInterfaceMutex); + SkAutoMutexExclusive ac(font_config_interface_mutex()); SkSafeUnref(gFontConfigInterface); gFontConfigInterface = fc.release(); diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp index b471692860..84fd11b1f3 100644 --- a/src/ports/SkFontConfigInterface_direct.cpp +++ b/src/ports/SkFontConfigInterface_direct.cpp @@ -31,7 +31,10 @@ 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); +static SkMutex& f_c_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} #ifdef SK_DEBUG void* CreateThreadFcLocked() { return new bool(false); } @@ -45,7 +48,7 @@ struct FCLocker { FCLocker() { if (FcGetVersion() < 21091) { - gFCMutex.acquire(); + f_c_mutex().acquire(); } else { SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED); SkASSERT(false == *threadLocked); @@ -56,7 +59,7 @@ struct FCLocker { ~FCLocker() { AssertHeld(); if (FcGetVersion() < 21091) { - gFCMutex.release(); + f_c_mutex().release(); } else { SkDEBUGCODE(*THREAD_FC_LOCKED = false); } @@ -64,7 +67,7 @@ struct FCLocker { static void AssertHeld() { SkDEBUGCODE( if (FcGetVersion() < 21091) { - gFCMutex.assertHeld(); + f_c_mutex().assertHeld(); } else { SkASSERT(true == *THREAD_FC_LOCKED); } diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index e963217f00..cc4633883a 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -254,16 +254,20 @@ private: struct SkFaceRec; -SK_DECLARE_STATIC_MUTEX(gFTMutex); +static SkMutex& f_t_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} + static FreeTypeLibrary* gFTLibrary; static SkFaceRec* gFaceRecHead; // Private to ref_ft_library and unref_ft_library static int gFTCount; -// Caller must lock gFTMutex before calling this function. +// Caller must lock f_t_mutex() before calling this function. static bool ref_ft_library() { - gFTMutex.assertHeld(); + f_t_mutex().assertHeld(); SkASSERT(gFTCount >= 0); if (0 == gFTCount) { @@ -274,9 +278,9 @@ static bool ref_ft_library() { return gFTLibrary->library(); } -// Caller must lock gFTMutex before calling this function. +// Caller must lock f_t_mutex() before calling this function. static void unref_ft_library() { - gFTMutex.assertHeld(); + f_t_mutex().assertHeld(); SkASSERT(gFTCount > 0); --gFTCount; @@ -387,9 +391,9 @@ static void ft_face_setup_axes(SkFaceRec* rec, const SkFontData& data) { } // Will return nullptr on failure -// Caller must lock gFTMutex before calling this function. +// Caller must lock f_t_mutex() before calling this function. static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { - gFTMutex.assertHeld(); + f_t_mutex().assertHeld(); const SkFontID fontID = typeface->uniqueID(); SkFaceRec* cachedRec = gFaceRecHead; @@ -449,10 +453,10 @@ static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { return rec.release(); } -// Caller must lock gFTMutex before calling this function. +// Caller must lock f_t_mutex() before calling this function. // Marked extern because vc++ does not support internal linkage template parameters. extern /*static*/ void unref_ft_face(SkFaceRec* faceRec) { - gFTMutex.assertHeld(); + f_t_mutex().assertHeld(); SkFaceRec* rec = gFaceRecHead; SkFaceRec* prev = nullptr; @@ -478,7 +482,7 @@ extern /*static*/ void unref_ft_face(SkFaceRec* faceRec) { class AutoFTAccess { public: AutoFTAccess(const SkTypeface* tf) : fFaceRec(nullptr) { - gFTMutex.acquire(); + f_t_mutex().acquire(); SkASSERT_RELEASE(ref_ft_library()); fFaceRec = ref_ft_face(tf); } @@ -488,7 +492,7 @@ public: unref_ft_face(fFaceRec); } unref_ft_library(); - gFTMutex.release(); + f_t_mutex().release(); } FT_Face face() { return fFaceRec ? fFaceRec->fFace.get() : nullptr; } @@ -549,9 +553,9 @@ private: void getBBoxForCurrentGlyph(const SkGlyph* glyph, FT_BBox* bbox, bool snapToPixelBoundary = false); bool getCBoxForLetter(char letter, FT_BBox* bbox); - // Caller must lock gFTMutex before calling this function. + // Caller must lock f_t_mutex() before calling this function. void updateGlyphIfLCD(SkGlyph* glyph); - // Caller must lock gFTMutex before calling this function. + // Caller must lock f_t_mutex() before calling this function. // update FreeType2 glyph slot with glyph emboldened void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph, SkGlyphID gid); bool shouldSubpixelBitmap(const SkGlyph&, const SkMatrix&); @@ -733,7 +737,7 @@ void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const { if (isLCD(*rec)) { // TODO: re-work so that FreeType is set-up and selected by the SkFontMgr. - SkAutoMutexAcquire ama(gFTMutex); + SkAutoMutexExclusive ama(f_t_mutex()); ref_ft_library(); if (!gFTLibrary->isLCDSupported()) { // If the runtime Freetype library doesn't support LCD, disable it here. @@ -844,7 +848,7 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp typeface, , fFTSize(nullptr) , fStrikeIndex(-1) { - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); SkASSERT_RELEASE(ref_ft_library()); fFaceRec.reset(ref_ft_face(this->getTypeface())); @@ -1022,7 +1026,7 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp typeface, } SkScalerContext_FreeType::~SkScalerContext_FreeType() { - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); if (fFTSize != nullptr) { FT_Done_Size(fFTSize); @@ -1037,7 +1041,7 @@ SkScalerContext_FreeType::~SkScalerContext_FreeType() { this face with other context (at different sizes). */ FT_Error SkScalerContext_FreeType::setupSize() { - gFTMutex.assertHeld(); + f_t_mutex().assertHeld(); FT_Error err = FT_Activate_Size(fFTSize); if (err != 0) { return err; @@ -1058,7 +1062,7 @@ bool SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) { return false; } - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); if (this->setupSize()) { glyph->zeroMetrics(); @@ -1163,7 +1167,7 @@ bool SkScalerContext_FreeType::shouldSubpixelBitmap(const SkGlyph& glyph, const } void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); glyph->fMaskFormat = fRec.fMaskFormat; @@ -1319,7 +1323,7 @@ static void clear_glyph_image(const SkGlyph& glyph) { } void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); if (this->setupSize()) { clear_glyph_image(glyph); @@ -1352,7 +1356,7 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { bool SkScalerContext_FreeType::generatePath(SkGlyphID glyphID, SkPath* path) { SkASSERT(path); - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); // FT_IS_SCALABLE is documented to mean the face contains outline glyphs. if (!FT_IS_SCALABLE(fFace) || this->setupSize()) { @@ -1393,7 +1397,7 @@ void SkScalerContext_FreeType::generateFontMetrics(SkFontMetrics* metrics) { return; } - SkAutoMutexAcquire ac(gFTMutex); + SkAutoMutexExclusive ac(f_t_mutex()); if (this->setupSize()) { sk_bzero(metrics, sizeof(*metrics)); diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp index 55dfb93a81..5131562faf 100644 --- a/src/ports/SkFontMgr_fontconfig.cpp +++ b/src/ports/SkFontMgr_fontconfig.cpp @@ -64,7 +64,10 @@ 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); +static SkMutex& f_c_mutex() { + static SkMutex& mutex = *(new SkMutex); + return mutex; +} #ifdef SK_DEBUG void* CreateThreadFcLocked() { return new bool(false); } @@ -75,19 +78,19 @@ void DeleteThreadFcLocked(void* v) { delete static_cast(v); } class FCLocker { // Assume FcGetVersion() has always been thread safe. - static void lock() { + static void lock() SK_NO_THREAD_SAFETY_ANALYSIS { if (FcGetVersion() < 21091) { - gFCMutex.acquire(); + f_c_mutex().acquire(); } else { SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED); SkASSERT(false == *threadLocked); SkDEBUGCODE(*threadLocked = true); } } - static void unlock() { + static void unlock() SK_NO_THREAD_SAFETY_ANALYSIS { AssertHeld(); if (FcGetVersion() < 21091) { - gFCMutex.release(); + f_c_mutex().release(); } else { SkDEBUGCODE(*THREAD_FC_LOCKED = false); } @@ -109,7 +112,7 @@ public: static void AssertHeld() { SkDEBUGCODE( if (FcGetVersion() < 21091) { - gFCMutex.assertHeld(); + f_c_mutex().assertHeld(); } else { SkASSERT(true == *THREAD_FC_LOCKED); } diff --git a/src/ports/SkTLS_win.cpp b/src/ports/SkTLS_win.cpp index 39ba8c360c..e598c2fb7d 100644 --- a/src/ports/SkTLS_win.cpp +++ b/src/ports/SkTLS_win.cpp @@ -13,15 +13,15 @@ static bool gOnce = false; static DWORD gTlsIndex; -SK_DECLARE_STATIC_MUTEX(gMutex); void* SkTLS::PlatformGetSpecific(bool forceCreateTheSlot) { + static SkMutex& mutex = *(new SkMutex); if (!forceCreateTheSlot && !gOnce) { return nullptr; } if (!gOnce) { - SkAutoMutexAcquire tmp(gMutex); + SkAutoMutexExclusive tmp(mutex); if (!gOnce) { gTlsIndex = TlsAlloc(); gOnce = true; diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp index f55cba33a9..a80e3345c4 100644 --- a/tests/PathOpsExtendedTest.cpp +++ b/tests/PathOpsExtendedTest.cpp @@ -357,12 +357,11 @@ static void showPathOpPath(const char* testName, const SkPath& one, const SkPath drawAsciiPaths(scaledOne, scaledTwo, true); } -SK_DECLARE_STATIC_MUTEX(compareDebugOut3); - static int comparePaths(skiatest::Reporter* reporter, const char* testName, const SkPath& one, const SkPath& scaledOne, const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const SkMatrix& scale, ExpectMatch expectMatch) { + static SkMutex& compareDebugOut3 = *(new SkMutex); int errors2x2; const int MAX_ERRORS = 8; (void) pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); @@ -376,7 +375,7 @@ static int comparePaths(skiatest::Reporter* reporter, const char* testName, cons return 0; } if (ExpectMatch::kYes == expectMatch && errors2x2 >= MAX_ERRORS) { - SkAutoMutexAcquire autoM(compareDebugOut3); + SkAutoMutexExclusive autoM(compareDebugOut3); showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); SkDebugf("\n/*"); REPORTER_ASSERT(reporter, 0); @@ -450,10 +449,9 @@ void markTestFlakyForPathKit() { } } -SK_DECLARE_STATIC_MUTEX(simplifyDebugOut); - bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state, const char* pathStr) { + static SkMutex& simplifyDebugOut = *(new SkMutex); SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType; path.setFillType(fillType); state.fReporter->bumpTestCount(); @@ -467,7 +465,7 @@ bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st } int result = comparePaths(state.fReporter, nullptr, path, out, *state.fBitmap); if (result) { - SkAutoMutexAcquire autoM(simplifyDebugOut); + SkAutoMutexExclusive autoM(simplifyDebugOut); std::string str; const char* pathPrefix = nullptr; const char* nameSuffix = nullptr; @@ -751,11 +749,10 @@ bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& return true; } -SK_DECLARE_STATIC_MUTEX(gMutex); - void initializeTests(skiatest::Reporter* reporter, const char* test) { + static SkMutex& mu = *(new SkMutex); if (reporter->verbose()) { - SkAutoMutexAcquire lock(gMutex); + SkAutoMutexExclusive lock(mu); testName = test; size_t testNameSize = strlen(test); SkFILEStream inFile("../../experimental/Intersection/op.htm");