From c0944ebe5b4b4cb74912492f64606b2aca5f3350 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 6 Jun 2014 09:51:24 -0400 Subject: [PATCH] Bug 774388 - Patch 4: Flatten the way that we track whether we are using OMTC, and move Layers IPC shutdown code back to gfxPlatform (but still triggered by ShutdownXPCOM) - r=nical,sotaro --- dom/ipc/ContentParent.cpp | 3 +- dom/ipc/TabParent.cpp | 6 +- gfx/thebes/gfxPlatform.cpp | 88 +++++++++++++++++----------- gfx/thebes/gfxPlatform.h | 22 ++++--- gfx/thebes/gfxPlatformGtk.cpp | 12 ---- gfx/thebes/gfxPlatformGtk.h | 1 - gfx/thebes/gfxPlatformMac.cpp | 6 -- gfx/thebes/gfxPlatformMac.h | 2 - gfx/thebes/gfxQtPlatform.cpp | 11 ---- gfx/thebes/gfxQtPlatform.h | 2 - gfx/thebes/gfxWindowsPlatform.cpp | 4 +- layout/build/nsLayoutModule.cpp | 1 - layout/ipc/RenderFrameParent.cpp | 2 +- widget/windows/winrt/MetroWidget.cpp | 6 +- widget/xpwidgets/nsBaseWidget.cpp | 5 +- xpcom/build/nsXPComInit.cpp | 13 ++-- 16 files changed, 87 insertions(+), 97 deletions(-) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 23a76e9fa5e7..6f15767a37ee 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1710,8 +1710,7 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority, // PBrowsers are created, because they rely on the Compositor // already being around. (Creation is async, so can't happen // on demand.) - bool useOffMainThreadCompositing = !!CompositorParent::CompositorLoop(); - if (useOffMainThreadCompositing) { + if (gfxPlatform::UsesOffMainThreadCompositing()) { DebugOnly opened = PCompositor::Open(this); MOZ_ASSERT(opened); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index b02ffa04d2c3..69e45fc2d32e 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1888,9 +1888,9 @@ TabParent::GetWidget() const bool TabParent::UseAsyncPanZoom() { - bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop(); - return (usingOffMainThreadCompositing && gfxPrefs::AsyncPanZoomEnabled() && - GetScrollingBehavior() == ASYNC_PAN_ZOOM); + return gfxPlatform::UsesOffMainThreadCompositing() && + gfxPrefs::AsyncPanZoomEnabled() && + GetScrollingBehavior() == ASYNC_PAN_ZOOM; } nsEventStatus diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index b84c80aedce0..87439dc90966 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -277,6 +277,9 @@ gfxPlatform::gfxPlatform() uint32_t contentMask = BackendTypeBit(BackendType::CAIRO); InitBackendPrefs(canvasMask, BackendType::CAIRO, contentMask, BackendType::CAIRO); + + mUsesOffMainThreadCompositing = ComputeUsesOffMainThreadCompositing(); + mAlreadyShutDownLayersIPC = false; } gfxPlatform* @@ -364,17 +367,12 @@ gfxPlatform::Init() mozilla::gl::GLContext::StaticInit(); #endif - bool useOffMainThreadCompositing = OffMainThreadCompositionRequired() || - GetPrefLayersOffMainThreadCompositionEnabled(); - - if (!OffMainThreadCompositionRequired()) { - useOffMainThreadCompositing &= GetPlatform()->SupportsOffMainThreadCompositing(); - } - - if (useOffMainThreadCompositing && (XRE_GetProcessType() == GeckoProcessType_Default)) { - CompositorParent::StartUp(); + if (UsesOffMainThreadCompositing() && + XRE_GetProcessType() == GeckoProcessType_Default) + { + mozilla::layers::CompositorParent::StartUp(); if (gfxPrefs::AsyncVideoEnabled()) { - ImageBridgeChild::StartUp(); + mozilla::layers::ImageBridgeChild::StartUp(); } #ifdef MOZ_WIDGET_GONK SharedBufferManagerChild::StartUp(); @@ -444,6 +442,9 @@ gfxPlatform::Init() void gfxPlatform::Shutdown() { + MOZ_ASSERT(gPlatform, "gfxPlatform already down!"); + MOZ_ASSERT(gPlatform->mAlreadyShutDownLayersIPC, "ShutdownLayersIPC should have been called before this point!"); + // These may be called before the corresponding subsystems have actually // started up. That's OK, they can handle it. gfxFontCache::Shutdown(); @@ -506,6 +507,25 @@ gfxPlatform::Shutdown() gPlatform = nullptr; } +/* static */ void +gfxPlatform::ShutdownLayersIPC() +{ + MOZ_ASSERT(!gPlatform->mAlreadyShutDownLayersIPC); + if (UsesOffMainThreadCompositing() && + XRE_GetProcessType() == GeckoProcessType_Default) + { + // This must happen after the shutdown of media and widgets, which + // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification. + layers::ImageBridgeChild::ShutDown(); +#ifdef MOZ_WIDGET_GONK + layers::SharedBufferManagerChild::ShutDown(); +#endif + + layers::CompositorParent::ShutDown(); + } + gPlatform->mAlreadyShutDownLayersIPC = true; +} + gfxPlatform::~gfxPlatform() { mScreenReferenceSurface = nullptr; @@ -532,7 +552,6 @@ gfxPlatform::~gfxPlatform() bool gfxPlatform::PreferMemoryOverShmem() const { - MOZ_ASSERT(!CompositorParent::IsInCompositorThread()); return mLayersPreferMemoryOverShmem; } @@ -1542,9 +1561,7 @@ gfxPlatform::GetBackendPref(const char* aBackendPrefName, uint32_t &aBackendBitm bool gfxPlatform::OffMainThreadCompositingEnabled() { - return XRE_GetProcessType() == GeckoProcessType_Default ? - CompositorParent::CompositorLoop() != nullptr : - CompositorChild::ChildProcessHasCompositor(); + return UsesOffMainThreadCompositing(); } eCMSMode @@ -2008,27 +2025,6 @@ InitLayersAccelerationPrefs() } } -bool -gfxPlatform::GetPrefLayersOffMainThreadCompositionEnabled() -{ - InitLayersAccelerationPrefs(); - return gfxPrefs::LayersOffMainThreadCompositionEnabled() || - gfxPrefs::LayersOffMainThreadCompositionForceEnabled() || - gfxPrefs::LayersOffMainThreadCompositionTestingEnabled(); -} - -bool gfxPlatform::OffMainThreadCompositionRequired() -{ - InitLayersAccelerationPrefs(); -#if defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD) - // Linux users who chose OpenGL are being grandfathered in to OMTC - return sPrefBrowserTabsRemoteAutostart || - gfxPrefs::LayersAccelerationForceEnabled(); -#else - return sPrefBrowserTabsRemoteAutostart; -#endif -} - bool gfxPlatform::CanUseDirect3D9() { @@ -2075,3 +2071,25 @@ gfxPlatform::GetScaledFontForFontWithCairoSkia(DrawTarget* aTarget, gfxFont* aFo return nullptr; } + +bool +gfxPlatform::ComputeUsesOffMainThreadCompositing() +{ + InitLayersAccelerationPrefs(); + bool result = + sPrefBrowserTabsRemoteAutostart || + gfxPrefs::LayersOffMainThreadCompositionEnabled() || + gfxPrefs::LayersOffMainThreadCompositionForceEnabled() || + gfxPrefs::LayersOffMainThreadCompositionTestingEnabled(); +#if defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD) + // Linux users who chose OpenGL are being grandfathered in to OMTC + result |= + gfxPrefs::LayersAccelerationForceEnabled() || + PR_GetEnv("MOZ_USE_OMTC") || + PR_GetEnv("MOZ_OMTC_ENABLED"); // yeah, these two env vars do the same thing. + // I'm told that one of them is enabled on some test slaves config. + // so be slightly careful if you think you can + // remove one of them. +#endif + return result; +} \ No newline at end of file diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 89bc0ab2ef7b..9c90bd1814bd 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -170,6 +170,8 @@ public: */ static void Shutdown(); + static void ShutdownLayersIPC(); + /** * Create an offscreen surface of the given dimensions * and image format. @@ -433,16 +435,9 @@ public: static bool OffMainThreadCompositingEnabled(); - /** Use gfxPlatform::GetPref* methods instead of direct calls to Preferences - * to get the values for layers preferences. These will only be evaluated - * only once, and remain the same until restart. - */ - static bool GetPrefLayersOffMainThreadCompositionEnabled(); static bool CanUseDirect3D9(); static bool CanUseDirect3D11(); - static bool OffMainThreadCompositionRequired(); - /** * Is it possible to use buffer rotation. Note that these * check the preference, but also allow for the override to @@ -549,6 +544,10 @@ public: virtual bool IsInGonkEmulator() const { return false; } + static bool UsesOffMainThreadCompositing() { + return GetPlatform()->mUsesOffMainThreadCompositing; + } + protected: gfxPlatform(); virtual ~gfxPlatform(); @@ -618,6 +617,13 @@ protected: // max number of entries in word cache int32_t mWordCacheMaxEntries; + // Whether we use OMTC/OMPC (as opposed to main-thread compositing) + bool mUsesOffMainThreadCompositing; + + // Whether ShutdownLayersIPC has alrady been called. Used to enforce that + // it is called before Shutdown. + bool mAlreadyShutDownLayersIPC; + private: /** * Start up Thebes. @@ -632,7 +638,7 @@ private: virtual void GetPlatformCMSOutputProfile(void *&mem, size_t &size); - virtual bool SupportsOffMainThreadCompositing() { return true; } + bool ComputeUsesOffMainThreadCompositing(); nsRefPtr mScreenReferenceSurface; mozilla::RefPtr mScreenReferenceDrawTarget; diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 7a51c40dbe0f..bea4a6bac579 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -252,18 +252,6 @@ gfxPlatformGtk::GetScreenDepth() const return sDepth; } -bool -gfxPlatformGtk::SupportsOffMainThreadCompositing() -{ - // Nightly builds have OMTC support by default for Electrolysis testing. -#if defined(MOZ_X11) && !defined(NIGHTLY_BUILD) - return (PR_GetEnv("MOZ_USE_OMTC") != nullptr) || - (PR_GetEnv("MOZ_OMTC_ENABLED") != nullptr); -#else - return true; -#endif -} - void gfxPlatformGtk::GetPlatformCMSOutputProfile(void *&mem, size_t &size) { diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h index 7c3b35a1f5af..a8996d7b1a8f 100644 --- a/gfx/thebes/gfxPlatformGtk.h +++ b/gfx/thebes/gfxPlatformGtk.h @@ -98,7 +98,6 @@ protected: private: virtual void GetPlatformCMSOutputProfile(void *&mem, size_t &size); - virtual bool SupportsOffMainThreadCompositing(); #ifdef MOZ_X11 static bool sUseXRender; #endif diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp index 5a2801470de6..e4365724e287 100644 --- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -435,12 +435,6 @@ gfxPlatformMac::UseAcceleratedCanvas() return nsCocoaFeatures::OnLionOrLater() && Preferences::GetBool("gfx.canvas.azure.accelerated", false); } -bool -gfxPlatformMac::SupportsOffMainThreadCompositing() -{ - return true; -} - void gfxPlatformMac::GetPlatformCMSOutputProfile(void* &mem, size_t &size) { diff --git a/gfx/thebes/gfxPlatformMac.h b/gfx/thebes/gfxPlatformMac.h index 9e7bb52d57b4..e818e587827f 100644 --- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -72,8 +72,6 @@ public: private: virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size); - virtual bool SupportsOffMainThreadCompositing(); - // read in the pref value for the lower threshold on font anti-aliasing static uint32_t ReadAntiAliasingThreshold(); diff --git a/gfx/thebes/gfxQtPlatform.cpp b/gfx/thebes/gfxQtPlatform.cpp index 559c3b6af210..e5da35f0bbf5 100644 --- a/gfx/thebes/gfxQtPlatform.cpp +++ b/gfx/thebes/gfxQtPlatform.cpp @@ -160,17 +160,6 @@ gfxQtPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, aFontData, aLength); } -bool -gfxQtPlatform::SupportsOffMainThreadCompositing() -{ -#if defined(MOZ_X11) && !defined(NIGHTLY_BUILD) - return (PR_GetEnv("MOZ_USE_OMTC") != nullptr) || - (PR_GetEnv("MOZ_OMTC_ENABLED") != nullptr); -#else - return true; -#endif -} - bool gfxQtPlatform::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) { diff --git a/gfx/thebes/gfxQtPlatform.h b/gfx/thebes/gfxQtPlatform.h index 3556515bea42..57fa3c711bb9 100644 --- a/gfx/thebes/gfxQtPlatform.h +++ b/gfx/thebes/gfxQtPlatform.h @@ -83,8 +83,6 @@ public: virtual int GetScreenDepth() const MOZ_OVERRIDE; - virtual bool SupportsOffMainThreadCompositing() MOZ_OVERRIDE; - protected: static gfxFontconfigUtils *sFontconfigUtils; diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 4e6b7bbf5ac3..7f1921335dd1 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -1380,8 +1380,8 @@ gfxWindowsPlatform::GetD3D9DeviceManager() // We should only create the d3d9 device on the compositor thread // or we don't have a compositor thread. if (!mDeviceManager && - (CompositorParent::IsInCompositorThread() || - !CompositorParent::CompositorLoop())) { + (!gfxPlatform::UsesOffMainThreadCompositing() || + CompositorParent::IsInCompositorThread())) { mDeviceManager = new DeviceManagerD3D9(); if (!mDeviceManager->Init()) { NS_WARNING("Could not initialise device manager"); diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index c790795aa93d..f63575a8320f 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -71,7 +71,6 @@ #include "nsDOMBlobBuilder.h" #include "nsDOMFileReader.h" -#include "gfxPlatform.h" #include "nsFormData.h" #include "nsHostObjectProtocolHandler.h" #include "nsHostObjectURI.h" diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index bdfc212b275a..f08ee4e8f883 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -737,7 +737,7 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, } } - if (CompositorParent::CompositorLoop()) { + if (gfxPlatform::UsesOffMainThreadCompositing()) { // Our remote frame will push layers updates to the compositor, // and we'll keep an indirect reference to that tree. *aId = mLayersId = CompositorParent::AllocateLayerTreeId(); diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index 94d5b9de7a8b..5b51580d5e33 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -998,7 +998,8 @@ MetroWidget::ShouldUseOffMainThreadCompositing() return false; } // toolkit or test widgets can't use omtc, they don't have ICoreWindow. - return (CompositorParent::CompositorLoop() && mWindowType == eWindowType_toplevel); + return gfxPlatform::UsesOffMainThreadCompositing() && + mWindowType == eWindowType_toplevel; } bool @@ -1008,7 +1009,8 @@ MetroWidget::ShouldUseMainThreadD3D10Manager() if (!mView) { return false; } - return (!CompositorParent::CompositorLoop() && mWindowType == eWindowType_toplevel); + return !gfxPlatform::UsesOffMainThreadCompositing() && + mWindowType == eWindowType_toplevel; } bool diff --git a/widget/xpwidgets/nsBaseWidget.cpp b/widget/xpwidgets/nsBaseWidget.cpp index 1061d5b4a79e..059033150fa6 100644 --- a/widget/xpwidgets/nsBaseWidget.cpp +++ b/widget/xpwidgets/nsBaseWidget.cpp @@ -888,6 +888,9 @@ CheckForBasicBackends(nsTArray& aHints) void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) { + MOZ_ASSERT(gfxPlatform::UsesOffMainThreadCompositing(), + "This function assumes OMTC"); + // Recreating this is tricky, as we may still have an old and we need // to make sure it's properly destroyed by calling DestroyCompositor! @@ -946,7 +949,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) bool nsBaseWidget::ShouldUseOffMainThreadCompositing() { - return CompositorParent::CompositorLoop(); + return gfxPlatform::UsesOffMainThreadCompositing(); } LayerManager* nsBaseWidget::GetLayerManager(PLayerTransactionChild* aShadowManager, diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index 065fd2fa9c5d..5e7f997e0ebe 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -149,6 +149,8 @@ extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **) #include "jsapi.h" +#include "gfxPlatform.h" + using namespace mozilla; using base::AtExitManager; using mozilla::ipc::BrowserProcessSubThread; @@ -797,13 +799,6 @@ ShutdownXPCOM(nsIServiceManager* servMgr) } } - // This must happen after the shutdown of media and widgets, which - // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification. - layers::ImageBridgeChild::ShutDown(); -#ifdef MOZ_WIDGET_GONK - layers::SharedBufferManagerChild::ShutDown(); -#endif - NS_ProcessPendingEvents(thread); mozilla::scache::StartupCache::DeleteSingleton(); if (observerService) @@ -811,7 +806,9 @@ ShutdownXPCOM(nsIServiceManager* servMgr) NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, nullptr); - layers::CompositorParent::ShutDown(); + // This must happen after the shutdown of media and widgets, which + // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification. + gfxPlatform::ShutdownLayersIPC(); gXPCOMThreadsShutDown = true; NS_ProcessPendingEvents(thread);