Bug 1373739 - Make headless compositing Windows-compatible, in addition to Linux. r=dvander
To make the HeadlessCompositorWidget work under Windows as well as Linux, I had
to change the way that I hooked it into the existing CompositorWidget system.
Under GTK, the CompositorWidgetInitData and CompositorWidgetDelegate types
provided the information needed by the headless compositor widget already (the
widget client size). On Windows, however, the definitions of these types
differ, and the client size information is simply retrieved from the platform
APIs when needed.
After this patch, CompositorWidgetDelegate is renamed to
PlatformCompositorWidgetDelegate, and a new base class called
CompositorWidgetDelegate is added with "AsPlatformSpecificDelegate()" and
"AsHeadlessCompositorWidget()" methods. In non-headless mode, widgets use
AsPlatformSpecificDelegate() to access the Windows- and GTK-specific delegate
APIs. In headless mode, AsHeadlessCompositorWidget() is used to access the
singular CompositorWidget implementation for headless. Meanwhile, the
CompositorWidgetInitData IPDL type is made into a union which always contains a
headless-specific HeadlessCompositorWidgetInitData struct and under GTK and
Windows also contains an {X11,Win}CompositorWidgetInitData struct.
This also includes a small patch to ensure that the GPU process and
hardware-accelerated compositing are always disabled under headless mode. These
features weren't activated by default in the Linux environments I tested in, but
did end up activating (and then promptly crashing Firefox) when I tested on
Windows.
MozReview-Commit-ID: CocPoHBDV7H
This commit is contained in:
@@ -38,6 +38,7 @@ GPUProcessHost::Launch()
|
||||
{
|
||||
MOZ_ASSERT(mLaunchPhase == LaunchPhase::Unlaunched);
|
||||
MOZ_ASSERT(!mGPUChild);
|
||||
MOZ_ASSERT(!gfxPlatform::IsHeadless());
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
mSandboxLevel = Preferences::GetInt("security.sandbox.gpu.level");
|
||||
|
||||
@@ -29,6 +29,7 @@ RemoteCompositorSession::RemoteCompositorSession(nsBaseWidget* aWidget,
|
||||
mWidget(aWidget),
|
||||
mAPZ(aAPZ)
|
||||
{
|
||||
MOZ_ASSERT(!gfxPlatform::IsHeadless());
|
||||
GPUProcessManager::Get()->RegisterRemoteProcessSession(this);
|
||||
if (mAPZ) {
|
||||
mAPZ->SetCompositorSession(this);
|
||||
|
||||
@@ -2362,6 +2362,13 @@ gfxPlatform::InitGPUProcessPrefs()
|
||||
gpuProc.UserForceEnable("User force-enabled via pref");
|
||||
}
|
||||
|
||||
if (IsHeadless()) {
|
||||
gpuProc.ForceDisable(
|
||||
FeatureStatus::Blocked,
|
||||
"Headless mode is enabled",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_HEADLESS_MODE"));
|
||||
return;
|
||||
}
|
||||
if (InSafeMode()) {
|
||||
gpuProc.ForceDisable(
|
||||
FeatureStatus::Blocked,
|
||||
@@ -2408,11 +2415,15 @@ gfxPlatform::InitCompositorAccelerationPrefs()
|
||||
feature.UserForceEnable("Force-enabled by pref");
|
||||
}
|
||||
|
||||
// Safe mode trumps everything.
|
||||
// Safe and headless modes override everything.
|
||||
if (InSafeMode()) {
|
||||
feature.ForceDisable(FeatureStatus::Blocked, "Acceleration blocked by safe-mode",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_SAFEMODE"));
|
||||
}
|
||||
if (IsHeadless()) {
|
||||
feature.ForceDisable(FeatureStatus::Blocked, "Acceleration blocked by headless mode",
|
||||
NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_HEADLESSMODE"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -42,7 +42,22 @@ class CompositorWidgetInitData;
|
||||
// transparency). This functionality is controlled through a "host". Since
|
||||
// this functionality is platform-dependent, it is only forward declared
|
||||
// here.
|
||||
class CompositorWidgetDelegate;
|
||||
class PlatformCompositorWidgetDelegate;
|
||||
|
||||
// Headless mode uses its own, singular CompositorWidget implementation.
|
||||
class HeadlessCompositorWidget;
|
||||
|
||||
class CompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
virtual PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual HeadlessCompositorWidget* AsHeadlessCompositorWidget() {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// Platforms that support out-of-process widgets.
|
||||
#if defined(XP_WIN) || defined(MOZ_X11)
|
||||
|
||||
@@ -7,11 +7,19 @@
|
||||
// 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.
|
||||
|
||||
include HeadlessWidgetTypes;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
struct CompositorWidgetInitData
|
||||
union CompositorWidgetInitData
|
||||
{
|
||||
HeadlessCompositorWidgetInitData;
|
||||
};
|
||||
|
||||
struct HeadlessCompositorWidgetInitData
|
||||
{
|
||||
LayoutDeviceIntSize InitialClientSize;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "CompositorWidgetChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
@@ -15,6 +16,7 @@ CompositorWidgetChild::CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> a
|
||||
, mVsyncObserver(aVsyncObserver)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(!gfxPlatform::IsHeadless());
|
||||
}
|
||||
|
||||
CompositorWidgetChild::~CompositorWidgetChild()
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace widget {
|
||||
|
||||
class CompositorWidgetChild final
|
||||
: public PCompositorWidgetChild
|
||||
, public CompositorWidgetDelegate
|
||||
, public PlatformCompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
|
||||
#include "CompositorWidgetParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
CompositorWidgetParent::CompositorWidgetParent(const CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions)
|
||||
: X11CompositorWidget(aInitData, aOptions)
|
||||
: X11CompositorWidget(aInitData.get_X11CompositorWidgetInitData(), aOptions)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* 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 "gfxPlatform.h"
|
||||
#include "HeadlessCompositorWidget.h"
|
||||
#include "HeadlessWidget.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
|
||||
#include "InProcessX11CompositorWidget.h"
|
||||
#include "nsWindow.h"
|
||||
@@ -18,14 +18,16 @@ CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsIWidget* aWidget)
|
||||
{
|
||||
if (gfxPlatform::IsHeadless()) {
|
||||
return new HeadlessCompositorWidget(aInitData, aOptions, static_cast<HeadlessWidget*>(aWidget));
|
||||
if (aInitData.type() == CompositorWidgetInitData::THeadlessCompositorWidgetInitData) {
|
||||
return new HeadlessCompositorWidget(aInitData.get_HeadlessCompositorWidgetInitData(),
|
||||
aOptions, static_cast<HeadlessWidget*>(aWidget));
|
||||
} else {
|
||||
return new InProcessX11CompositorWidget(aInitData, aOptions, static_cast<nsWindow*>(aWidget));
|
||||
return new InProcessX11CompositorWidget(aInitData.get_X11CompositorWidgetInitData(),
|
||||
aOptions, static_cast<nsWindow*>(aWidget));
|
||||
}
|
||||
}
|
||||
|
||||
InProcessX11CompositorWidget::InProcessX11CompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
InProcessX11CompositorWidget::InProcessX11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsWindow* aWindow)
|
||||
: X11CompositorWidget(aInitData, aOptions, aWindow)
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace widget {
|
||||
class InProcessX11CompositorWidget final : public X11CompositorWidget
|
||||
{
|
||||
public:
|
||||
InProcessX11CompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
InProcessX11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsWindow* aWindow);
|
||||
|
||||
|
||||
@@ -4,15 +4,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/. */
|
||||
|
||||
// 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.
|
||||
include HeadlessWidgetTypes;
|
||||
|
||||
using mozilla::LayoutDeviceIntSize from "Units.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
struct CompositorWidgetInitData
|
||||
struct X11CompositorWidgetInitData
|
||||
{
|
||||
uintptr_t XWindow;
|
||||
nsCString XDisplayString;
|
||||
@@ -20,5 +19,11 @@ struct CompositorWidgetInitData
|
||||
LayoutDeviceIntSize InitialClientSize;
|
||||
};
|
||||
|
||||
union CompositorWidgetInitData
|
||||
{
|
||||
X11CompositorWidgetInitData;
|
||||
HeadlessCompositorWidgetInitData;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
X11CompositorWidget::X11CompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
X11CompositorWidget::X11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
|
||||
const CompositorOptions& aOptions,
|
||||
nsWindow* aWindow)
|
||||
: CompositorWidget(aOptions)
|
||||
|
||||
@@ -15,18 +15,27 @@ class nsWindow;
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
class CompositorWidgetDelegate
|
||||
class PlatformCompositorWidgetDelegate
|
||||
: public CompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
virtual void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) = 0;
|
||||
|
||||
// CompositorWidgetDelegate Overrides
|
||||
|
||||
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
class X11CompositorWidgetInitData;
|
||||
|
||||
class X11CompositorWidget
|
||||
: public CompositorWidget
|
||||
, public CompositorWidgetDelegate
|
||||
, public PlatformCompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
X11CompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
X11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsWindow* aWindow = nullptr);
|
||||
~X11CompositorWidget();
|
||||
@@ -43,7 +52,6 @@ public:
|
||||
LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
uintptr_t GetWidgetKey() override;
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||
LayoutDeviceIntSize GetClientSize() override;
|
||||
|
||||
nsIWidget* RealWidget() override;
|
||||
@@ -53,6 +61,10 @@ public:
|
||||
Display* XDisplay() const { return mXDisplay; }
|
||||
Window XWindow() const { return mXWindow; }
|
||||
|
||||
// PlatformCompositorWidgetDelegate Overrides
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||
|
||||
protected:
|
||||
nsWindow* mWidget;
|
||||
|
||||
|
||||
@@ -437,6 +437,7 @@ nsWindow::nsWindow()
|
||||
mContainer = nullptr;
|
||||
mGdkWindow = nullptr;
|
||||
mShell = nullptr;
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
mHasMappedToplevel = false;
|
||||
mIsFullyObscured = false;
|
||||
mRetryPointerGrab = false;
|
||||
@@ -6529,6 +6530,18 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
return nsBaseWidget::GetLayerManager(aShadowManager, aBackendHint, aPersistence);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate)
|
||||
{
|
||||
if (delegate) {
|
||||
mCompositorWidgetDelegate = delegate->AsPlatformSpecificDelegate();
|
||||
MOZ_ASSERT(mCompositorWidgetDelegate,
|
||||
"nsWindow::SetCompositorWidgetDelegate called with a non-PlatformCompositorWidgetDelegate");
|
||||
} else {
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::ClearCachedResources()
|
||||
{
|
||||
@@ -6825,7 +6838,7 @@ nsWindow::RoundsWidgetCoordinatesTo()
|
||||
void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
|
||||
{
|
||||
#ifdef MOZ_X11
|
||||
*aInitData = mozilla::widget::CompositorWidgetInitData(
|
||||
*aInitData = mozilla::widget::X11CompositorWidgetInitData(
|
||||
mXWindow,
|
||||
nsCString(XDisplayString(mXDisplay)),
|
||||
GetClientSize());
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
#include "nsBaseWidget.h"
|
||||
#include "CompositorWidget.h"
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
@@ -73,6 +74,7 @@ class nsWindow final : public nsBaseWidget
|
||||
public:
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
typedef mozilla::WidgetEventTime WidgetEventTime;
|
||||
typedef mozilla::widget::PlatformCompositorWidgetDelegate PlatformCompositorWidgetDelegate;
|
||||
|
||||
nsWindow();
|
||||
|
||||
@@ -436,6 +438,8 @@ private:
|
||||
GtkWidget *mShell;
|
||||
MozContainer *mContainer;
|
||||
GdkWindow *mGdkWindow;
|
||||
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
|
||||
|
||||
|
||||
uint32_t mHasMappedToplevel : 1,
|
||||
mIsFullyObscured : 1,
|
||||
@@ -541,6 +545,8 @@ private:
|
||||
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
|
||||
|
||||
void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
|
||||
|
||||
void CleanLayerManagerRecursive();
|
||||
|
||||
virtual int32_t RoundsWidgetCoordinatesTo() override;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
HeadlessCompositorWidget::HeadlessCompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
HeadlessCompositorWidget::HeadlessCompositorWidget(const HeadlessCompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
HeadlessWidget* aWindow)
|
||||
: CompositorWidget(aOptions)
|
||||
|
||||
@@ -7,27 +7,29 @@
|
||||
#define widget_headless_HeadlessCompositorWidget_h
|
||||
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "InProcessX11CompositorWidget.h"
|
||||
|
||||
#include "HeadlessWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
class HeadlessCompositorWidgetInitData;
|
||||
|
||||
class HeadlessCompositorWidget final
|
||||
: public CompositorWidget
|
||||
, public CompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
HeadlessCompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
HeadlessCompositorWidget(const HeadlessCompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
HeadlessWidget* aWindow);
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize);
|
||||
|
||||
// CompositorWidget Overrides
|
||||
|
||||
uintptr_t GetWidgetKey() override;
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||
LayoutDeviceIntSize GetClientSize() override;
|
||||
|
||||
nsIWidget* RealWidget() override;
|
||||
@@ -35,6 +37,12 @@ public:
|
||||
|
||||
void ObserveVsync(VsyncObserver* aObserver) override;
|
||||
|
||||
// CompositorWidgetDelegate Overrides
|
||||
|
||||
HeadlessCompositorWidget* AsHeadlessCompositorWidget() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
private:
|
||||
HeadlessWidget* mWidget;
|
||||
|
||||
|
||||
@@ -37,6 +37,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(HeadlessWidget, nsBaseWidget)
|
||||
|
||||
HeadlessWidget* HeadlessWidget::sActiveWindow = nullptr;
|
||||
|
||||
HeadlessWidget::HeadlessWidget()
|
||||
: mEnabled(true)
|
||||
, mVisible(false)
|
||||
, mTopLevel(nullptr)
|
||||
, mCompositorWidget(nullptr)
|
||||
, mLastSizeMode(nsSizeMode_Normal)
|
||||
, mEffectiveSizeMode(nsSizeMode_Normal)
|
||||
, mRestoreBounds(0,0,0,0)
|
||||
{
|
||||
}
|
||||
|
||||
HeadlessWidget::~HeadlessWidget()
|
||||
{
|
||||
if (sActiveWindow == this)
|
||||
@@ -55,8 +66,6 @@ HeadlessWidget::Create(nsIWidget* aParent,
|
||||
|
||||
mBounds = aRect;
|
||||
mRestoreBounds = aRect;
|
||||
mVisible = false;
|
||||
mEnabled = true;
|
||||
|
||||
if (aParent) {
|
||||
mTopLevel = aParent->GetTopLevelWidget();
|
||||
@@ -84,13 +93,7 @@ HeadlessWidget::CreateChild(const LayoutDeviceIntRect& aRect,
|
||||
|
||||
void HeadlessWidget::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
|
||||
{
|
||||
uintptr_t xWindow(0);
|
||||
nsCString xDisplayString(0);
|
||||
|
||||
*aInitData = mozilla::widget::CompositorWidgetInitData(
|
||||
xWindow,
|
||||
xDisplayString,
|
||||
GetClientSize());
|
||||
*aInitData = mozilla::widget::HeadlessCompositorWidgetInitData(GetClientSize());
|
||||
}
|
||||
|
||||
nsIWidget*
|
||||
@@ -207,6 +210,18 @@ HeadlessWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
return nsBaseWidget::GetLayerManager(aShadowManager, aBackendHint, aPersistence);
|
||||
}
|
||||
|
||||
void
|
||||
HeadlessWidget::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate)
|
||||
{
|
||||
if (delegate) {
|
||||
mCompositorWidget = delegate->AsHeadlessCompositorWidget();
|
||||
MOZ_ASSERT(mCompositorWidget,
|
||||
"HeadlessWidget::SetCompositorWidgetDelegate called with a non-HeadlessCompositorWidget");
|
||||
} else {
|
||||
mCompositorWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HeadlessWidget::Resize(double aWidth,
|
||||
double aHeight,
|
||||
@@ -217,9 +232,8 @@ HeadlessWidget::Resize(double aWidth,
|
||||
ConstrainSize(&width, &height);
|
||||
mBounds.SizeTo(LayoutDeviceIntSize(width, height));
|
||||
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->NotifyClientSizeChanged(
|
||||
LayoutDeviceIntSize(mBounds.width, mBounds.height));
|
||||
if (mCompositorWidget) {
|
||||
mCompositorWidget->NotifyClientSizeChanged(LayoutDeviceIntSize(mBounds.width, mBounds.height));
|
||||
}
|
||||
if (mWidgetListener) {
|
||||
mWidgetListener->WindowResized(this, mBounds.width, mBounds.height);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/widget/InProcessCompositorWidget.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "CompositorWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
@@ -16,7 +17,7 @@ namespace widget {
|
||||
class HeadlessWidget : public nsBaseWidget
|
||||
{
|
||||
public:
|
||||
HeadlessWidget() : mEffectiveSizeMode(nsSizeMode_Normal) {}
|
||||
HeadlessWidget();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
@@ -85,6 +86,8 @@ public:
|
||||
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
|
||||
|
||||
void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
|
||||
|
||||
virtual nsresult DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
nsEventStatus& aStatus) override;
|
||||
|
||||
@@ -93,6 +96,7 @@ private:
|
||||
bool mEnabled;
|
||||
bool mVisible;
|
||||
nsIWidget* mTopLevel;
|
||||
HeadlessCompositorWidget* mCompositorWidget;
|
||||
// The size mode before entering fullscreen mode.
|
||||
nsSizeMode mLastSizeMode;
|
||||
// The last size mode set while the window was visible.
|
||||
|
||||
18
widget/headless/HeadlessWidgetTypes.ipdlh
Normal file
18
widget/headless/HeadlessWidgetTypes.ipdlh
Normal file
@@ -0,0 +1,18 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
using mozilla::LayoutDeviceIntSize from "Units.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
struct HeadlessCompositorWidgetInitData
|
||||
{
|
||||
LayoutDeviceIntSize InitialClientSize;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
@@ -292,6 +292,7 @@ LOCAL_INCLUDES += [
|
||||
|
||||
if toolkit == 'windows':
|
||||
IPDL_SOURCES = [
|
||||
'headless/HeadlessWidgetTypes.ipdlh',
|
||||
'windows/PCompositorWidget.ipdl',
|
||||
'windows/PlatformWidgetTypes.ipdlh',
|
||||
]
|
||||
@@ -299,9 +300,11 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT'] and CONFIG['MOZ_X11']:
|
||||
IPDL_SOURCES = [
|
||||
'gtk/PCompositorWidget.ipdl',
|
||||
'gtk/PlatformWidgetTypes.ipdlh',
|
||||
'headless/HeadlessWidgetTypes.ipdlh',
|
||||
]
|
||||
else:
|
||||
IPDL_SOURCES = [
|
||||
'headless/HeadlessWidgetTypes.ipdlh',
|
||||
'PCompositorWidget.ipdl',
|
||||
'PlatformWidgetTypes.ipdlh',
|
||||
]
|
||||
|
||||
@@ -166,7 +166,6 @@ nsBaseWidget::nsBaseWidget()
|
||||
, mPopupLevel(ePopupLevelTop)
|
||||
, mPopupType(ePopupTypeAny)
|
||||
, mHasRemoteContent(false)
|
||||
, mCompositorWidgetDelegate(nullptr)
|
||||
, mUpdateCursor(true)
|
||||
, mUseAttachedEvents(false)
|
||||
, mIMEHasFocus(false)
|
||||
@@ -281,7 +280,7 @@ void nsBaseWidget::DestroyCompositor()
|
||||
if (mCompositorSession) {
|
||||
ReleaseContentController();
|
||||
mAPZC = nullptr;
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
SetCompositorWidgetDelegate(nullptr);
|
||||
mCompositorBridgeChild = nullptr;
|
||||
|
||||
// XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
|
||||
@@ -1347,7 +1346,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
|
||||
MOZ_ASSERT(mCompositorSession);
|
||||
mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
|
||||
mCompositorWidgetDelegate = mCompositorSession->GetCompositorWidgetDelegate();
|
||||
SetCompositorWidgetDelegate(mCompositorSession->GetCompositorWidgetDelegate());
|
||||
|
||||
if (options.UseAPZ()) {
|
||||
mAPZC = mCompositorSession->GetAPZCTreeManager();
|
||||
|
||||
@@ -214,6 +214,7 @@ public:
|
||||
void CreateCompositorVsyncDispatcher();
|
||||
virtual void CreateCompositor();
|
||||
virtual void CreateCompositor(int aWidth, int aHeight);
|
||||
virtual void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) {}
|
||||
virtual void PrepareWindowEffects() override {}
|
||||
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) override {}
|
||||
virtual void SetModal(bool aModal) override {}
|
||||
@@ -690,8 +691,6 @@ protected:
|
||||
SizeConstraints mSizeConstraints;
|
||||
bool mHasRemoteContent;
|
||||
|
||||
CompositorWidgetDelegate* mCompositorWidgetDelegate;
|
||||
|
||||
bool mUpdateCursor;
|
||||
bool mUseAttachedEvents;
|
||||
bool mIMEHasFocus;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "mozilla/widget/CompositorWidgetVsyncObserver.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "VsyncDispatcher.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
@@ -18,6 +19,7 @@ CompositorWidgetChild::CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> a
|
||||
mVsyncObserver(aVsyncObserver)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(!gfxPlatform::IsHeadless());
|
||||
}
|
||||
|
||||
CompositorWidgetChild::~CompositorWidgetChild()
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace widget {
|
||||
|
||||
class CompositorWidgetChild final
|
||||
: public PCompositorWidgetChild,
|
||||
public CompositorWidgetDelegate
|
||||
public PlatformCompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
#include "CompositorWidgetParent.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
CompositorWidgetParent::CompositorWidgetParent(const CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions)
|
||||
: WinCompositorWidget(aInitData, aOptions)
|
||||
: WinCompositorWidget(aInitData.get_WinCompositorWidgetInitData(), aOptions)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* 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 "gfxPlatform.h"
|
||||
#include "HeadlessCompositorWidget.h"
|
||||
#include "HeadlessWidget.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
|
||||
#include "InProcessWinCompositorWidget.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
@@ -14,10 +19,16 @@ CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsIWidget* aWidget)
|
||||
{
|
||||
return new InProcessWinCompositorWidget(aInitData, aOptions, static_cast<nsWindow*>(aWidget));
|
||||
if (aInitData.type() == CompositorWidgetInitData::THeadlessCompositorWidgetInitData) {
|
||||
return new HeadlessCompositorWidget(aInitData.get_HeadlessCompositorWidgetInitData(),
|
||||
aOptions, static_cast<HeadlessWidget*>(aWidget));
|
||||
} else {
|
||||
return new InProcessWinCompositorWidget(aInitData.get_WinCompositorWidgetInitData(),
|
||||
aOptions, static_cast<nsWindow*>(aWidget));
|
||||
}
|
||||
}
|
||||
|
||||
InProcessWinCompositorWidget::InProcessWinCompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
InProcessWinCompositorWidget::InProcessWinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsWindow* aWindow)
|
||||
: WinCompositorWidget(aInitData, aOptions),
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace widget {
|
||||
class InProcessWinCompositorWidget final : public WinCompositorWidget
|
||||
{
|
||||
public:
|
||||
InProcessWinCompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
InProcessWinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions,
|
||||
nsWindow* aWindow);
|
||||
|
||||
|
||||
@@ -4,20 +4,25 @@
|
||||
* 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/. */
|
||||
|
||||
// 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.
|
||||
include HeadlessWidgetTypes;
|
||||
|
||||
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
struct CompositorWidgetInitData
|
||||
struct WinCompositorWidgetInitData
|
||||
{
|
||||
WindowsHandle hWnd;
|
||||
uintptr_t widgetKey;
|
||||
int32_t transparencyMode;
|
||||
};
|
||||
|
||||
union CompositorWidgetInitData
|
||||
{
|
||||
WinCompositorWidgetInitData;
|
||||
HeadlessCompositorWidgetInitData;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace widget {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
WinCompositorWidget::WinCompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
WinCompositorWidget::WinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions)
|
||||
: CompositorWidget(aOptions)
|
||||
, mWidgetKey(aInitData.widgetKey()),
|
||||
|
||||
@@ -17,7 +17,8 @@ class nsWindow;
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
class CompositorWidgetDelegate
|
||||
class PlatformCompositorWidgetDelegate
|
||||
: public CompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
// Callbacks for nsWindow.
|
||||
@@ -32,20 +33,30 @@ public:
|
||||
// If in-process and using software rendering, return the backing transparent
|
||||
// DC.
|
||||
virtual HDC GetTransparentDC() const = 0;
|
||||
|
||||
// CompositorWidgetDelegate Overrides
|
||||
|
||||
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class WinCompositorWidgetInitData;
|
||||
|
||||
// This is the Windows-specific implementation of CompositorWidget. For
|
||||
// the most part it only requires an HWND, however it maintains extra state
|
||||
// for transparent windows, as well as for synchronizing WM_SETTEXT messages
|
||||
// with the compositor.
|
||||
class WinCompositorWidget
|
||||
: public CompositorWidget,
|
||||
public CompositorWidgetDelegate
|
||||
public PlatformCompositorWidgetDelegate
|
||||
{
|
||||
public:
|
||||
WinCompositorWidget(const CompositorWidgetInitData& aInitData,
|
||||
WinCompositorWidget(const WinCompositorWidgetInitData& aInitData,
|
||||
const layers::CompositorOptions& aOptions);
|
||||
|
||||
// CompositorWidget Overrides
|
||||
|
||||
bool PreRender(WidgetRenderingContext*) override;
|
||||
void PostRender(WidgetRenderingContext*) override;
|
||||
already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
|
||||
@@ -66,7 +77,8 @@ public:
|
||||
}
|
||||
bool IsHidden() const override;
|
||||
|
||||
// CompositorWidgetDelegate overrides.
|
||||
// PlatformCompositorWidgetDelegate Overrides
|
||||
|
||||
void EnterPresentLock() override;
|
||||
void LeavePresentLock() override;
|
||||
void OnDestroyWindow() override;
|
||||
|
||||
@@ -645,6 +645,8 @@ nsWindow::nsWindow(bool aIsChildWindow)
|
||||
|
||||
mTaskbarPreview = nullptr;
|
||||
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
|
||||
// Global initialization
|
||||
if (!sInstanceCount) {
|
||||
// Global app registration id for Win7 and up. See
|
||||
@@ -3948,7 +3950,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
|
||||
// Ensure we have a widget proxy even if we're not using the compositor,
|
||||
// since all our transparent window handling lives there.
|
||||
CompositorWidgetInitData initData(
|
||||
WinCompositorWidgetInitData initData(
|
||||
reinterpret_cast<uintptr_t>(mWnd),
|
||||
reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this)),
|
||||
mTransparencyMode);
|
||||
@@ -3964,6 +3966,27 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
return mLayerManager;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: nsBaseWidget::SetCompositorWidgetDelegate
|
||||
*
|
||||
* Called to connect the nsWindow to the delegate providing
|
||||
* platform compositing API access.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
void
|
||||
nsWindow::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate)
|
||||
{
|
||||
if (delegate) {
|
||||
mCompositorWidgetDelegate = delegate->AsPlatformSpecificDelegate();
|
||||
MOZ_ASSERT(mCompositorWidgetDelegate,
|
||||
"nsWindow::SetCompositorWidgetDelegate called with a non-PlatformCompositorWidgetDelegate");
|
||||
} else {
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: nsIWidget::OnDefaultButtonLoaded
|
||||
@@ -8379,9 +8402,10 @@ bool nsWindow::OnPointerEvents(UINT msg, WPARAM aWParam, LPARAM aLParam)
|
||||
void
|
||||
nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
|
||||
{
|
||||
aInitData->hWnd() = reinterpret_cast<uintptr_t>(mWnd);
|
||||
aInitData->widgetKey() = reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this));
|
||||
aInitData->transparencyMode() = mTransparencyMode;
|
||||
*aInitData = WinCompositorWidgetInitData(
|
||||
reinterpret_cast<uintptr_t>(mWnd),
|
||||
reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this)),
|
||||
mTransparencyMode);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "CompositorWidget.h"
|
||||
#include "nsWindowBase.h"
|
||||
#include "nsdefs.h"
|
||||
#include "nsIdleService.h"
|
||||
@@ -76,6 +77,7 @@ class nsWindow final : public nsWindowBase
|
||||
typedef mozilla::widget::NativeKey NativeKey;
|
||||
typedef mozilla::widget::MSGResult MSGResult;
|
||||
typedef mozilla::widget::IMEContext IMEContext;
|
||||
typedef mozilla::widget::PlatformCompositorWidgetDelegate PlatformCompositorWidgetDelegate;
|
||||
|
||||
public:
|
||||
explicit nsWindow(bool aIsChildWindow = false);
|
||||
@@ -177,6 +179,7 @@ public:
|
||||
virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
|
||||
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
|
||||
void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
|
||||
virtual MOZ_MUST_USE nsresult OnDefaultButtonLoaded(const LayoutDeviceIntRect& aButtonRect) override;
|
||||
virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
|
||||
int32_t aNativeKeyCode,
|
||||
@@ -559,6 +562,8 @@ protected:
|
||||
static bool sIsInMouseCapture;
|
||||
static bool sHaveInitializedPrefs;
|
||||
|
||||
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
|
||||
|
||||
// Always use the helper method to read this property. See bug 603793.
|
||||
static TriStateBool sHasBogusPopupsDropShadowOnMultiMonitor;
|
||||
static bool HasBogusPopupsDropShadowOnMultiMonitor();
|
||||
|
||||
Reference in New Issue
Block a user