Implement remote CompositorWidgets on Windows. (
bug 1281998 part 7, r=billm)
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -24,16 +24,20 @@
#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop, etc
#include "FrameLayerBuilder.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/unused.h"
#include "mozilla/DebugOnly.h"
#if defined(XP_WIN)
#include "WinUtils.h"
#endif
+#include "mozilla/widget/CompositorWidget.h"
+#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
+# include "mozilla/widget/CompositorWidgetChild.h"
+#endif
using mozilla::layers::LayerTransactionChild;
using mozilla::dom::TabChildBase;
using mozilla::Unused;
namespace mozilla {
namespace layers {
@@ -948,11 +952,36 @@ CompositorBridgeChild::AllocShmem(size_t
}
void
CompositorBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
{
PCompositorBridgeChild::DeallocShmem(aShmem);
}
+widget::PCompositorWidgetChild*
+CompositorBridgeChild::AllocPCompositorWidgetChild(const CompositorWidgetInitData& aInitData)
+{
+ // We send the constructor manually.
+ MOZ_CRASH("Should not be called");
+ return nullptr;
+}
+
+bool
+CompositorBridgeChild::DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor)
+{
+#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
+ delete aActor;
+ return true;
+#else
+ return false;
+#endif
+}
+
+void
+CompositorBridgeChild::ProcessingError(Result aCode, const char* aReason)
+{
+ MOZ_CRASH("Processing error in CompositorBridgeChild");
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -188,18 +188,23 @@ public:
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
virtual bool AllocShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
+ PCompositorWidgetChild* AllocPCompositorWidgetChild(const CompositorWidgetInitData& aInitData) override;
+ bool DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor) override;
+
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
+ void ProcessingError(Result aCode, const char* aReason) override;
+
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeChild();
virtual PLayerTransactionChild*
AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -71,16 +71,20 @@
#include "mozilla/unused.h"
#include "mozilla/Hal.h"
#include "mozilla/HalTypes.h"
#include "mozilla/StaticPtr.h"
#ifdef MOZ_ENABLE_PROFILER_SPS
#include "ProfilerMarkers.h"
#endif
#include "mozilla/VsyncDispatcher.h"
+#include "mozilla/widget/CompositorWidget.h"
+#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
+# include "mozilla/widget/CompositorWidgetParent.h"
+#endif
#ifdef MOZ_WIDGET_GONK
#include "GeckoTouchDispatcher.h"
#include "nsScreenManagerGonk.h"
#endif
#ifdef MOZ_ANDROID_APZ
#include "AndroidBridge.h"
@@ -1798,16 +1802,48 @@ CompositorBridgeParent::RequestNotifyLay
/* static */ void
CompositorBridgeParent::RequestNotifyLayerTreeCleared(uint64_t aLayersId, CompositorUpdateObserver* aObserver)
{
EnsureLayerTreeMapReady();
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aLayersId].mLayerTreeClearedObserver = aObserver;
}
+widget::PCompositorWidgetParent*
+CompositorBridgeParent::AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData)
+{
+#if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
+ if (mWidget) {
+ // Should not create two widgets on the same compositor.
+ return nullptr;
+ }
+
+ widget::CompositorWidgetParent* widget =
+ new widget::CompositorWidgetParent(aInitData);
+ widget->AddRef();
+
+ // Sending the constructor acts as initialization as well.
+ mWidget = widget;
+ return widget;
+#else
+ return nullptr;
+#endif
+}
+
+bool
+CompositorBridgeParent::DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor)
+{
+#if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
+ static_cast<widget::CompositorWidgetParent*>(aActor)->Release();
+ return true;
+#else
+ return false;
+#endif
+}
+
/**
* This class handles layer updates pushed directly from child processes to
* the compositor thread. It's associated with a CompositorBridgeParent on the
* compositor thread. While it uses the PCompositorBridge protocol to manage
* these updates, it doesn't actually drive compositing itself. For that it
* hands off work to the CompositorBridgeParent it's associated with.
*/
class CrossProcessCompositorBridgeParent final : public PCompositorBridgeParent,
@@ -1977,16 +2013,25 @@ public:
return OtherPid();
}
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override
{
Unused << SendParentAsyncMessages(aMessage);
}
+ PCompositorWidgetParent* AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData) override {
+ // Not allowed.
+ return nullptr;
+ }
+ bool DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor) override {
+ // Not allowed.
+ return false;
+ }
+
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; }
protected:
void OnChannelConnected(int32_t pid) override {
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
}
private:
// Private destructor, to discourage deletion outside of Release():
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -300,16 +300,19 @@ public:
mozilla::ipc::Shmem* aShmem) override;
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aType,
mozilla::ipc::Shmem* aShmem) override;
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
+ PCompositorWidgetParent* AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData) override;
+ bool DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor) override;
+
virtual base::ProcessId GetChildProcessId() override
{
return OtherPid();
}
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; }
--- a/gfx/layers/ipc/PCompositorBridge.ipdl
+++ b/gfx/layers/ipc/PCompositorBridge.ipdl
@@ -2,18 +2,20 @@
* vim: sw=2 ts=8 et :
*/
/* 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/. */
include LayersSurfaces;
include LayersMessages;
+include PlatformWidgetTypes;
include protocol PBrowser;
include protocol PCompositable;
+include protocol PCompositorWidget;
include protocol PImageContainer;
include protocol PLayer;
include protocol PLayerTransaction;
include protocol PTexture;
include "mozilla/GfxMessageUtils.h";
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
@@ -42,16 +44,17 @@ namespace layers {
* the main thread and the compositor thread context. It's primary
* purpose is to manage the PLayerTransaction sub protocol.
*/
sync protocol PCompositorBridge
{
// A Compositor manages a single Layer Manager (PLayerTransaction)
manages PLayerTransaction;
manages PTexture;
+ manages PCompositorWidget;
child:
// The child should invalidate retained layers. This is used for local
// compositor device resets, such as in CompositorD3D9, and ensures that
// TextureSources are recreated.
async InvalidateLayers(uint64_t layersId);
// The compositor type or device has changed, and a new texture factory
@@ -98,16 +101,18 @@ child:
* Drop any buffers that might be retained on the child compositor
* side.
*/
async ClearCachedResources(uint64_t id);
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
parent:
+ async PCompositorWidget(CompositorWidgetInitData aInitData);
+
/**
* Confirmation callback for UpdatePluginConfigurations and HideAllPlugins.
*/
async RemotePluginsReady();
// Confirmation that the child has invalidated all its layers, and will not
// request layers against an old compositor.
async AcknowledgeCompositorUpdate(uint64_t id);
--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -33,16 +33,29 @@ class CompositorWidgetInitData;
// Gecko widgets usually need to communicate with the CompositorWidget with
// platform-specific messages (for example to update the window size or
// transparency). This functionality is controlled through a "host". Since
// this functionality is platform-dependent, it is only forward declared
// here.
class CompositorWidgetDelegate;
+// Platforms that support out-of-process widgets.
+#if defined(XP_WIN)
+// CompositorWidgetParent should implement CompositorWidget and
+// PCompositorWidgetParent.
+class CompositorWidgetParent;
+
+// CompositorWidgetChild should implement CompositorWidgetDelegate and
+// PCompositorWidgetChild.
+class CompositorWidgetChild;
+
+# define MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
+#endif
+
/**
* Access to a widget from the compositor is restricted to these methods.
*/
class CompositorWidget
{
public:
NS_INLINE_DECL_REFCOUNTING(mozilla::widget::CompositorWidget)
--- a/widget/InProcessCompositorWidget.cpp
+++ b/widget/InProcessCompositorWidget.cpp
@@ -5,17 +5,17 @@
#include "InProcessCompositorWidget.h"
#include "nsBaseWidget.h"
namespace mozilla {
namespace widget {
// Platforms with no OOP compositor process support use
// InProcessCompositorWidget by default.
-#if !defined(XP_WIN)
+#if !defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
/* static */ RefPtr<CompositorWidget>
CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData, nsIWidget* aWidget)
{
MOZ_ASSERT(aWidget);
return new InProcessCompositorWidget(static_cast<nsBaseWidget*>(aWidget));
}
#endif
new file mode 100644
--- /dev/null
+++ b/widget/PCompositorWidget.ipdl
@@ -0,0 +1,24 @@
+/* -*- 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/. */
+
+include protocol PCompositorBridge;
+
+// This file is a stub, for platforms that do not yet support out-of-process
+// compositing or do not need specialized types to do so.
+
+namespace mozilla {
+namespace widget {
+
+sync protocol PCompositorWidget
+{
+ manager PCompositorBridge;
+
+parent:
+ async __delete__();
+};
+
+} // namespace widget
+} // namespace mozilla
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -239,20 +239,22 @@ LOCAL_INCLUDES += [
'/layout/generic',
'/layout/xul',
'/view',
'/widget',
]
if toolkit == 'windows':
IPDL_SOURCES = [
+ 'windows/PCompositorWidget.ipdl',
'windows/PlatformWidgetTypes.ipdlh',
]
else:
IPDL_SOURCES = [
+ 'PCompositorWidget.ipdl',
'PlatformWidgetTypes.ipdlh',
]
widget_dir = toolkit
if widget_dir in ('gtk3', 'gtk2'):
# gtk3 shares includes with gtk2
widget_dir = 'gtk'
new file mode 100644
--- /dev/null
+++ b/widget/windows/CompositorWidgetChild.cpp
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "CompositorWidgetChild.h"
+#include "mozilla/unused.h"
+
+namespace mozilla {
+namespace widget {
+
+CompositorWidgetChild::CompositorWidgetChild(nsIWidget* aWidget)
+{
+}
+
+CompositorWidgetChild::~CompositorWidgetChild()
+{
+}
+
+void
+CompositorWidgetChild::EnterPresentLock()
+{
+ Unused << SendEnterPresentLock();
+}
+
+void
+CompositorWidgetChild::LeavePresentLock()
+{
+ Unused << SendLeavePresentLock();
+}
+
+void
+CompositorWidgetChild::OnDestroyWindow()
+{
+}
+
+void
+CompositorWidgetChild::UpdateTransparency(nsTransparencyMode aMode)
+{
+ Unused << SendUpdateTransparency(static_cast<int32_t>(aMode));
+}
+
+void
+CompositorWidgetChild::ClearTransparentWindow()
+{
+ Unused << SendClearTransparentWindow();
+}
+
+void
+CompositorWidgetChild::ResizeTransparentWindow(const gfx::IntSize& aSize)
+{
+ Unused << SendResizeTransparentWindow(aSize);
+}
+
+HDC CompositorWidgetChild::GetTransparentDC() const
+{
+ // Not supported in out-of-process mode.
+ return nullptr;
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/windows/CompositorWidgetChild.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 widget_windows_CompositorWidgetChild_h
+#define widget_windows_CompositorWidgetChild_h
+
+#include "WinCompositorWidget.h"
+#include "mozilla/widget/PCompositorWidgetChild.h"
+
+namespace mozilla {
+namespace widget {
+
+class CompositorWidgetChild final
+ : public PCompositorWidgetChild,
+ public CompositorWidgetDelegate
+{
+public:
+ CompositorWidgetChild(nsIWidget* aWidget);
+ ~CompositorWidgetChild() override;
+
+ void EnterPresentLock() override;
+ void LeavePresentLock() override;
+ void OnDestroyWindow() override;
+ void UpdateTransparency(nsTransparencyMode aMode) override;
+ void ClearTransparentWindow() override;
+ void ResizeTransparentWindow(const gfx::IntSize& aSize) override;
+ HDC GetTransparentDC() const override;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // widget_windows_CompositorWidgetChild_h
new file mode 100644
--- /dev/null
+++ b/widget/windows/CompositorWidgetParent.cpp
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "CompositorWidgetParent.h"
+
+namespace mozilla {
+namespace widget {
+
+CompositorWidgetParent::CompositorWidgetParent(const CompositorWidgetInitData& aInitData)
+ : WinCompositorWidget(aInitData)
+{
+}
+
+CompositorWidgetParent::~CompositorWidgetParent()
+{
+}
+
+bool
+CompositorWidgetParent::RecvEnterPresentLock()
+{
+ EnterPresentLock();
+ return true;
+}
+
+bool
+CompositorWidgetParent::RecvLeavePresentLock()
+{
+ LeavePresentLock();
+ return true;
+}
+
+bool
+CompositorWidgetParent::RecvUpdateTransparency(const int32_t& aMode)
+{
+ UpdateTransparency(static_cast<nsTransparencyMode>(aMode));
+ return true;
+}
+
+bool
+CompositorWidgetParent::RecvClearTransparentWindow()
+{
+ ClearTransparentWindow();
+ return true;
+}
+
+bool
+CompositorWidgetParent::RecvResizeTransparentWindow(const IntSize& aSize)
+{
+ ResizeTransparentWindow(aSize);
+ return true;
+}
+
+void
+CompositorWidgetParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/windows/CompositorWidgetParent.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 _widget_windows_WinCompositorWidget_h__
+#define _widget_windows_WinCompositorWidget_h__
+
+#include "WinCompositorWidget.h"
+#include "mozilla/widget/PCompositorWidgetParent.h"
+
+namespace mozilla {
+namespace widget {
+
+class CompositorWidgetParent final
+ : public PCompositorWidgetParent,
+ public WinCompositorWidget
+{
+public:
+ CompositorWidgetParent(const CompositorWidgetInitData& aInitData);
+ ~CompositorWidgetParent() override;
+
+ bool RecvEnterPresentLock() override;
+ bool RecvLeavePresentLock() override;
+ bool RecvUpdateTransparency(const int32_t& aMode) override;
+ bool RecvClearTransparentWindow() override;
+ bool RecvResizeTransparentWindow(const IntSize& aSize) override;
+ void ActorDestroy(ActorDestroyReason aWhy) override;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // _widget_windows_WinCompositorWidget_h__
new file mode 100644
--- /dev/null
+++ b/widget/windows/PCompositorWidget.ipdl
@@ -0,0 +1,28 @@
+/* -*- 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/. */
+
+include protocol PCompositorBridge;
+
+using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
+
+namespace mozilla {
+namespace widget {
+
+sync protocol PCompositorWidget
+{
+ manager PCompositorBridge;
+
+parent:
+ sync EnterPresentLock();
+ sync LeavePresentLock();
+ async UpdateTransparency(int32_t aMode);
+ sync ClearTransparentWindow();
+ sync ResizeTransparentWindow(IntSize aSize);
+ async __delete__();
+};
+
+} // namespace widget
+} // namespace mozilla
--- a/widget/windows/WinCompositorWidget.h
+++ b/widget/windows/WinCompositorWidget.h
@@ -1,19 +1,21 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 _widget_windows_WinCompositorWidget_h__
-#define _widget_windows_WinCompositorWidget_h__
+#ifndef widget_windows_CompositorWidgetParent_h
+#define widget_windows_CompositorWidgetParent_h
#include "CompositorWidget.h"
+#include "gfxASurface.h"
#include "mozilla/gfx/CriticalSection.h"
#include "mozilla/gfx/Point.h"
+#include "nsIWidget.h"
class nsWindow;
namespace mozilla {
namespace widget {
class CompositorWidgetDelegate
{
@@ -106,9 +108,9 @@ private:
// Locked back buffer of BasicCompositor
uint8_t* mLockedBackBufferData;
};
} // namespace widget
} // namespace mozilla
-#endif // _widget_windows_WinCompositorWidget_h__
+#endif // widget_windows_CompositorWidgetParent_h
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -9,24 +9,28 @@ TEST_DIRS += ['tests']
EXPORTS += [
'nsdefs.h',
'WindowHook.h',
'WinUtils.h',
]
EXPORTS.mozilla.widget += [
'AudioSession.h',
+ 'CompositorWidgetChild.h',
+ 'CompositorWidgetParent.h',
'WinCompositorWidget.h',
'WinMessages.h',
'WinModifierKeyState.h',
'WinNativeEventData.h',
]
UNIFIED_SOURCES += [
'AudioSession.cpp',
+ 'CompositorWidgetChild.cpp',
+ 'CompositorWidgetParent.cpp',
'GfxInfo.cpp',
'IEnumFE.cpp',
'IMMHandler.cpp',
'InkCollector.cpp',
'JumpListItem.cpp',
'KeyboardLayout.cpp',
'nsAppShell.cpp',
'nsClipboard.cpp',