diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index 6014a674ded3..7a70c1562710 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -29,6 +29,10 @@ #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; @@ -953,6 +957,31 @@ 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 diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index 863c01bf30f3..78ac98821a05 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -193,8 +193,13 @@ public: 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(); diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 3cc43e855de0..c022bc68eede 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -76,6 +76,10 @@ #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" @@ -1803,6 +1807,38 @@ CompositorBridgeParent::RequestNotifyLayerTreeCleared(uint64_t aLayersId, Compos 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(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 @@ -1982,6 +2018,15 @@ public: 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: diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h index c2a92491d220..53b810f44cf2 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.h +++ b/gfx/layers/ipc/CompositorBridgeParent.h @@ -305,6 +305,9 @@ public: 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(); diff --git a/gfx/layers/ipc/PCompositorBridge.ipdl b/gfx/layers/ipc/PCompositorBridge.ipdl index 113fe283c57b..51676691e61b 100644 --- a/gfx/layers/ipc/PCompositorBridge.ipdl +++ b/gfx/layers/ipc/PCompositorBridge.ipdl @@ -7,8 +7,10 @@ include LayersSurfaces; include LayersMessages; +include PlatformWidgetTypes; include protocol PBrowser; include protocol PCompositable; +include protocol PCompositorWidget; include protocol PImageContainer; include protocol PLayer; include protocol PLayerTransaction; @@ -47,6 +49,7 @@ 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 @@ -103,6 +106,8 @@ child: async ParentAsyncMessages(AsyncParentMessageData[] aMessages); parent: + async PCompositorWidget(CompositorWidgetInitData aInitData); + /** * Confirmation callback for UpdatePluginConfigurations and HideAllPlugins. */ diff --git a/widget/CompositorWidget.h b/widget/CompositorWidget.h index b4c7115958f0..64e78e7ffc0d 100644 --- a/widget/CompositorWidget.h +++ b/widget/CompositorWidget.h @@ -38,6 +38,19 @@ class CompositorWidgetInitData; // 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. */ diff --git a/widget/InProcessCompositorWidget.cpp b/widget/InProcessCompositorWidget.cpp index 50e443c8d347..9411fd3fa7f9 100644 --- a/widget/InProcessCompositorWidget.cpp +++ b/widget/InProcessCompositorWidget.cpp @@ -10,7 +10,7 @@ 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::CreateLocal(const CompositorWidgetInitData& aInitData, nsIWidget* aWidget) { diff --git a/widget/PCompositorWidget.ipdl b/widget/PCompositorWidget.ipdl new file mode 100644 index 000000000000..2789f6d25b42 --- /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 diff --git a/widget/moz.build b/widget/moz.build index 9939dda2f337..570606eb74dc 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -244,10 +244,12 @@ LOCAL_INCLUDES += [ if toolkit == 'windows': IPDL_SOURCES = [ + 'windows/PCompositorWidget.ipdl', 'windows/PlatformWidgetTypes.ipdlh', ] else: IPDL_SOURCES = [ + 'PCompositorWidget.ipdl', 'PlatformWidgetTypes.ipdlh', ] diff --git a/widget/windows/CompositorWidgetChild.cpp b/widget/windows/CompositorWidgetChild.cpp new file mode 100644 index 000000000000..2af2eadfa21f --- /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(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 diff --git a/widget/windows/CompositorWidgetChild.h b/widget/windows/CompositorWidgetChild.h new file mode 100644 index 000000000000..6dd954c3c39f --- /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 diff --git a/widget/windows/CompositorWidgetParent.cpp b/widget/windows/CompositorWidgetParent.cpp new file mode 100644 index 000000000000..c5ddb6513e4e --- /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(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 diff --git a/widget/windows/CompositorWidgetParent.h b/widget/windows/CompositorWidgetParent.h new file mode 100644 index 000000000000..35e67c533e4c --- /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__ diff --git a/widget/windows/PCompositorWidget.ipdl b/widget/windows/PCompositorWidget.ipdl new file mode 100644 index 000000000000..7da1b5e9b14f --- /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 diff --git a/widget/windows/WinCompositorWidget.h b/widget/windows/WinCompositorWidget.h index 1ee3e5c1c9c9..22f1f041549c 100644 --- a/widget/windows/WinCompositorWidget.h +++ b/widget/windows/WinCompositorWidget.h @@ -3,12 +3,14 @@ * 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; @@ -111,4 +113,4 @@ private: } // namespace widget } // namespace mozilla -#endif // _widget_windows_WinCompositorWidget_h__ +#endif // widget_windows_CompositorWidgetParent_h diff --git a/widget/windows/moz.build b/widget/windows/moz.build index 95767194462c..d967b758e3ca 100644 --- a/widget/windows/moz.build +++ b/widget/windows/moz.build @@ -14,6 +14,8 @@ EXPORTS += [ EXPORTS.mozilla.widget += [ 'AudioSession.h', + 'CompositorWidgetChild.h', + 'CompositorWidgetParent.h', 'WinCompositorWidget.h', 'WinMessages.h', 'WinModifierKeyState.h', @@ -22,6 +24,8 @@ EXPORTS.mozilla.widget += [ UNIFIED_SOURCES += [ 'AudioSession.cpp', + 'CompositorWidgetChild.cpp', + 'CompositorWidgetParent.cpp', 'GfxInfo.cpp', 'IEnumFE.cpp', 'IMMHandler.cpp',