Bug 1330037 - Introduce a CompositorOptions struct that holds options on a per-compositor basis. r=dvander
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 12 Jan 2017 17:29:41 -0500
changeset 374194 3d27c7cbcafa48642e0368319c563c4e32895242
parent 374193 afe70927277c0e6c2f62917c4215624e5c8657ef
child 374195 0f5987e936748bdc2d0717c181b7545b13aaaa2f
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs1330037
milestone53.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 1330037 - Introduce a CompositorOptions struct that holds options on a per-compositor basis. r=dvander MozReview-Commit-ID: Kja7zpCDmp3
gfx/ipc/CompositorOptions.h
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/ipc/InProcessCompositorSession.cpp
gfx/ipc/InProcessCompositorSession.h
gfx/ipc/moz.build
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
widget/nsBaseWidget.cpp
new file mode 100644
--- /dev/null
+++ b/gfx/ipc/CompositorOptions.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=99: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _include_mozilla_gfx_ipc_CompositorOptions_h_
+#define _include_mozilla_gfx_ipc_CompositorOptions_h_
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * This class holds options that are "per compositor" - that is, these options
+ * affect a particular CompositorBridgeParent and all the content that it
+ * renders.
+ *
+ * This class is intended to be created by a platform widget (but NOT
+ * PuppetWidget) and passed to the graphics code during initialization of the
+ * top level compositor associated with that widget. The options are immutable
+ * after creation. The CompositorBridgeParent holds the canonical version of
+ * the options, but they may be accessed by other parts of the code as needed,
+ * and are accessible to content processes over PCompositorBridge as well.
+ */
+class CompositorOptions
+{
+public:
+  explicit CompositorOptions(bool aUseAPZ)
+    : mUseAPZ(aUseAPZ)
+  {
+  }
+
+  bool UseAPZ() const { return mUseAPZ; }
+
+private:
+  bool mUseAPZ;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // _include_mozilla_gfx_ipc_CompositorOptions_h_
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -7,16 +7,17 @@
 #include "GPUProcessHost.h"
 #include "GPUProcessListener.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZCTreeManagerChild.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
+#include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/layers/InProcessCompositorSession.h"
 #include "mozilla/layers/LayerTreeOwnerTracker.h"
 #include "mozilla/layers/RemoteCompositorSession.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
 # include "mozilla/widget/CompositorWidgetChild.h"
@@ -482,59 +483,59 @@ GPUProcessManager::DestroyProcess()
     mVsyncBridge = nullptr;
   }
 }
 
 RefPtr<CompositorSession>
 GPUProcessManager::CreateTopLevelCompositor(nsBaseWidget* aWidget,
                                             LayerManager* aLayerManager,
                                             CSSToLayoutDeviceScale aScale,
-                                            bool aUseAPZ,
+                                            const CompositorOptions& aOptions,
                                             bool aUseExternalSurfaceSize,
                                             const gfx::IntSize& aSurfaceSize)
 {
   uint64_t layerTreeId = AllocateLayerTreeId();
 
   EnsureGPUReady();
   EnsureImageBridgeChild();
   EnsureVRManager();
 
   if (mGPUChild) {
     RefPtr<CompositorSession> session = CreateRemoteSession(
       aWidget,
       aLayerManager,
       layerTreeId,
       aScale,
-      aUseAPZ,
+      aOptions,
       aUseExternalSurfaceSize,
       aSurfaceSize);
     if (session) {
       return session;
     }
 
     // We couldn't create a remote compositor, so abort the process.
     DisableGPUProcess("Failed to create remote compositor");
   }
 
   return InProcessCompositorSession::Create(
     aWidget,
     aLayerManager,
     layerTreeId,
     aScale,
-    aUseAPZ,
+    aOptions,
     aUseExternalSurfaceSize,
     aSurfaceSize);
 }
 
 RefPtr<CompositorSession>
 GPUProcessManager::CreateRemoteSession(nsBaseWidget* aWidget,
                                        LayerManager* aLayerManager,
                                        const uint64_t& aRootLayerTreeId,
                                        CSSToLayoutDeviceScale aScale,
-                                       bool aUseAPZ,
+                                       const CompositorOptions& aOptions,
                                        bool aUseExternalSurfaceSize,
                                        const gfx::IntSize& aSurfaceSize)
 {
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
   ipc::Endpoint<PCompositorBridgeParent> parentPipe;
   ipc::Endpoint<PCompositorBridgeChild> childPipe;
 
   nsresult rv = PCompositorBridge::CreateEndpoints(
@@ -580,17 +581,17 @@ GPUProcessManager::CreateRemoteSession(n
   if (!child->SendPCompositorWidgetConstructor(widget, initData)) {
     return nullptr;
   }
   if (!child->SendInitialize(aRootLayerTreeId)) {
     return nullptr;
   }
 
   RefPtr<APZCTreeManagerChild> apz = nullptr;
-  if (aUseAPZ) {
+  if (aOptions.UseAPZ()) {
     PAPZCTreeManagerChild* papz = child->SendPAPZCTreeManagerConstructor(0);
     if (!papz) {
       return nullptr;
     }
     apz = static_cast<APZCTreeManagerChild*>(papz);
   }
 
   RefPtr<RemoteCompositorSession> session =
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -19,16 +19,17 @@
 #include "nsIObserverService.h"
 #include "nsThreadUtils.h"
 class nsBaseWidget;
 
 
 namespace mozilla {
 namespace layers {
 class IAPZCTreeManager;
+class CompositorOptions;
 class CompositorSession;
 class CompositorUpdateObserver;
 class PCompositorBridgeChild;
 class PImageBridgeChild;
 class RemoteCompositorSession;
 } // namespace layers
 namespace widget {
 class CompositorWidget;
@@ -51,16 +52,17 @@ class VsyncIOThreadHolder;
 
 // The GPUProcessManager is a singleton responsible for creating GPU-bound
 // objects that may live in another process. Currently, it provides access
 // to the compositor via CompositorBridgeParent.
 class GPUProcessManager final : public GPUProcessHost::Listener
 {
   friend class layers::RemoteCompositorSession;
 
+  typedef layers::CompositorOptions CompositorOptions;
   typedef layers::CompositorSession CompositorSession;
   typedef layers::CompositorUpdateObserver CompositorUpdateObserver;
   typedef layers::IAPZCTreeManager IAPZCTreeManager;
   typedef layers::LayerManager LayerManager;
   typedef layers::PCompositorBridgeChild PCompositorBridgeChild;
   typedef layers::PImageBridgeChild PImageBridgeChild;
   typedef layers::RemoteCompositorSession RemoteCompositorSession;
 
@@ -78,17 +80,17 @@ public:
   // used, or one is launched and ready, this function returns immediately.
   // Otherwise it blocks until the GPU process has finished launching.
   void EnsureGPUReady();
 
   RefPtr<CompositorSession> CreateTopLevelCompositor(
     nsBaseWidget* aWidget,
     LayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
-    bool aUseAPZ,
+    const CompositorOptions& aOptions,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   bool CreateContentBridges(
     base::ProcessId aOtherProcess,
     ipc::Endpoint<PCompositorBridgeChild>* aOutCompositor,
     ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
     ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
@@ -192,17 +194,17 @@ private:
   void EnsureImageBridgeChild();
   void EnsureVRManager();
 
   RefPtr<CompositorSession> CreateRemoteSession(
     nsBaseWidget* aWidget,
     LayerManager* aLayerManager,
     const uint64_t& aRootLayerTreeId,
     CSSToLayoutDeviceScale aScale,
-    bool aUseAPZ,
+    const CompositorOptions& aOptions,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   DISALLOW_COPY_AND_ASSIGN(GPUProcessManager);
 
   class Observer final : public nsIObserver {
   public:
     NS_DECL_ISUPPORTS
--- a/gfx/ipc/InProcessCompositorSession.cpp
+++ b/gfx/ipc/InProcessCompositorSession.cpp
@@ -22,27 +22,27 @@ InProcessCompositorSession::InProcessCom
 {
 }
 
 /* static */ RefPtr<InProcessCompositorSession>
 InProcessCompositorSession::Create(nsIWidget* aWidget,
                                    LayerManager* aLayerManager,
                                    const uint64_t& aRootLayerTreeId,
                                    CSSToLayoutDeviceScale aScale,
-                                   bool aUseAPZ,
+                                   const CompositorOptions& aOptions,
                                    bool aUseExternalSurfaceSize,
                                    const gfx::IntSize& aSurfaceSize)
 {
   CompositorWidgetInitData initData;
   aWidget->GetCompositorWidgetInitData(&initData);
 
   RefPtr<CompositorWidget> widget = CompositorWidget::CreateLocal(initData, aWidget);
   RefPtr<CompositorBridgeChild> child = new CompositorBridgeChild(aLayerManager);
   RefPtr<CompositorBridgeParent> parent =
-    child->InitSameProcess(widget, aRootLayerTreeId, aScale, aUseAPZ, aUseExternalSurfaceSize, aSurfaceSize);
+    child->InitSameProcess(widget, aRootLayerTreeId, aScale, aOptions, aUseExternalSurfaceSize, aSurfaceSize);
 
   return new InProcessCompositorSession(widget, child, parent);
 }
 
 CompositorBridgeParent*
 InProcessCompositorSession::GetInProcessBridge() const
 {
   return mCompositorBridgeParent;
--- a/gfx/ipc/InProcessCompositorSession.h
+++ b/gfx/ipc/InProcessCompositorSession.h
@@ -8,27 +8,29 @@
 
 #include "CompositorSession.h"
 #include "mozilla/gfx/Point.h"
 #include "Units.h"
 
 namespace mozilla {
 namespace layers {
 
+class CompositorOptions;
+
 // A CompositorSession where both the child and parent CompositorBridge reside
 // in the same process.
 class InProcessCompositorSession final : public CompositorSession
 {
 public:
   static RefPtr<InProcessCompositorSession> Create(
     nsIWidget* aWidget,
     LayerManager* aLayerManager,
     const uint64_t& aRootLayerTreeId,
     CSSToLayoutDeviceScale aScale,
-    bool aUseAPZ,
+    const CompositorOptions& aOptions,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   CompositorBridgeParent* GetInProcessBridge() const override;
   void SetContentController(GeckoContentController* aController) override;
   RefPtr<IAPZCTreeManager> GetAPZCTreeManager() const override;
   bool Reset(const nsTArray<LayersBackend>& aBackendHints,
              uint64_t aSeqNo,
--- a/gfx/ipc/moz.build
+++ b/gfx/ipc/moz.build
@@ -18,16 +18,17 @@ EXPORTS.mozilla.gfx += [
     'GPUProcessManager.h',
     'SharedDIB.h',
     'VsyncBridgeChild.h',
     'VsyncBridgeParent.h',
     'VsyncIOThreadHolder.h',
 ]
 
 EXPORTS.mozilla.layers += [
+    'CompositorOptions.h',
     'CompositorSession.h',
     'InProcessCompositorSession.h',
     'RemoteCompositorSession.h',
 ]
 
 EXPORTS.mozilla.widget += [
     'CompositorWidgetVsyncObserver.h',
 ]
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -229,33 +229,33 @@ CompositorBridgeChild::ReinitForContent(
 
   return InitForContent(Move(aEndpoint));
 }
 
 CompositorBridgeParent*
 CompositorBridgeChild::InitSameProcess(widget::CompositorWidget* aWidget,
                                        const uint64_t& aLayerTreeId,
                                        CSSToLayoutDeviceScale aScale,
-                                       bool aUseAPZ,
+                                       const CompositorOptions& aOptions,
                                        bool aUseExternalSurface,
                                        const gfx::IntSize& aSurfaceSize)
 {
   TimeDuration vsyncRate =
     gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
 
   mCompositorBridgeParent =
     new CompositorBridgeParent(aScale, vsyncRate, aUseExternalSurface, aSurfaceSize);
 
   bool ok = Open(mCompositorBridgeParent->GetIPCChannel(),
                  CompositorThreadHolder::Loop(),
                  ipc::ChildSide);
   MOZ_RELEASE_ASSERT(ok);
 
   InitIPDL();
-  mCompositorBridgeParent->InitSameProcess(aWidget, aLayerTreeId, aUseAPZ);
+  mCompositorBridgeParent->InitSameProcess(aWidget, aLayerTreeId, aOptions);
   return mCompositorBridgeParent;
 }
 
 /* static */ RefPtr<CompositorBridgeChild>
 CompositorBridgeChild::CreateRemote(const uint64_t& aProcessToken,
                                     LayerManager* aLayerManager,
                                     Endpoint<PCompositorBridgeChild>&& aEndpoint)
 {
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -33,16 +33,17 @@ class CompositorWidget;
 namespace layers {
 
 using mozilla::dom::TabChild;
 
 class IAPZCTreeManager;
 class APZCTreeManagerChild;
 class ClientLayerManager;
 class CompositorBridgeParent;
+class CompositorOptions;
 class TextureClient;
 class TextureClientPool;
 struct FrameMetrics;
 
 class CompositorBridgeChild final : public PCompositorBridgeChild,
                                     public TextureForwarder
 {
   typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
@@ -75,17 +76,17 @@ public:
   /**
    * Initialize the CompositorBridgeChild, create CompositorBridgeParent, and
    * open a same-process connection.
    */
   CompositorBridgeParent* InitSameProcess(
     widget::CompositorWidget* aWidget,
     const uint64_t& aLayerTreeId,
     CSSToLayoutDeviceScale aScale,
-    bool aUseAPZ,
+    const CompositorOptions& aOptions,
     bool aUseExternalSurface,
     const gfx::IntSize& aSurfaceSize);
 
   static CompositorBridgeChild* Get();
 
   static bool ChildProcessHasCompositorBridge();
 
   // Returns whether the compositor is in the GPU process (false if in the UI
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -34,16 +34,17 @@
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/layers/APZCTreeManager.h"  // for APZCTreeManager
 #include "mozilla/layers/APZCTreeManagerParent.h"  // for APZCTreeManagerParent
 #include "mozilla/layers/APZThreadUtils.h"  // for APZCTreeManager
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include "mozilla/layers/BasicCompositor.h"  // for BasicCompositor
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/CompositorOGL.h"  // for CompositorOGL
+#include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/CompositorVsyncScheduler.h"
 #include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
 #include "mozilla/layers/FrameUniformityData.h"
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayerTreeOwnerTracker.h"
@@ -316,21 +317,21 @@ CompositorBridgeParent::CompositorBridge
 {
   // Always run destructor on the main thread
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 void
 CompositorBridgeParent::InitSameProcess(widget::CompositorWidget* aWidget,
                                         const uint64_t& aLayerTreeId,
-                                        bool aUseAPZ)
+                                        const CompositorOptions& aOptions)
 {
   mWidget = aWidget;
   mRootLayerTreeID = aLayerTreeId;
-  if (aUseAPZ) {
+  if (aOptions.UseAPZ()) {
     mApzcTreeManager = new APZCTreeManager();
   }
 
   // IPDL initialization. mSelfRef is cleared in DeferredDestroy.
   SetOtherProcessId(base::GetCurrentProcId());
   mSelfRef = this;
 
   Initialize();
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -58,16 +58,17 @@ class Shmem;
 
 namespace layers {
 
 class APZCTreeManager;
 class APZCTreeManagerParent;
 class AsyncCompositionManager;
 class Compositor;
 class CompositorBridgeParent;
+class CompositorOptions;
 class CompositorVsyncScheduler;
 class HostLayerManager;
 class LayerTransactionParent;
 class PAPZParent;
 class CrossProcessCompositorBridgeParent;
 class CompositorThreadHolder;
 class InProcessCompositorSession;
 
@@ -158,17 +159,17 @@ public:
                                   bool aUseExternalSurfaceSize,
                                   const gfx::IntSize& aSurfaceSize);
 
   // Must only be called by CompositorBridgeChild. After invoking this, the
   // IPC channel is active and RecvWillStop/ActorDestroy must be called to
   // free the compositor.
   void InitSameProcess(widget::CompositorWidget* aWidget,
                        const uint64_t& aLayerTreeId,
-                       bool aUseAPZ);
+                       const CompositorOptions& aOptions);
 
   // Must only be called by GPUParent. After invoking this, the IPC channel
   // is active and RecvWillStop/ActorDestroy must be called to free the
   // compositor.
   bool Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint);
 
   virtual mozilla::ipc::IPCResult RecvInitialize(const uint64_t& aRootLayerTreeId) override;
   virtual mozilla::ipc::IPCResult RecvReset(nsTArray<LayersBackend>&& aBackendHints,
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -50,16 +50,17 @@
 #include "GLConsts.h"
 #include "mozilla/Unused.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/VsyncDispatcher.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/ChromeProcessController.h"
+#include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/Move.h"
 #include "mozilla/Services.h"
 #include "mozilla/Sprintf.h"
@@ -1292,30 +1293,30 @@ void nsBaseWidget::CreateCompositor(int 
   if (!mShutdownObserver) {
     return;
   }
 
   CreateCompositorVsyncDispatcher();
 
   RefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
 
-  bool useAPZ = UseAPZ();
+  CompositorOptions options(UseAPZ());
 
   gfx::GPUProcessManager* gpu = gfx::GPUProcessManager::Get();
   mCompositorSession = gpu->CreateTopLevelCompositor(
     this,
     lm,
     GetDefaultScale(),
-    useAPZ,
+    options,
     UseExternalCompositingSurface(),
     gfx::IntSize(aWidth, aHeight));
   mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
   mCompositorWidgetDelegate = mCompositorSession->GetCompositorWidgetDelegate();
 
-  if (useAPZ) {
+  if (options.UseAPZ()) {
     mAPZC = mCompositorSession->GetAPZCTreeManager();
     ConfigureAPZCTreeManager();
   } else {
     mAPZC = nullptr;
   }
 
   if (mInitialZoomConstraints) {
     UpdateZoomConstraints(mInitialZoomConstraints->mPresShellID,