Bug 1490537 - init and shutdown Skia in the GPU process. r=mattwoodrow
authorLee Salzman <lsalzman@mozilla.com>
Thu, 29 Nov 2018 18:09:46 -0500
changeset 505281 e0639d2ca407392acc67e65cc7eb058363e733e3
parent 505280 3a2c2eb8f481dedfdf7680b856cdef72a34fece9
child 505282 368e88f08417bc4edcd4c4b48b43369083f0e7b4
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1490537
milestone65.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 1490537 - init and shutdown Skia in the GPU process. r=mattwoodrow
gfx/2d/2D.h
gfx/2d/Factory.cpp
gfx/ipc/GPUParent.cpp
gfx/ipc/moz.build
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1860,17 +1860,17 @@ public:
 
   static FT_Face NewFTFace(FT_Library aFTLibrary, const char* aFileName, int aFaceIndex);
   static FT_Face NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize, int aFaceIndex);
   static void ReleaseFTFace(FT_Face aFace);
   static FT_Error LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
 
 private:
   static FT_Library mFTLibrary;
-  static Mutex* mFTLock;
+  static StaticMutex mFTLock;
 public:
 #endif
 
 #ifdef WIN32
   static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
 
   /*
    * Attempts to create and install a D2D1 device from the supplied Direct3D11 device.
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -41,17 +41,16 @@
 
 #ifdef WIN32
 #include "DrawTargetD2D1.h"
 #include "ScaledFontDWrite.h"
 #include "NativeFontResourceDWrite.h"
 #include <d3d10_1.h>
 #include "HelpersD2D.h"
 #include "HelpersWinFonts.h"
-#include "mozilla/Mutex.h"
 #endif
 
 #include "DrawTargetCapture.h"
 #include "DrawTargetDual.h"
 #include "DrawTargetTiled.h"
 #include "DrawTargetOffset.h"
 #include "DrawTargetWrapAndRecord.h"
 #include "DrawTargetRecording.h"
@@ -62,18 +61,16 @@
 
 #include "Logging.h"
 
 #include "mozilla/CheckedInt.h"
 
 #ifdef MOZ_ENABLE_FREETYPE
 #include "ft2build.h"
 #include FT_FREETYPE_H
-
-#include "mozilla/Mutex.h"
 #endif
 #include "MainThreadUtils.h"
 
 #if defined(MOZ_LOGGING)
 GFX2D_API mozilla::LogModule*
 GetGFX2DLog()
 {
   static mozilla::LazyLogModule sLog("gfx2d");
@@ -214,17 +211,17 @@ mozilla_UnlockFTLibrary(FT_Library aFTLi
 namespace mozilla {
 namespace gfx {
 
 // In Gecko, this value is managed by gfx.logging.level in gfxPrefs.
 int32_t LoggingPrefs::sGfxLogLevel = LOG_DEFAULT;
 
 #ifdef MOZ_ENABLE_FREETYPE
 FT_Library Factory::mFTLibrary = nullptr;
-Mutex* Factory::mFTLock = nullptr;
+StaticMutex Factory::mFTLock;
 #endif
 
 #ifdef WIN32
 // Note: mDeviceLock must be held when mutating these values.
 static uint32_t mDeviceSeq = 0;
 StaticRefPtr<ID3D11Device> Factory::mD3D11Device;
 StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
 StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
@@ -238,37 +235,29 @@ DrawEventRecorder *Factory::mRecorder;
 
 mozilla::gfx::Config* Factory::sConfig = nullptr;
 
 void
 Factory::Init(const Config& aConfig)
 {
   MOZ_ASSERT(!sConfig);
   sConfig = new Config(aConfig);
-
-#ifdef MOZ_ENABLE_FREETYPE
-  mFTLock = new Mutex("Factory::mFTLock");
-#endif
 }
 
 void
 Factory::ShutDown()
 {
   if (sConfig) {
     delete sConfig->mLogForwarder;
     delete sConfig;
     sConfig = nullptr;
   }
 
 #ifdef MOZ_ENABLE_FREETYPE
   mFTLibrary = nullptr;
-  if (mFTLock) {
-    delete mFTLock;
-    mFTLock = nullptr;
-  }
 #endif
 }
 
 bool
 Factory::HasSSE2()
 {
 #if defined(__SSE2__) || defined(_M_X64) || \
     (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
@@ -759,77 +748,64 @@ void
 Factory::ReleaseFTLibrary(FT_Library aFTLibrary)
 {
   FT_Done_FreeType(aFTLibrary);
 }
 
 void
 Factory::LockFTLibrary(FT_Library aFTLibrary)
 {
-  MOZ_ASSERT(mFTLock);
-  mFTLock->Lock();
+  mFTLock.Lock();
 }
 
 void
 Factory::UnlockFTLibrary(FT_Library aFTLibrary)
 {
-  MOZ_ASSERT(mFTLock);
-  mFTLock->Unlock();
+  mFTLock.Unlock();
 }
 
 FT_Face
 Factory::NewFTFace(FT_Library aFTLibrary, const char* aFileName, int aFaceIndex)
 {
-  MOZ_ASSERT(mFTLock);
-  MutexAutoLock lock(*mFTLock);
+  StaticMutexAutoLock lock(mFTLock);
   if (!aFTLibrary) {
     aFTLibrary = mFTLibrary;
   }
   FT_Face face;
   if (FT_New_Face(aFTLibrary, aFileName, aFaceIndex, &face) != FT_Err_Ok) {
     return nullptr;
   }
   return face;
 }
 
 FT_Face
 Factory::NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize, int aFaceIndex)
 {
-  MOZ_ASSERT(mFTLock);
-  MutexAutoLock lock(*mFTLock);
+  StaticMutexAutoLock lock(mFTLock);
   if (!aFTLibrary) {
     aFTLibrary = mFTLibrary;
   }
   FT_Face face;
   if (FT_New_Memory_Face(aFTLibrary, aData, aDataSize, aFaceIndex, &face) != FT_Err_Ok) {
     return nullptr;
   }
   return face;
 }
 
 void
 Factory::ReleaseFTFace(FT_Face aFace)
 {
-  // May be called during shutdown when the lock is already destroyed.
-  // However, there are no other threads using the face by this point,
-  // so it is safe to skip locking if the lock is not around.
-  if (mFTLock) {
-    mFTLock->Lock();
-  }
+  StaticMutexAutoLock lock(mFTLock);
   FT_Done_Face(aFace);
-  if (mFTLock) {
-    mFTLock->Unlock();
-  }
 }
 
 FT_Error
 Factory::LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags)
 {
-  MOZ_ASSERT(mFTLock);
-  MutexAutoLock lock(*mFTLock);
+  StaticMutexAutoLock lock(mFTLock);
   return FT_Load_Glyph(aFace, aGlyphIndex, aFlags);
 }
 #endif
 
 #ifdef WIN32
 already_AddRefed<DrawTarget>
 Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat)
 {
@@ -1023,17 +999,17 @@ Factory::CreateScaledFontForDWriteFont(I
                                        Float aContrast)
 {
   return MakeAndAddRef<ScaledFontDWrite>(aFontFace, aUnscaledFont, aSize,
                                          aUseEmbeddedBitmap, aForceGDIMode,
                                          aParams, aGamma, aContrast,
                                          aStyle);
 }
 
-#endif // XP_WIN
+#endif // WIN32
 
 #ifdef USE_SKIA_GPU
 already_AddRefed<DrawTarget>
 Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
                                            const IntSize &aSize,
                                            SurfaceFormat aFormat)
 {
   RefPtr<DrawTarget> newTarget = new DrawTargetSkia();
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -33,32 +33,36 @@
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/layers/LayerTreeOwnerTracker.h"
 #include "mozilla/layers/UiCompositorControllerParent.h"
 #include "mozilla/layers/MemoryReportingMLGPU.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "mozilla/HangDetails.h"
+#include "nscore.h"
 #include "nsDebugImpl.h"
 #include "nsIGfxInfo.h"
 #include "nsThreadManager.h"
 #include "prenv.h"
 #include "ProcessUtils.h"
 #include "VRGPUChild.h"
 #include "VRManager.h"
 #include "VRManagerParent.h"
 #include "VsyncBridgeParent.h"
+#include "cairo.h"
+#include "skia/include/core/SkGraphics.h"
 #if defined(XP_WIN)
 # include "mozilla/gfx/DeviceManagerDx.h"
 # include <process.h>
 # include <dwrite.h>
 #endif
 #ifdef MOZ_WIDGET_GTK
 # include <gtk/gtk.h>
+# include "skia/include/ports/SkTypeface_cairo.h"
 #endif
 #ifdef MOZ_GECKO_PROFILER
 #include "ChildProfilerController.h"
 #endif
 
 namespace mozilla {
 namespace gfx {
 
@@ -215,16 +219,20 @@ GPUParent::RecvInit(nsTArray<GfxPrefSett
       reporter.SetSuccessful();
     }
   }
 
   for (const LayerTreeIdMapping& map : aMappings) {
     LayerTreeOwnerTracker::Get()->Map(map.layersId(), map.ownerId());
   }
 
+  // We bypass gfxPlatform::Init, so we must initialize any relevant libraries
+  // here that would normally be initialized there.
+  SkGraphics::Init();
+
 #if defined(XP_WIN)
   if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     DeviceManagerDx::Get()->CreateCompositorDevices();
   }
   if (gfxVars::UseWebRender()) {
     DeviceManagerDx::Get()->CreateDirectCompositionDevice();
     // Ensure to initialize GfxInfo
     nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
@@ -255,16 +263,18 @@ GPUParent::RecvInit(nsTArray<GfxPrefSett
 
   // Ensure we have an FT library for font instantiation.
   // This would normally be set by gfxPlatform::Init().
   // Since we bypass that, we must do it here instead.
   if (gfxVars::UseWebRender()) {
     FT_Library library = Factory::NewFTLibrary();
     MOZ_ASSERT(library);
     Factory::SetFTLibrary(library);
+
+    SkInitCairoFT(true);
   }
 #endif
 
   // Make sure to do this *after* we update gfxVars above.
   if (gfxVars::UseWebRender()) {
     wr::RenderThread::Start();
     image::ImageMemoryReporter::InitForWebRender();
   }
@@ -547,16 +557,24 @@ GPUParent::ActorDestroy(ActorDestroyReas
   // context providers available, so we have to shut all of them down.
   // We should only support the default GL provider on Windows; then, this
   // could go away. Unfortunately, we currently support WGL (the default) for
   // WebGL on Optimus.
   gl::GLContextProviderEGL::Shutdown();
 #endif
 
   Factory::ShutDown();
+
+  // We bypass gfxPlatform shutdown, so we must shutdown any libraries here
+  // that would normally be handled by it.
+#ifdef NS_FREE_PERMANENT_DATA
+  SkGraphics::PurgeFontCache();
+  cairo_debug_reset_static_data();
+#endif
+
 #if defined(XP_WIN)
   DeviceManagerDx::Shutdown();
 #endif
   LayerTreeOwnerTracker::Shutdown();
   gfxVars::Shutdown();
   gfxConfig::Shutdown();
   gfxPrefs::DestroySingleton();
   CrashReporterClient::DestroySingleton();
--- a/gfx/ipc/moz.build
+++ b/gfx/ipc/moz.build
@@ -81,8 +81,10 @@ LOCAL_INCLUDES += [
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
 CXXFLAGS += CONFIG['TK_CFLAGS']
+
+LOCAL_INCLUDES += CONFIG['SKIA_INCLUDES']