Remove all global mutexes
Remove the SkBaseMutex (and SkBaseSemaphore). This allows all the thread annotation machinery to work. Change-Id: I2da420ec3165ccbcd90c474c0b62bfef42df2a53 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/221340 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
17a9655db2
commit
9c71e7be10
@ -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<SkString> 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);
|
||||
}
|
||||
|
@ -20,10 +20,14 @@
|
||||
namespace DM {
|
||||
|
||||
SkTArray<JsonWriter::BitmapResult> 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();
|
||||
|
@ -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 <typename T>
|
||||
SkAutoMutexAcquire(T* mutex) : fMutex(mutex) {
|
||||
if (mutex) {
|
||||
mutex->acquire();
|
||||
}
|
||||
fRelease = [](void* mutex) { ((T*)mutex)->release(); };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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
|
||||
|
@ -12,10 +12,12 @@
|
||||
#include "include/private/SkOnce.h"
|
||||
#include <atomic>
|
||||
|
||||
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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
|
||||
#include <mach/mach.h>
|
||||
|
||||
// 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 <errno.h>
|
||||
#include <semaphore.h>
|
||||
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);
|
||||
|
@ -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<SkTypeface> face) {
|
||||
SkAutoMutexAcquire ama(gMutex);
|
||||
SkAutoMutexExclusive ama(typeface_cache_mutex());
|
||||
Get().add(std::move(face));
|
||||
}
|
||||
|
||||
sk_sp<SkTypeface> 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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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> 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> SkFontConfigInterface::RefGlobal() {
|
||||
}
|
||||
|
||||
void SkFontConfigInterface::SetGlobal(sk_sp<SkFontConfigInterface> fc) {
|
||||
SkAutoMutexAcquire ac(gFontConfigInterfaceMutex);
|
||||
SkAutoMutexExclusive ac(font_config_interface_mutex());
|
||||
|
||||
SkSafeUnref(gFontConfigInterface);
|
||||
gFontConfigInterface = fc.release();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<SkTypeface> 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<SkTypeface> 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));
|
||||
|
@ -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<bool*>(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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user