From f1a1e8d5528d123890c9e86f672084b86c69dcfe Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 14 May 2012 16:30:59 -0400 Subject: Cleanup pixel ref mutexes in Skia Mutexes in pixelrefs were done very sloppily initially. The code (a) assumes all pixelref subclasses want a mutex to guard their lock/unlock virtuals, and (b) most subclasses use the same mutex for *all* of their instances, even when there is no explicit need to guard modifying one instances with another. When we try drawing bitmaps from multiple threads, we are seeing a lot of slow- down from these mutexes. This CL has two changes to try to speed things up. 1. Add setPreLocked(), for pixelrefs who never need the onLockPixels virtual to be called. This speeds up those subclasses in multithreaded environs as it avoids the mutex lock all together (e.g. SkMallocPixelRef). 2. Add setMutex() to allow a subclass to change the mutex choice. ashmem wants this, since its unflattening constructor cannot pass down the null, it needs to cleanup afterwards. see https://codereview.appspot.com/6199075/ bug: 6469917 Change-Id: I81a7cfa0b2ead5a42059697eafa58de1e7a87da2 --- include/core/SkPixelRef.h | 23 ++++++++++++++++++++--- include/core/SkThread_platform.h | 7 +++++-- 2 files changed, 25 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index d5f6ab2..f01ba15 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -63,9 +63,10 @@ public: */ SkColorTable* colorTable() const { return fColorTable; } - /** Return the current lockcount (defaults to 0) - */ - int getLockCount() const { return fLockCount; } + /** + * Returns true if the lockcount > 0 + */ + bool isLocked() const { return fLockCount > 0; } /** Call to access the pixel memory, which is returned. Balance with a call to unlockPixels(). @@ -205,6 +206,18 @@ protected: SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); + // only call from constructor. Flags this to always be locked, removing + // the need to grab the mutex and call onLockPixels/onUnlockPixels. + // Performance tweak to avoid those calls (esp. in multi-thread use case). + void setPreLocked(void* pixels, SkColorTable* ctable); + + // only call from constructor. Specify a (possibly) different mutex, or + // null to use the default. Use with caution. + // The default logic is to provide a mutex, but possibly one that is + // shared with other instances, though this sharing is implementation + // specific, and it is legal for each instance to have its own mutex. + void useDefaultMutex() { this->setMutex(NULL); } + private: #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS static void InitializeFlattenables(); @@ -221,6 +234,10 @@ private: // can go from false to true, but never from true to false bool fIsImmutable; + // only ever set in constructor, const after that + bool fPreLocked; + + void setMutex(SkBaseMutex* mutex); friend class SkGraphics; }; diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h index 863f6e3..58311e1 100644 --- a/include/core/SkThread_platform.h +++ b/include/core/SkThread_platform.h @@ -75,6 +75,8 @@ struct SkBaseMutex { // Special case used when the static mutex must be available globally. #define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } +#define SK_DECLARE_MUTEX_ARRAY(name, count) SkBaseMutex name[count] = { PTHREAD_MUTEX_INITIALIZER } + // A normal mutex that requires to be initialized through normal C++ construction, // i.e. when it's a member of another class, or allocated on the heap. class SkMutex : public SkBaseMutex, SkNoncopyable { @@ -106,8 +108,9 @@ private: typedef SkMutex SkBaseMutex; -#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name -#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name +#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name +#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name +#define SK_DECLARE_MUTEX_ARRAY(name, count) SkBaseMutex name[count] #endif // !SK_USE_POSIX_THREADS -- cgit v1.1