Bug 1404742 - track ScaledFont and UnscaledFont lifetimes with ThreadSafeWeakPointer. r=bas
authorLee Salzman <lsalzman@mozilla.com>
Wed, 18 Oct 2017 14:22:09 -0400
changeset 387007 16a80fc4e1026d42d148e834f41237b35d0474b8
parent 387006 efd9a7070a08bdcf2077f3b9cf230f6462ce671a
child 387008 1e8b051b15f8418405b3b1bb8ca2f85a16bc8a91
push id32705
push userryanvm@gmail.com
push dateThu, 19 Oct 2017 01:01:49 +0000
treeherdermozilla-central@a21099ce055f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1404742
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1404742 - track ScaledFont and UnscaledFont lifetimes with ThreadSafeWeakPointer. r=bas MozReview-Commit-ID: GRSEYh1fG4U
gfx/2d/2D.h
gfx/layers/wr/WebRenderBridgeChild.h
gfx/thebes/gfxDWriteFontList.cpp
gfx/thebes/gfxDWriteFontList.h
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFT2FontList.h
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
gfx/thebes/gfxGDIFontList.cpp
gfx/thebes/gfxGDIFontList.h
gfx/thebes/gfxMacPlatformFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -21,20 +21,19 @@
 // to be able to hold on to a GLContext.
 #include "mozilla/GenericRefCounted.h"
 #include "mozilla/MemoryReporting.h"
 
 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
 // outparams using the &-operator. But it will have to do as there's no easy
 // solution.
 #include "mozilla/RefPtr.h"
-#include "mozilla/ServoUtils.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/StaticPtr.h"
-#include "mozilla/WeakPtr.h"
+#include "mozilla/ThreadSafeWeakPtr.h"
 
 #include "mozilla/DebugOnly.h"
 
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
   #ifndef MOZ_ENABLE_FREETYPE
   #define MOZ_ENABLE_FREETYPE
   #endif
 #endif
@@ -77,38 +76,16 @@ struct FontInstanceOptions;
 struct FontInstancePlatformOptions;
 }
 
 namespace gfx {
 class UnscaledFont;
 class ScaledFont;
 }
 
-template<>
-struct WeakPtrTraits<gfx::UnscaledFont>
-{
-  static void AssertSafeToAccessFromNonOwningThread()
-  {
-    // We want to allow UnscaledFont objects that were created on the main
-    // thread to be accessed from other threads if the Servo font metrics
-    // mutex is locked, and for objects created on Servo style worker threads
-    // to be accessed later back on the main thread.
-    AssertIsMainThreadOrServoFontMetricsLocked();
-  }
-};
-
-template<>
-struct WeakPtrTraits<gfx::ScaledFont>
-{
-  static void AssertSafeToAccessFromNonOwningThread()
-  {
-    AssertIsMainThreadOrServoFontMetricsLocked();
-  }
-};
-
 namespace gfx {
 
 class ScaledFont;
 class SourceSurface;
 class DataSourceSurface;
 class DrawTarget;
 class DrawEventRecorder;
 class FilterNode;
@@ -745,23 +722,21 @@ struct GlyphMetrics
   // glyph, this is used when drawing vertically and will typically be 0.
   Float mYAdvance;
   // Width of the glyph's black box.
   Float mWidth;
   // Height of the glyph's black box.
   Float mHeight;
 };
 
-class UnscaledFont
-  : public external::AtomicRefCounted<UnscaledFont>
-  , public SupportsWeakPtr<UnscaledFont>
+class UnscaledFont : public SupportsThreadSafeWeakPtr<UnscaledFont>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFont)
-  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(UnscaledFont)
+  MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(UnscaledFont)
 
   virtual ~UnscaledFont();
 
   virtual FontType GetType() const = 0;
 
   static uint32_t DeletionCounter() { return sDeletionCounter; }
 
   typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex,
@@ -791,23 +766,21 @@ protected:
 private:
   static Atomic<uint32_t> sDeletionCounter;
 };
 
 /** This class is an abstraction of a backend/platform specific font object
  * at a particular size. It is passed into text drawing calls to describe
  * the font used for the drawing call.
  */
