--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -24,27 +24,28 @@ class Composer2D;
} // namespace layers
namespace gfx {
class DrawTarget;
class SourceSurface;
} // namespace gfx
namespace widget {
class WinCompositorWidget;
+class X11CompositorWidget;
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)
+#if defined(XP_WIN) || defined(MOZ_X11)
// CompositorWidgetParent should implement CompositorWidget and
// PCompositorWidgetParent.
class CompositorWidgetParent;
// CompositorWidgetChild should implement CompositorWidgetDelegate and
// PCompositorWidgetChild.
class CompositorWidgetChild;
@@ -240,16 +241,19 @@ public:
/**
* This is only used by out-of-process compositors.
*/
virtual RefPtr<VsyncObserver> GetVsyncObserver() const;
virtual WinCompositorWidget* AsWindows() {
return nullptr;
}
+ virtual X11CompositorWidget* AsX11() {
+ return nullptr;
+ }
/**
* Return the platform-specific delegate for the widget, if any.
*/
virtual CompositorWidgetDelegate* AsDelegate() {
return nullptr;
}
new file mode 100644
--- /dev/null
+++ b/widget/gtk/CompositorWidgetChild.cpp
@@ -0,0 +1,45 @@
+/* -*- 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(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
+ RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver)
+ : mVsyncDispatcher(aVsyncDispatcher)
+ , mVsyncObserver(aVsyncObserver)
+{
+ MOZ_ASSERT(XRE_IsParentProcess());
+}
+
+CompositorWidgetChild::~CompositorWidgetChild()
+{
+}
+
+bool
+CompositorWidgetChild::RecvObserveVsync()
+{
+ mVsyncDispatcher->SetCompositorVsyncObserver(mVsyncObserver);
+ return true;
+}
+
+bool
+CompositorWidgetChild::RecvUnobserveVsync()
+{
+ mVsyncDispatcher->SetCompositorVsyncObserver(nullptr);
+ return true;
+}
+
+void
+CompositorWidgetChild::NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize)
+{
+ Unused << SendNotifyClientSizeChanged(aClientSize);
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/gtk/CompositorWidgetChild.h
@@ -0,0 +1,38 @@
+/* -*- 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_gtk_CompositorWidgetChild_h
+#define widget_gtk_CompositorWidgetChild_h
+
+#include "X11CompositorWidget.h"
+#include "mozilla/widget/PCompositorWidgetChild.h"
+#include "mozilla/widget/CompositorWidgetVsyncObserver.h"
+
+namespace mozilla {
+namespace widget {
+
+class CompositorWidgetChild final
+ : public PCompositorWidgetChild
+ , public CompositorWidgetDelegate
+{
+public:
+ CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
+ RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver);
+ ~CompositorWidgetChild() override;
+
+ bool RecvObserveVsync() override;
+ bool RecvUnobserveVsync() override;
+
+ void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
+
+private:
+ RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
+ RefPtr<CompositorWidgetVsyncObserver> mVsyncObserver;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // widget_gtk_CompositorWidgetChild_h
new file mode 100644
--- /dev/null
+++ b/widget/gtk/CompositorWidgetParent.cpp
@@ -0,0 +1,48 @@
+/* -*- 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"
+#include "mozilla/Unused.h"
+
+namespace mozilla {
+namespace widget {
+
+CompositorWidgetParent::CompositorWidgetParent(const CompositorWidgetInitData& aInitData)
+ : X11CompositorWidget(aInitData)
+{
+ MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
+}
+
+CompositorWidgetParent::~CompositorWidgetParent()
+{
+}
+
+void
+CompositorWidgetParent::ObserveVsync(VsyncObserver* aObserver)
+{
+ if (aObserver) {
+ Unused << SendObserveVsync();
+ } else {
+ Unused << SendUnobserveVsync();
+ }
+ mVsyncObserver = aObserver;
+}
+
+RefPtr<VsyncObserver>
+CompositorWidgetParent::GetVsyncObserver() const
+{
+ MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
+ return mVsyncObserver;
+}
+
+bool
+CompositorWidgetParent::RecvNotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize)
+{
+ NotifyClientSizeChanged(aClientSize);
+ return true;
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/gtk/CompositorWidgetParent.h
@@ -0,0 +1,37 @@
+/* -*- 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_gtk_CompositorWidgetParent_h
+#define widget_gtk_CompositorWidgetParent_h
+
+#include "X11CompositorWidget.h"
+#include "mozilla/widget/PCompositorWidgetParent.h"
+
+namespace mozilla {
+namespace widget {
+
+class CompositorWidgetParent final
+ : public PCompositorWidgetParent,
+ public X11CompositorWidget
+{
+public:
+ explicit CompositorWidgetParent(const CompositorWidgetInitData& aInitData);
+ ~CompositorWidgetParent() override;
+
+ void ActorDestroy(ActorDestroyReason aWhy) override { }
+
+ void ObserveVsync(VsyncObserver* aObserver) override;
+ RefPtr<VsyncObserver> GetVsyncObserver() const override;
+
+ bool RecvNotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
+
+private:
+ RefPtr<VsyncObserver> mVsyncObserver;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // widget_gtk_CompositorWidgetParent_h
new file mode 100644
--- /dev/null
+++ b/widget/gtk/InProcessX11CompositorWidget.cpp
@@ -0,0 +1,33 @@
+/* -*- 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 "InProcessX11CompositorWidget.h"
+
+#include "nsWindow.h"
+
+namespace mozilla {
+namespace widget {
+
+/* static */ RefPtr<CompositorWidget>
+CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData, nsIWidget* aWidget)
+{
+ return new InProcessX11CompositorWidget(aInitData, static_cast<nsWindow*>(aWidget));
+}
+
+InProcessX11CompositorWidget::InProcessX11CompositorWidget(const CompositorWidgetInitData& aInitData,
+ nsWindow* aWindow)
+ : X11CompositorWidget(aInitData, aWindow)
+{
+}
+
+void
+InProcessX11CompositorWidget::ObserveVsync(VsyncObserver* aObserver)
+{
+ RefPtr<CompositorVsyncDispatcher> cvd = mWidget->GetCompositorVsyncDispatcher();
+ cvd->SetCompositorVsyncObserver(aObserver);
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/gtk/InProcessX11CompositorWidget.h
@@ -0,0 +1,30 @@
+/* -*- 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_gtk_InProcessX11CompositorWidgetParent_h
+#define widget_gtk_InProcessX11CompositorWidgetParent_h
+
+#include "X11CompositorWidget.h"
+
+class nsWindow;
+
+namespace mozilla {
+namespace widget {
+
+class InProcessX11CompositorWidget final : public X11CompositorWidget
+{
+public:
+ InProcessX11CompositorWidget(const CompositorWidgetInitData& aInitData,
+ nsWindow* aWindow);
+
+ // CompositorWidgetDelegate
+
+ void ObserveVsync(VsyncObserver* aObserver) override;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // widget_gtk_InProcessX11CompositorWidgetParent_h
new file mode 100644
--- /dev/null
+++ b/widget/gtk/PCompositorWidget.ipdl
@@ -0,0 +1,30 @@
+/* -*- 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::LayoutDeviceIntSize from "Units.h";
+
+namespace mozilla {
+namespace widget {
+
+sync protocol PCompositorWidget
+{
+ manager PCompositorBridge;
+
+parent:
+ async __delete__();
+
+ async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize);
+
+child:
+
+ async ObserveVsync();
+ async UnobserveVsync();
+};
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/gtk/PlatformWidgetTypes.ipdlh
@@ -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/. */
+
+// 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.
+
+using mozilla::LayoutDeviceIntSize from "Units.h";
+
+namespace mozilla {
+namespace widget {
+
+struct CompositorWidgetInitData
+{
+ uintptr_t XWindow;
+ nsCString XDisplayString;
+
+ LayoutDeviceIntSize InitialClientSize;
+};
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/gtk/WindowSurfaceProvider.cpp
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * 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 "WindowSurfaceProvider.h"
+
+#include "gfxPlatformGtk.h"
+#include "mozilla/layers/LayersTypes.h"
+#include "WindowSurfaceX11Image.h"
+#include "WindowSurfaceX11SHM.h"
+#include "WindowSurfaceXRender.h"
+
+namespace mozilla {
+namespace widget {
+
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+WindowSurfaceProvider::WindowSurfaceProvider()
+ : mXDisplay(nullptr)
+ , mXWindow(0)
+ , mXVisual(nullptr)
+ , mXDepth(0)
+ , mWindowSurface(nullptr)
+{
+}
+
+void WindowSurfaceProvider::Initialize(
+ Display* aDisplay,
+ Window aWindow,
+ Visual* aVisual,
+ int aDepth)
+{
+ // We should not be initialized
+ MOZ_ASSERT(!mXDisplay);
+
+ // This should also be a valid initialization
+ MOZ_ASSERT(aDisplay && aWindow != X11None && aVisual);
+
+ mXDisplay = aDisplay;
+ mXWindow = aWindow;
+ mXVisual = aVisual;
+ mXDepth = aDepth;
+}
+void WindowSurfaceProvider::CleanupResources()
+{
+ mWindowSurface = nullptr;
+}
+
+UniquePtr<WindowSurface>
+WindowSurfaceProvider::CreateWindowSurface()
+{
+ // We should be initialized
+ MOZ_ASSERT(mXDisplay);
+
+ // Blit to the window with the following priority:
+ // 1. XRender (iff XRender is enabled && we are in-process)
+ // 2. MIT-SHM
+ // 3. XPutImage
+
+#ifdef MOZ_WIDGET_GTK
+ if (gfxVars::UseXRender()) {
+ LOGDRAW(("Drawing to nsWindow %p using XRender\n", (void*)this));
+ return MakeUnique<WindowSurfaceXRender>(mXDisplay, mXWindow, mXVisual, mXDepth);
+ }
+#endif // MOZ_WIDGET_GTK
+
+#ifdef MOZ_HAVE_SHMIMAGE
+ if (nsShmImage::UseShm()) {
+ LOGDRAW(("Drawing to nsWindow %p using MIT-SHM\n", (void*)this));
+ return MakeUnique<WindowSurfaceX11SHM>(mXDisplay, mXWindow, mXVisual, mXDepth);
+ }
+#endif // MOZ_HAVE_SHMIMAGE
+
+ LOGDRAW(("Drawing to nsWindow %p using XPutImage\n", (void*)this));
+ return MakeUnique<WindowSurfaceX11Image>(mXDisplay, mXWindow, mXVisual, mXDepth);
+}
+
+already_AddRefed<gfx::DrawTarget>
+WindowSurfaceProvider::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
+ layers::BufferMode* aBufferMode)
+{
+ if (aInvalidRegion.IsEmpty())
+ return nullptr;
+
+ if (!mWindowSurface) {
+ mWindowSurface = CreateWindowSurface();
+ if (!mWindowSurface)
+ return nullptr;
+ }
+
+ *aBufferMode = BufferMode::BUFFER_NONE;
+ RefPtr<DrawTarget> dt = nullptr;
+ if (!(dt = mWindowSurface->Lock(aInvalidRegion))) {
+ gfxWarningOnce() << "Failed to lock WindowSurface, falling back to XPutImage backend.";
+ mWindowSurface = MakeUnique<WindowSurfaceX11Image>(mXDisplay, mXWindow, mXVisual, mXDepth);
+ }
+ return dt.forget();
+}
+
+void
+WindowSurfaceProvider::EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
+ LayoutDeviceIntRegion& aInvalidRegion)
+{
+ if (mWindowSurface)
+ mWindowSurface->Commit(aInvalidRegion);
+}
+
+} // namespace mozilla
+} // namespace widget
new file mode 100644
--- /dev/null
+++ b/widget/gtk/WindowSurfaceProvider.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * 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 _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_PROVIDER_H
+#define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_PROVIDER_H
+
+#include "mozilla/widget/WindowSurface.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/gfx/2D.h"
+#include "Units.h"
+
+#include <X11/Xlib.h> // for Window, Display, Visual, etc.
+
+namespace mozilla {
+namespace widget {
+
+/*
+ * Holds the logic for creating WindowSurface's for a GTK nsWindow.
+ * The main purpose of this class is to allow sharing of logic between
+ * nsWindow and X11CompositorWidget, for when OMTC is enabled or disabled.
+ */
+class WindowSurfaceProvider final
+{
+public:
+ WindowSurfaceProvider();
+
+ /**
+ * Initializes the WindowSurfaceProvider by giving it the window
+ * handle and display to attach to. WindowSurfaceProvider doesn't
+ * own the Display, Window, etc, and they must continue to exist
+ * while WindowSurfaceProvider is used.
+ */
+ void Initialize(
+ Display* aDisplay,
+ Window aWindow,
+ Visual* aVisual,
+ int aDepth);
+
+ /**
+ * Releases any surfaces created by this provider.
+ * This is used by X11CompositorWidget to get rid
+ * of resources before we close the display connection.
+ */
+ void CleanupResources();
+
+ already_AddRefed<gfx::DrawTarget>
+ StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
+ layers::BufferMode* aBufferMode);
+ void EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
+ LayoutDeviceIntRegion& aInvalidRegion);
+
+private:
+ UniquePtr<WindowSurface> CreateWindowSurface();
+
+ Display* mXDisplay;
+ Window mXWindow;
+ Visual* mXVisual;
+ int mXDepth;
+
+ UniquePtr<WindowSurface> mWindowSurface;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_PROVIDER_H
--- a/widget/gtk/WindowSurfaceX11.cpp
+++ b/widget/gtk/WindowSurfaceX11.cpp
@@ -1,38 +1,39 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 "WindowSurfaceX11.h"
#include "gfxPlatform.h"
+#include "X11UndefineNone.h"
namespace mozilla {
namespace widget {
WindowSurfaceX11::WindowSurfaceX11(Display* aDisplay,
Window aWindow,
Visual* aVisual,
unsigned int aDepth)
: mDisplay(aDisplay)
, mWindow(aWindow)
, mVisual(aVisual)
, mDepth(aDepth)
, mFormat(GetVisualFormat(aVisual, aDepth))
- , mGC(None)
+ , mGC(X11None)
{
MOZ_ASSERT(mFormat != gfx::SurfaceFormat::UNKNOWN,
"Could not find SurfaceFormat for visual!");
}
WindowSurfaceX11::~WindowSurfaceX11()
{
- if (mGC != None)
+ if (mGC != X11None)
XFreeGC(mDisplay, mGC);
}
void
WindowSurfaceX11::Commit(const LayoutDeviceIntRegion& aInvalidRegion)
{
AutoTArray<XRectangle, 32> xrects;
xrects.SetCapacity(aInvalidRegion.GetNumRects());
new file mode 100644
--- /dev/null
+++ b/widget/gtk/X11CompositorWidget.cpp
@@ -0,0 +1,108 @@
+/* -*- 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 "X11CompositorWidget.h"
+
+#include "gfxPlatformGtk.h"
+#include "mozilla/layers/CompositorThread.h"
+#include "mozilla/widget/InProcessCompositorWidget.h"
+#include "mozilla/widget/PlatformWidgetTypes.h"
+#include "nsWindow.h"
+
+namespace mozilla {
+namespace widget {
+
+X11CompositorWidget::X11CompositorWidget(const CompositorWidgetInitData& aInitData,
+ nsWindow* aWindow)
+ : mWidget(aWindow)
+{
+ // If we have a nsWindow, then grab the already existing display connection
+ // If we don't, then use the init data to connect to the display
+ if (aWindow) {
+ mXDisplay = (Display*)aWindow->GetNativeData(NS_NATIVE_COMPOSITOR_DISPLAY);
+ } else {
+ mXDisplay = XOpenDisplay(aInitData.XDisplayString().get());
+ }
+ mXWindow = (Window)aInitData.XWindow();
+
+ // Grab the window's visual and depth
+ XWindowAttributes windowAttrs;
+ XGetWindowAttributes(mXDisplay, mXWindow, &windowAttrs);
+
+ Visual* visual = windowAttrs.visual;
+ int depth = windowAttrs.depth;
+
+ // Initialize the window surface provider
+ mProvider.Initialize(
+ mXDisplay,
+ mXWindow,
+ visual,
+ depth
+ );
+
+ mClientSize = aInitData.InitialClientSize();
+}
+
+X11CompositorWidget::~X11CompositorWidget()
+{
+ mProvider.CleanupResources();
+
+ // If we created our own display connection, we need to destroy it
+ if (!mWidget && mXDisplay) {
+ XCloseDisplay(mXDisplay);
+ mXDisplay = nullptr;
+ }
+}
+
+already_AddRefed<gfx::DrawTarget>
+X11CompositorWidget::StartRemoteDrawing()
+{
+ return nullptr;
+}
+void
+X11CompositorWidget::EndRemoteDrawing()
+{
+}
+
+already_AddRefed<gfx::DrawTarget>
+X11CompositorWidget::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
+ layers::BufferMode* aBufferMode)
+{
+ return mProvider.StartRemoteDrawingInRegion(aInvalidRegion,
+ aBufferMode);
+}
+
+void X11CompositorWidget::EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
+ LayoutDeviceIntRegion& aInvalidRegion)
+{
+ mProvider.EndRemoteDrawingInRegion(aDrawTarget,
+ aInvalidRegion);
+}
+
+nsIWidget* X11CompositorWidget::RealWidget()
+{
+ return mWidget;
+}
+
+void
+X11CompositorWidget::NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize)
+{
+ mClientSize = aClientSize;
+}
+
+LayoutDeviceIntSize
+X11CompositorWidget::GetClientSize()
+{
+ return mClientSize;
+}
+
+uintptr_t
+X11CompositorWidget::GetWidgetKey()
+{
+ return reinterpret_cast<uintptr_t>(mWidget);
+}
+
+} // namespace widget
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/gtk/X11CompositorWidget.h
@@ -0,0 +1,66 @@
+/* -*- 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_gtk_X11CompositorWidget_h
+#define widget_gtk_X11CompositorWidget_h
+
+#include "mozilla/widget/CompositorWidget.h"
+#include "WindowSurfaceProvider.h"
+
+class nsIWidget;
+class nsWindow;
+
+namespace mozilla {
+namespace widget {
+
+class CompositorWidgetDelegate
+{
+public:
+ virtual void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) = 0;
+};
+
+class X11CompositorWidget
+ : public CompositorWidget
+ , public CompositorWidgetDelegate
+{
+public:
+ X11CompositorWidget(const CompositorWidgetInitData& aInitData,
+ nsWindow* aWindow = nullptr);
+ ~X11CompositorWidget();
+
+ // CompositorWidget Overrides
+
+ already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
+ void EndRemoteDrawing() override;
+
+ already_AddRefed<gfx::DrawTarget>
+ StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
+ layers::BufferMode* aBufferMode) override;
+ void EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
+ LayoutDeviceIntRegion& aInvalidRegion) override;
+ uintptr_t GetWidgetKey() override;
+
+ void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
+ LayoutDeviceIntSize GetClientSize() override;
+
+ nsIWidget* RealWidget() override;
+ X11CompositorWidget* AsX11() override { return this; }
+ CompositorWidgetDelegate* AsDelegate() override { return this; }
+
+protected:
+ nsWindow* mWidget;
+
+private:
+ LayoutDeviceIntSize mClientSize;
+
+ Display* mXDisplay;
+ Window mXWindow;
+ WindowSurfaceProvider mProvider;
+};
+
+} // namespace widget
+} // namespace mozilla
+
+#endif // widget_gtk_X11CompositorWidget_h
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -40,17 +40,27 @@ UNIFIED_SOURCES += [
]
SOURCES += [
'nsWindow.cpp', # conflicts with X11 headers
]
if CONFIG['MOZ_X11']:
UNIFIED_SOURCES += [
+ 'CompositorWidgetChild.cpp',
+ 'CompositorWidgetParent.cpp',
+ 'InProcessX11CompositorWidget.cpp',
'nsIdleServiceGTK.cpp',
+ 'X11CompositorWidget.cpp',
+ ]
+ EXPORTS.mozilla.widget += [
+ 'CompositorWidgetChild.h',
+ 'CompositorWidgetParent.h',
+ 'InProcessX11CompositorWidget.h',
+ 'X11CompositorWidget.h',
]
if CONFIG['NS_PRINTING']:
UNIFIED_SOURCES += [
'nsCUPSShim.cpp',
'nsDeviceContextSpecG.cpp',
'nsPaperPS.cpp',
'nsPrintDialogGTK.cpp',
@@ -58,20 +68,24 @@ if CONFIG['NS_PRINTING']:
'nsPrintSettingsGTK.cpp',
'nsPSPrinters.cpp',
]
if CONFIG['MOZ_X11']:
UNIFIED_SOURCES += [
'nsClipboard.cpp',
'nsDragService.cpp',
+ 'WindowSurfaceProvider.cpp',
'WindowSurfaceX11.cpp',
'WindowSurfaceX11Image.cpp',
'WindowSurfaceXRender.cpp',
]
+ EXPORTS.mozilla.widget += [
+ 'WindowSurfaceProvider.h',
+ ]
if CONFIG['ACCESSIBILITY']:
UNIFIED_SOURCES += [
'maiRedundantObjectFactory.c',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
UNIFIED_SOURCES += [
--- a/widget/gtk/nsApplicationChooser.cpp
+++ b/widget/gtk/nsApplicationChooser.cpp
@@ -5,18 +5,21 @@
#include "mozilla/Types.h"
#include <gtk/gtk.h>
#include "nsApplicationChooser.h"
#include "WidgetUtils.h"
#include "nsIMIMEInfo.h"
+#include "nsIWidget.h"
#include "nsCExternalHandlerService.h"
+#include "nsComponentManagerUtils.h"
#include "nsGtkUtils.h"
+#include "nsPIDOMWindow.h"
using namespace mozilla;
NS_IMPL_ISUPPORTS(nsApplicationChooser, nsIApplicationChooser)
nsApplicationChooser::nsApplicationChooser()
{
}
--- a/widget/gtk/nsApplicationChooser.h
+++ b/widget/gtk/nsApplicationChooser.h
@@ -2,17 +2,21 @@
/* 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 nsApplicationChooser_h__
#define nsApplicationChooser_h__
#include <gtk/gtk.h>
+#include "nsCOMPtr.h"
#include "nsIApplicationChooser.h"
+#include "nsString.h"
+
+class nsIWidget;
class nsApplicationChooser final : public nsIApplicationChooser
{
public:
nsApplicationChooser();
NS_DECL_ISUPPORTS
NS_DECL_NSIAPPLICATIONCHOOSER
void Done(GtkWidget* chooser, gint response);
--- a/widget/gtk/nsClipboard.cpp
+++ b/widget/gtk/nsClipboard.cpp
@@ -27,16 +27,17 @@
// For manipulation of the X event queue
#include <X11/Xlib.h>
#include <gdk/gdkx.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
+#include "X11UndefineNone.h"
#include "mozilla/dom/EncodingUtils.h"
#include "nsIUnicodeDecoder.h"
using mozilla::dom::EncodingUtils;
using namespace mozilla;
// Callback when someone asks us for the data
--- a/widget/gtk/nsColorPicker.cpp
+++ b/widget/gtk/nsColorPicker.cpp
@@ -5,16 +5,17 @@
#include <gtk/gtk.h>
#include "nsColor.h"
#include "nsColorPicker.h"
#include "nsGtkUtils.h"
#include "nsIWidget.h"
#include "WidgetUtils.h"
+#include "nsPIDOMWindow.h"
NS_IMPL_ISUPPORTS(nsColorPicker, nsIColorPicker)
#if defined(ACTIVATE_GTK3_COLOR_PICKER) && GTK_CHECK_VERSION(3,4,0)
int nsColorPicker::convertGdkRgbaComponent(gdouble color_component) {
// GdkRGBA value is in range [0.0..1.0]. We need something in range [0..255]
return color_component * 255 + 0.5;
}
--- a/widget/gtk/nsDeviceContextSpecG.cpp
+++ b/widget/gtk/nsDeviceContextSpecG.cpp
@@ -11,16 +11,17 @@
#include "plstr.h"
#include "prenv.h" /* for PR_GetEnv */
#include "nsPrintfCString.h"
#include "nsReadableUtils.h"
#include "nsStringEnumerator.h"
#include "nsIServiceManager.h"
+#include "nsThreadUtils.h"
#include "nsPSPrinters.h"
#include "nsPaperPS.h" /* Paper size list */
#include "nsPrintSettingsGTK.h"
#include "nsIFileStreams.h"
#include "nsIFile.h"
--- a/widget/gtk/nsScreenGtk.cpp
+++ b/widget/gtk/nsScreenGtk.cpp
@@ -1,15 +1,17 @@
/* -*- 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 "nsScreenGtk.h"
+#include "nsIWidget.h"
+
#include <gdk/gdk.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#endif
#include <gtk/gtk.h>
#include <dlfcn.h>
#include "gfxPlatformGtk.h"
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -112,16 +112,17 @@ using namespace mozilla::widget;
#include "Layers.h"
#include "GLContextProvider.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/HelpersCairo.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#ifdef MOZ_X11
+#include "X11CompositorWidget.h"
#include "gfxXlibSurface.h"
#include "WindowSurfaceX11Image.h"
#include "WindowSurfaceX11SHM.h"
#include "WindowSurfaceXRender.h"
#endif // MOZ_X11
#include "nsShmImage.h"
@@ -2484,16 +2485,23 @@ nsWindow::OnSizeAllocate(GtkAllocation *
GdkRectangle rect = DevicePixelsToGdkRectRoundOut(
LayoutDeviceIntRect(0, mBounds.height,
size.width, size.height - mBounds.height));
gdk_window_invalidate_rect(mGdkWindow, &rect, FALSE);
}
mBounds.SizeTo(size);
+#ifdef MOZ_X11
+ // Notify the X11CompositorWidget of a ClientSizeChange
+ if (mCompositorWidgetDelegate) {
+ mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
+ }
+#endif
+
// Gecko permits running nested event loops during processing of events,
// GtkWindow callers of gtk_widget_size_allocate expect the signal
// handlers to return sometime in the near future.
mNeedsDispatchResized = true;
NS_DispatchToCurrentThread(NewRunnableMethod(this, &nsWindow::MaybeDispatchResized));
}
void
@@ -3985,16 +3993,18 @@ nsWindow::Create(nsIWidget* aParent,
#ifdef MOZ_X11
if (mIsX11Display && mGdkWindow) {
mXDisplay = GDK_WINDOW_XDISPLAY(mGdkWindow);
mXWindow = gdk_x11_window_get_xid(mGdkWindow);
GdkVisual* gdkVisual = gdk_window_get_visual(mGdkWindow);
mXVisual = gdk_x11_visual_get_xvisual(gdkVisual);
mXDepth = gdk_visual_get_depth(gdkVisual);
+
+ mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth);
}
#endif
return NS_OK;
}
void
nsWindow::SetWindowClass(const nsAString &xulWinType)
@@ -4086,16 +4096,24 @@ nsWindow::NativeResize()
allocation.width = size.width;
allocation.height = size.height;
gtk_widget_size_allocate(widget, &allocation);
}
else if (mGdkWindow) {
gdk_window_resize(mGdkWindow, size.width, size.height);
}
+#ifdef MOZ_X11
+ // Notify the X11CompositorWidget of a ClientSizeChange
+ // This is different than OnSizeAllocate to catch initial sizing
+ if (mCompositorWidgetDelegate) {
+ mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
+ }
+#endif
+
// Does it need to be shown because bounds were previously insane?
if (mNeedsShow && mIsShown) {
NativeShow(true);
}
}
void
nsWindow::NativeMoveResize()
@@ -4134,16 +4152,24 @@ nsWindow::NativeMoveResize()
allocation.height = size.height;
gtk_widget_size_allocate(GTK_WIDGET(mContainer), &allocation);
}
else if (mGdkWindow) {
gdk_window_move_resize(mGdkWindow,
topLeft.x, topLeft.y, size.width, size.height);
}
+#ifdef MOZ_X11
+ // Notify the X11CompositorWidget of a ClientSizeChange
+ // This is different than OnSizeAllocate to catch initial sizing
+ if (mCompositorWidgetDelegate) {
+ mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
+ }
+#endif
+
// Does it need to be shown because bounds were previously insane?
if (mNeedsShow && mIsShown) {
NativeShow(true);
}
}
void
nsWindow::NativeShow(bool aAction)
@@ -6530,44 +6556,24 @@ nsWindow::GetDrawTargetForGdkDrawable(Gd
return dt.forget();
}
#endif
already_AddRefed<DrawTarget>
nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode)
{
- if (aInvalidRegion.IsEmpty())
- return nullptr;
-
- if (!mWindowSurface) {
- mWindowSurface = CreateWindowSurface();
- if (!mWindowSurface)
- return nullptr;
- }
-
- *aBufferMode = BufferMode::BUFFER_NONE;
- RefPtr<DrawTarget> dt = nullptr;
- if (!(dt = mWindowSurface->Lock(aInvalidRegion))) {
-#ifdef MOZ_X11
- if (mIsX11Display) {
- gfxWarningOnce() << "Failed to lock WindowSurface, falling back to XPutImage backend.";
- mWindowSurface = MakeUnique<WindowSurfaceX11Image>(mXDisplay, mXWindow, mXVisual, mXDepth);
- }
-#endif // MOZ_X11
- }
- return dt.forget();
+ return mSurfaceProvider.StartRemoteDrawingInRegion(aInvalidRegion, aBufferMode);
}
void
nsWindow::EndRemoteDrawingInRegion(DrawTarget* aDrawTarget,
LayoutDeviceIntRegion& aInvalidRegion)
{
- if (mWindowSurface)
- mWindowSurface->Commit(aInvalidRegion);
+ mSurfaceProvider.EndRemoteDrawingInRegion(aDrawTarget, aInvalidRegion);
}
// Code shared begin BeginMoveDrag and BeginResizeDrag
bool
nsWindow::GetDragInfo(WidgetMouseEvent* aMouseEvent,
GdkWindow** aWindow, gint* aButton,
gint* aRootX, gint* aRootY)
{
@@ -6994,50 +7000,20 @@ nsWindow::SynthesizeNativeTouchPoint(uin
#endif
int32_t
nsWindow::RoundsWidgetCoordinatesTo()
{
return GdkScaleFactor();
}
-UniquePtr<WindowSurface>
-nsWindow::CreateWindowSurface()
-{
- if (!mGdkWindow)
- return nullptr;
-
- // TODO: Add path for Wayland. We can't use gdk_cairo_create as it's not
- // threadsafe.
- if (!mIsX11Display)
- return nullptr;
-
-#ifdef MOZ_X11
- // Blit to the window with the following priority:
- // 1. XRender (iff XRender is enabled)
- // 2. MIT-SHM
- // 3. XPutImage
-
-#ifdef MOZ_WIDGET_GTK
- if (gfxVars::UseXRender()) {
- LOGDRAW(("Drawing to nsWindow %p using XRender\n", (void*)this));
- return MakeUnique<WindowSurfaceXRender>(mXDisplay, mXWindow, mXVisual, mXDepth);
- }
-#endif // MOZ_WIDGET_GTK
-
- Display* display;
- if (CompositorThreadHolder::IsInCompositorThread()) {
- display = gfxPlatformGtk::GetPlatform()->GetCompositorDisplay();
- } else {
- display = mXDisplay;
- }
-
-#ifdef MOZ_HAVE_SHMIMAGE
- if (nsShmImage::UseShm()) {
- LOGDRAW(("Drawing to nsWindow %p using MIT-SHM\n", (void*)this));
- return MakeUnique<WindowSurfaceX11SHM>(display, mXWindow, mXVisual, mXDepth);
- }
-#endif // MOZ_HAVE_SHMIMAGE
-
- LOGDRAW(("Drawing to nsWindow %p using XPutImage\n", (void*)this));
- return MakeUnique<WindowSurfaceX11Image>(display, mXWindow, mXVisual, mXDepth);
-#endif // MOZ_X11
-}
+void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
+{
+ #ifdef MOZ_X11
+ Display* xDisplay = (Display*)GetNativeData(NS_NATIVE_COMPOSITOR_DISPLAY);
+ char* xDisplayString = XDisplayString(xDisplay);
+
+ *aInitData = mozilla::widget::CompositorWidgetInitData(
+ mXWindow,
+ nsCString(xDisplayString),
+ GetClientSize());
+ #endif
+}
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -20,16 +20,17 @@
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#endif /* MOZ_X11 */
#include "mozilla/widget/WindowSurface.h"
+#include "mozilla/widget/WindowSurfaceProvider.h"
#ifdef ACCESSIBILITY
#include "mozilla/a11y/Accessible.h"
#endif
#include "mozilla/EventForwards.h"
#include "mozilla/TouchEvents.h"
#include "IMContextWrapper.h"
@@ -340,16 +341,18 @@ public:
virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
TouchPointerState aPointerState,
LayoutDeviceIntPoint aPoint,
double aPointerPressure,
uint32_t aPointerOrientation,
nsIObserver* aObserver) override;
#endif
+ virtual void GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData) override;
+
// HiDPI scale conversion
gint GdkScaleFactor();
// To GDK
gint DevicePixelsToGdkCoordRoundUp(int pixels);
gint DevicePixelsToGdkCoordRoundDown(int pixels);
GdkPoint DevicePixelsToGdkPointRoundDown(LayoutDeviceIntPoint point);
GdkRectangle DevicePixelsToGdkSizeRoundUp(LayoutDeviceIntSize pixelSize);
@@ -445,23 +448,22 @@ private:
#if GTK_CHECK_VERSION(3,4,0)
// This field omits duplicate scroll events caused by GNOME bug 726878.
guint32 mLastScrollEventTime;
// for touch event handling
nsRefPtrHashtable<nsPtrHashKey<GdkEventSequence>, mozilla::dom::Touch> mTouches;
#endif
- mozilla::UniquePtr<mozilla::widget::WindowSurface> mWindowSurface;
-
#ifdef MOZ_X11
Display* mXDisplay;
Window mXWindow;
Visual* mXVisual;
int mXDepth;
+ mozilla::widget::WindowSurfaceProvider mSurfaceProvider;
#endif
// Upper bound on pending ConfigureNotify events to be dispatched to the
// window. See bug 1225044.
int mPendingConfigures;
#ifdef ACCESSIBILITY
RefPtr<mozilla::a11y::Accessible> mRootAccessible;
@@ -542,18 +544,16 @@ private:
virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
void CleanLayerManagerRecursive();
virtual int32_t RoundsWidgetCoordinatesTo() override;
- mozilla::UniquePtr<mozilla::widget::WindowSurface> CreateWindowSurface();
-
/**
* |mIMContext| takes all IME related stuff.
*
* This is owned by the top-level nsWindow or the topmost child
* nsWindow embedded in a non-Gecko widget.
*
* The instance is created when the top level widget is created. And when
* the widget is destroyed, it's released. All child windows refer its
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -252,16 +252,21 @@ LOCAL_INCLUDES += [
'/widget',
]
if toolkit == 'windows':
IPDL_SOURCES = [
'windows/PCompositorWidget.ipdl',
'windows/PlatformWidgetTypes.ipdlh',
]
+elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT'] and CONFIG['MOZ_X11']:
+ IPDL_SOURCES = [
+ 'gtk/PCompositorWidget.ipdl',
+ 'gtk/PlatformWidgetTypes.ipdlh',
+ ]
else:
IPDL_SOURCES = [
'PCompositorWidget.ipdl',
'PlatformWidgetTypes.ipdlh',
]
widget_dir = toolkit
if widget_dir in ('gtk3', 'gtk2'):