}
virtual void onDraw(const int loops, SkCanvas*) {
- SK_DECLARE_STATIC_MUTEX(mu);
+ SkMutex mu;
for (int i = 0; i < loops; i++) {
mu.acquire();
mu.release();
return gChildren; \
} \
\
+ static void create_mutex(SkMutex** mutex) { \
+ *mutex = SkNEW(SkMutex); \
+ } \
static SkBaseMutex& GetChildrenMutex() { \
- SK_DECLARE_STATIC_MUTEX(childrenMutex); \
- return childrenMutex; \
+ static SkMutex* childrenMutex; \
+ SK_DECLARE_STATIC_ONCE(once); \
+ SkOnce(&once, className::SkInstanceCountHelper::create_mutex, &childrenMutex);\
+ return *childrenMutex; \
} \
\
} fInstanceCountHelper; \
};
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ...
-#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = ...
*/
#include SK_MUTEX_PLATFORM_H
*/
class GrFontDescKey : public SkRefCnt {
public:
- SK_DECLARE_INST_COUNT(SkGrDescKey)
+ SK_DECLARE_INST_COUNT(GrFontDescKey)
typedef uint32_t Hash;
}
};
+SK_DECLARE_STATIC_MUTEX(gCreateDefaultMutex);
SkTypeface* SkTypeface::CreateDefault(int style) {
// If backed by fontconfig, it's not safe to call SkFontHost::CreateTypeface concurrently.
// To be safe, we serialize here with a mutex so only one call to
// CreateTypeface is happening at any given time.
// TODO(bungeman, mtklein): This is sad. Make our fontconfig code safe?
- SK_DECLARE_STATIC_MUTEX(mutex);
- SkAutoMutexAcquire lock(&mutex);
+ SkAutoMutexAcquire lock(&gCreateDefaultMutex);
SkTypeface* t = SkFontHost::CreateTypeface(NULL, NULL, (Style)style);
return t ? t : SkEmptyTypeface::Create();
return fCache;
}
+SK_DECLARE_STATIC_MUTEX(gGradientCacheMutex);
/*
* Because our caller might rebuild the same (logically the same) gradient
* over and over, we'd like to return exactly the same "bitmap" if possible,
///////////////////////////////////
- SK_DECLARE_STATIC_MUTEX(gMutex);
static SkBitmapCache* gCache;
// each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp
static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
- SkAutoMutexAcquire ama(gMutex);
+ SkAutoMutexAcquire ama(gGradientCacheMutex);
if (NULL == gCache) {
gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
*/
class GrDrawTargetCaps : public SkRefCnt {
public:
- SK_DECLARE_INST_COUNT(Caps)
+ SK_DECLARE_INST_COUNT(GrDrawTargetCaps)
GrDrawTargetCaps() { this->reset(); }
GrDrawTargetCaps(const GrDrawTargetCaps& other) : INHERITED() { *this = other; }
return gCanonicalFonts;
}
+SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
// static
SkBaseMutex& SkPDFFont::CanonicalFontsMutex() {
- SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
return gCanonicalFontsMutex;
}
return gCanonicalPaints;
}
+SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
// static
SkBaseMutex& SkPDFGraphicState::CanonicalPaintsMutex() {
- SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
return gCanonicalPaintsMutex;
}
return gCanonicalShaders;
}
+SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
// static
SkBaseMutex& SkPDFShader::CanonicalShadersMutex() {
- SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
return gCanonicalShadersMutex;
}
///////////////////////////////////////////////////////////////////////////////
+SK_DECLARE_STATIC_MUTEX(gGetSingletonInterfaceMutex);
static SkFontConfigInterfaceAndroid* getSingletonInterface() {
- SK_DECLARE_STATIC_MUTEX(gMutex);
static SkFontConfigInterfaceAndroid* gFontConfigInterface;
- SkAutoMutexAcquire ac(gMutex);
+ SkAutoMutexAcquire ac(gGetSingletonInterfaceMutex);
if (NULL == gFontConfigInterface) {
// load info from a configuration file that we can use to populate the
// system/fallback font structures
return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL;
}
+SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex);
static SkTypeface* GetDefaultFace() {
- SK_DECLARE_STATIC_MUTEX(gMutex);
- SkAutoMutexAcquire ma(gMutex);
+ SkAutoMutexAcquire ma(gGetDefaultFaceMutex);
static SkTypeface* gDefaultFace;
#define SK_BASE_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, SkDEBUGCODE(0) }
// Using POD-style initialization prevents the generation of a static initializer.
-#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = SK_BASE_MUTEX_INIT
-
-// Special case used when the static mutex must be available globally.
-#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = SK_BASE_MUTEX_INIT
+// Without magic statics there are no thread safety guarantees on initialization
+// of local statics (even POD).
+// As a result, it is illegal to SK_DECLARE_STATIC_MUTEX in a function.
+#define SK_DECLARE_STATIC_MUTEX(name) \
+ static inline void SK_MACRO_APPEND_LINE(name)(){} \
+ static SkBaseMutex name = SK_BASE_MUTEX_INIT
#endif
class SkMutex : public SkBaseMutex { };
// Windows currently provides no documented means of POD initializing a CRITICAL_SECTION.
-#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name
-#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name
+// As a result, it is illegal to SK_DECLARE_STATIC_MUTEX in a function.
+#define SK_DECLARE_STATIC_MUTEX(name) \
+ static inline void SK_MACRO_APPEND_LINE(name)(){} \
+ static SkBaseMutex name
#endif
}
}
+SK_DECLARE_STATIC_MUTEX(compareDebugOut3);
+SK_DECLARE_STATIC_MUTEX(compareDebugOut4);
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) {
}
const int MAX_ERRORS = 8;
if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
- SK_DECLARE_STATIC_MUTEX(compareDebugOut3);
SkAutoMutexAcquire autoM(compareDebugOut3);
SkDebugf("\n*** this test fails ***\n");
showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
REPORTER_ASSERT(reporter, 0);
} else if (gShowPath || errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
- SK_DECLARE_STATIC_MUTEX(compareDebugOut4);
SkAutoMutexAcquire autoM(compareDebugOut4);
showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
}
outFile.flush();
}
+SK_DECLARE_STATIC_MUTEX(simplifyDebugOut);
bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
const char* pathStr) {
SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
}
int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap);
if (result && gPathStrAssert) {
- SK_DECLARE_STATIC_MUTEX(simplifyDebugOut);
SkAutoMutexAcquire autoM(simplifyDebugOut);
char temp[8192];
sk_bzero(temp, sizeof(temp));