-class ScaledFont
-  : public external::AtomicRefCounted<ScaledFont>
-  , public SupportsWeakPtr<ScaledFont>
+class ScaledFont : public SupportsThreadSafeWeakPtr<ScaledFont>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
-  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ScaledFont)
+  MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(ScaledFont)
 
   virtual ~ScaledFont();
 
   virtual FontType GetType() const = 0;
   virtual Float GetSize() const = 0;
   virtual AntialiasMode GetDefaultAAMode();
 
   static uint32_t DeletionCounter() { return sDeletionCounter; }
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -25,40 +25,40 @@ class IpcResourceUpdateQueue;
 namespace layers {
 
 class CompositableClient;
 class CompositorBridgeChild;
 class StackingContextHelper;
 class TextureForwarder;
 
 template<class T>
-class WeakPtrHashKey : public PLDHashEntryHdr
+class ThreadSafeWeakPtrHashKey : public PLDHashEntryHdr
 {
 public:
-  typedef T* KeyType;
+  typedef RefPtr<T> KeyType;
   typedef const T* KeyTypePointer;
 
-  explicit WeakPtrHashKey(KeyTypePointer aKey) : mKey(const_cast<KeyType>(aKey)) {}
+  explicit ThreadSafeWeakPtrHashKey(KeyTypePointer aKey) : mKey(do_AddRef(const_cast<T*>(aKey))) {}
 
-  KeyType GetKey() const { return mKey; }
-  bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
+  KeyType GetKey() const { return do_AddRef(mKey); }
+  bool KeyEquals(KeyTypePointer aKey) const { return mKey == aKey; }
 
-  static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
+  static KeyTypePointer KeyToPointer(const KeyType& aKey) { return aKey.get(); }
   static PLDHashNumber HashKey(KeyTypePointer aKey)
   {
     return NS_PTR_TO_UINT32(aKey) >> 2;
   }
   enum { ALLOW_MEMMOVE = true };
 
 private:
-  WeakPtr<T> mKey;
+  ThreadSafeWeakPtr<T> mKey;
 };
 
-typedef WeakPtrHashKey<gfx::UnscaledFont> UnscaledFontHashKey;
-typedef WeakPtrHashKey<gfx::ScaledFont> ScaledFontHashKey;
+typedef ThreadSafeWeakPtrHashKey<gfx::UnscaledFont> UnscaledFontHashKey;
+typedef ThreadSafeWeakPtrHashKey<gfx::ScaledFont> ScaledFontHashKey;
 
 class WebRenderBridgeChild final : public PWebRenderBridgeChild
                                  , public CompositableForwarder
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild, override)
 
 public:
   explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -586,20 +586,19 @@ gfxDWriteFontEntry::ReadCMAP(FontInfoDat
 
     return rv;
 }
 
 gfxFont *
 gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
                                        bool aNeedsBold)
 {
-    WeakPtr<UnscaledFont>& unscaledFontPtr =
+    ThreadSafeWeakPtr<UnscaledFontDWrite>& unscaledFontPtr =
         aNeedsBold ? mUnscaledFontBold : mUnscaledFont;
-    RefPtr<UnscaledFontDWrite> unscaledFont =
-        static_cast<UnscaledFontDWrite*>(unscaledFontPtr.get());
+    RefPtr<UnscaledFontDWrite> unscaledFont(unscaledFontPtr);
     if (!unscaledFont) {
         DWRITE_FONT_SIMULATIONS sims = DWRITE_FONT_SIMULATIONS_NONE;
         if (aNeedsBold) {
             sims |= DWRITE_FONT_SIMULATIONS_BOLD;
         }
         RefPtr<IDWriteFontFace> fontFace;
         nsresult rv = CreateFontFace(getter_AddRefs(fontFace), sims);
         if (NS_FAILED(rv)) {
--- a/gfx/thebes/gfxDWriteFontList.h
+++ b/gfx/thebes/gfxDWriteFontList.h
@@ -207,18 +207,18 @@ protected:
     // style simulations applied
     RefPtr<IDWriteFontFace> mFontFace;
 
     DWRITE_FONT_FACE_TYPE mFaceType;
 
     int8_t mIsCJK;
     bool mForceGDIClassic;
 
-    mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
-    mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFontBold;
+    mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFont;
+    mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontDWrite> mUnscaledFontBold;
 };
 
 // custom text renderer used to determine the fallback font for a given char
 class DWriteFontFallbackRenderer final : public IDWriteTextRenderer
 {
 public:
     explicit DWriteFontFallbackRenderer(IDWriteFactory *aFactory)
         : mRefCount(0)
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -244,18 +244,17 @@ FT2FontEntry::Clone() const
 gfxFont*
 FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold)
 {
     cairo_scaled_font_t *scaledFont = CreateScaledFont(aFontStyle);
     if (!scaledFont) {
         return nullptr;
     }
 
-    RefPtr<UnscaledFontFreeType> unscaledFont =
-        static_cast<UnscaledFontFreeType*>(mUnscaledFont.get());
+    RefPtr<UnscaledFontFreeType> unscaledFont(mUnscaledFont);
     if (!unscaledFont) {
         unscaledFont =
             mFilename.IsEmpty() ?
                 new UnscaledFontFreeType(mFTFace) :
                 new UnscaledFontFreeType(mFilename.BeginReading(),
                                          mFTFontIndex);
         mUnscaledFont = unscaledFont;
     }
--- a/gfx/thebes/gfxFT2FontList.h
+++ b/gfx/thebes/gfxFT2FontList.h
@@ -93,17 +93,17 @@ public:
                                         FontListSizes* aSizes) const override;
 
     FT_Face mFTFace;
     cairo_font_face_t *mFontFace;
 
     nsCString mFilename;
     uint8_t   mFTFontIndex;
 
-    mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
+    mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFreeType> mUnscaledFont;
 };
 
 class FT2FontFamily : public gfxFontFamily
 {
 public:
     FT2FontFamily(const nsAString& aName) :
         gfxFontFamily(aName) { }
 
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -809,35 +809,34 @@ PreparePattern(FcPattern* aPattern, bool
     }
 
     FcDefaultSubstitute(aPattern);
 }
 
 void
 gfxFontconfigFontEntry::UnscaledFontCache::MoveToFront(size_t aIndex) {
     if (aIndex > 0) {
-        WeakPtr<UnscaledFont> front =
+        ThreadSafeWeakPtr<UnscaledFontFontconfig> front =
             Move(mUnscaledFonts[aIndex]);
         for (size_t i = aIndex; i > 0; i--) {
             mUnscaledFonts[i] = Move(mUnscaledFonts[i-1]);
         }
         mUnscaledFonts[0] = Move(front);
     }
 }
 
 already_AddRefed<UnscaledFontFontconfig>
 gfxFontconfigFontEntry::UnscaledFontCache::Lookup(const char* aFile, uint32_t aIndex) {
     for (size_t i = 0; i < kNumEntries; i++) {
-        UnscaledFontFontconfig* entry =
-            static_cast<UnscaledFontFontconfig*>(mUnscaledFonts[i].get());
+        RefPtr<UnscaledFontFontconfig> entry(mUnscaledFonts[i]);
         if (entry &&
             !strcmp(entry->GetFile(), aFile) &&
             entry->GetIndex() == aIndex) {
             MoveToFront(i);
-            return do_AddRef(entry);
+            return entry.forget();
         }
     }
     return nullptr;
 }
 
 static inline gfxFloat
 SizeForStyle(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle)
 {
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -162,17 +162,17 @@ protected:
             mUnscaledFonts[kNumEntries-1] = aUnscaledFont;
             MoveToFront(kNumEntries-1);
         }
 
     private:
         void MoveToFront(size_t aIndex);
 
         static const size_t kNumEntries = 3;
-        mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFonts[kNumEntries];
+        mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFontconfig> mUnscaledFonts[kNumEntries];
     };
 
     UnscaledFontCache mUnscaledFontCache;
 };
 
 class gfxFontconfigFontFamily : public gfxFontFamily {
 public:
     explicit gfxFontconfigFontFamily(const nsAString& aName) :
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -239,18 +239,17 @@ GDIFontEntry::CopyFontTable(uint32_t aTa
         }
     }
     return NS_ERROR_FAILURE;
 }
 
 already_AddRefed<UnscaledFontGDI>
 GDIFontEntry::LookupUnscaledFont(HFONT aFont)
 {
-    RefPtr<UnscaledFontGDI> unscaledFont =
-        static_cast<UnscaledFontGDI*>(mUnscaledFont.get());
+    RefPtr<UnscaledFontGDI> unscaledFont(mUnscaledFont);
     if (!unscaledFont) {
         LOGFONT lf;
         GetObject(aFont, sizeof(LOGFONT), &lf);
         unscaledFont = new UnscaledFontGDI(lf);
         mUnscaledFont = unscaledFont;
     }
 
     return unscaledFont.forget();
--- a/gfx/thebes/gfxGDIFontList.h
+++ b/gfx/thebes/gfxGDIFontList.h
@@ -199,17 +199,17 @@ protected:
 
     virtual nsresult CopyFontTable(uint32_t aTableTag,
                                    nsTArray<uint8_t>& aBuffer) override;
 
     already_AddRefed<mozilla::gfx::UnscaledFontGDI> LookupUnscaledFont(HFONT aFont);
 
     LOGFONTW mLogFont;
 
-    mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
+    mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontGDI> mUnscaledFont;
 };
 
 // a single font family, referencing one or more faces
 class GDIFontFamily : public gfxFontFamily
 {
 public:
     explicit GDIFontFamily(const nsAString& aName) :
         gfxFontFamily(aName),
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -98,17 +98,17 @@ protected:
     bool mIsCFFInitialized;
     bool mHasVariations;
     bool mHasVariationsInitialized;
     bool mHasAATSmallCaps;
     bool mHasAATSmallCapsInitialized;
     bool mCheckedForTracking;
     nsTHashtable<nsUint32HashKey> mAvailableTables;
 
-    mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
+    mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;
 
     // For AAT font being shaped by Core Text, a strong reference to the 'trak'
     // table (if present).
     hb_blob_t* mTrakTable;
     // Cached pointers to tables within 'trak', initialized by ParseTrakTable.
     const mozilla::AutoSwap_PRInt16* mTrakValues;
     const mozilla::AutoSwap_PRInt32* mTrakSizeTable;
     uint16_t mNumTrakSizes;
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -259,18 +259,17 @@ MacOSFontEntry::ReadCMAP(FontInfoData *a
     }
 
     return rv;
 }
 
 gfxFont*
 MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold)
 {
-    RefPtr<UnscaledFontMac> unscaledFont =
-        static_cast<UnscaledFontMac*>(mUnscaledFont.get());
+    RefPtr<UnscaledFontMac> unscaledFont(mUnscaledFont);
     if (!unscaledFont) {
         CGFontRef baseFont = GetFontRef();
         if (!baseFont) {
             return nullptr;
         }
         unscaledFont = new UnscaledFontMac(baseFont);
         mUnscaledFont = unscaledFont;
     }