diff options
author | Martin Stransky <stransky@redhat.com> | 2019-07-02 12:23:46 +0200 |
---|---|---|
committer | Martin Stransky <stransky@redhat.com> | 2019-07-02 12:23:46 +0200 |
commit | ec241d8209f52813a2e99fd0abd1567aa2b46115 (patch) | |
tree | ea4210e50b8c62c6648af8416b744a789932aeed | |
parent | Updated to 67.0.4 (diff) | |
download | librewolf-fedora-ff-ec241d8209f52813a2e99fd0abd1567aa2b46115.tar.gz librewolf-fedora-ff-ec241d8209f52813a2e99fd0abd1567aa2b46115.tar.bz2 librewolf-fedora-ff-ec241d8209f52813a2e99fd0abd1567aa2b46115.zip |
Updated to 68.0
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | firefox-pipewire.patch | 43 | ||||
-rw-r--r-- | firefox.spec | 50 | ||||
-rw-r--r-- | mozilla-1196777.patch | 10 | ||||
-rw-r--r-- | mozilla-1423598-popup.patch | 203 | ||||
-rw-r--r-- | mozilla-1467127.patch | 256 | ||||
-rw-r--r-- | mozilla-1468911.patch | 276 | ||||
-rw-r--r-- | mozilla-1508378.patch | 92 | ||||
-rw-r--r-- | mozilla-1517205.patch | 209 | ||||
-rw-r--r-- | mozilla-1526243.patch | 340 | ||||
-rw-r--r-- | mozilla-1532643-popup.patch | 71 | ||||
-rw-r--r-- | mozilla-1535567.patch | 136 | ||||
-rw-r--r-- | mozilla-1539471.patch | 206 | ||||
-rw-r--r-- | mozilla-1540145.patch | 156 | ||||
-rw-r--r-- | mozilla-1552590.patch | 2701 | ||||
-rw-r--r-- | sources | 4 |
16 files changed, 19 insertions, 4736 deletions
@@ -351,3 +351,5 @@ firefox-3.6.4.source.tar.bz2 /firefox-67.0.3.source.tar.xz /firefox-67.0.4.source.tar.xz /firefox-langpacks-67.0.4-20190620.tar.xz +/firefox-68.0.source.tar.xz +/firefox-langpacks-68.0-20190702.tar.xz diff --git a/firefox-pipewire.patch b/firefox-pipewire.patch index aa1541b..816010e 100644 --- a/firefox-pipewire.patch +++ b/firefox-pipewire.patch @@ -17,49 +17,6 @@ diff -up firefox-66.0/config/system-headers.mozbuild.firefox-pipewire firefox-66 'pixman.h', 'pk11func.h', 'pk11pqg.h', -diff -up firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc.firefox-pipewire firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc ---- firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc.firefox-pipewire 2019-03-12 15:27:37.675285710 +0100 -+++ firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc 2019-03-12 15:27:37.675285710 +0100 -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#include "modules/desktop_capture/desktop_capture_options.h" -+#include "modules/desktop_capture/desktop_capturer.h" -+ -+#if defined(USE_X11) -+#include "modules/desktop_capture/app_capturer_x11.h" -+#endif // defined(USE_X11) -+ -+namespace webrtc { -+ -+// static -+AppCapturer* AppCapturer::Create(const DesktopCaptureOptions& options) { -+#if defined(USE_X11) -+ return AppCapturerX11::Create(options); -+#endif // defined(USE_X11) -+ -+ return nullptr; -+} -+ -+// static -+std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawAppCapturer( -+ const DesktopCaptureOptions& options) { -+#if defined(USE_X11) -+ return AppCapturerX11::CreateRawAppCapturer(options); -+#endif // defined(USE_X11) -+ -+ return nullptr; -+} -+ -+} // namespace webrtc diff -up firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc.firefox-pipewire firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc --- firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc.firefox-pipewire 2019-03-12 01:22:20.000000000 +0100 +++ firefox-66.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc 2019-03-12 15:27:37.675285710 +0100 diff --git a/firefox.spec b/firefox.spec index c1c3014..57d88ba 100644 --- a/firefox.spec +++ b/firefox.spec @@ -76,15 +76,8 @@ ExcludeArch: s390x %bcond_without langpacks +# Disable crashreporter as we want to collect Wayland crashes. %global enable_mozilla_crashreporter 0 -%if !%{debug_build} -%ifarch %{ix86} x86_64 -# Disable crashreporter sa we want to collect Wayland crashes. -%if 0%{?fedora} < 28 -%global enable_mozilla_crashreporter 1 -%endif -%endif -%endif %if !%{release_build} %global pre_tag .test @@ -92,13 +85,13 @@ ExcludeArch: s390x Summary: Mozilla Firefox Web browser Name: firefox -Version: 67.0.4 +Version: 68.0 Release: 1%{?pre_tag}%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz %if %{with langpacks} -Source1: firefox-langpacks-%{version}%{?pre_version}-20190620.tar.xz +Source1: firefox-langpacks-%{version}%{?pre_version}-20190702.tar.xz %endif Source2: cbindgen-vendor.tar.xz Source10: firefox-mozconfig @@ -142,23 +135,12 @@ Patch227: firefox-locale-debug.patch # Upstream patches Patch402: mozilla-1196777.patch Patch412: mozilla-1337988.patch -Patch413: mozilla-1353817.patch +#Patch413: mozilla-1353817.patch Patch415: Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch Patch417: bug1375074-save-restore-x28.patch -Patch418: mozilla-1526243.patch -Patch419: mozilla-1540145.patch # Wayland specific upstream patches -Patch574: firefox-pipewire.patch -Patch575: mozilla-1423598-popup.patch -Patch576: mozilla-1532643-popup.patch -Patch577: mozilla-1535567.patch -Patch579: mozilla-1468911.patch -Patch580: mozilla-1539471.patch -Patch581: mozilla-1517205.patch -Patch582: mozilla-1508378.patch -Patch583: mozilla-1467127.patch -Patch584: mozilla-1552590.patch +#Patch574: firefox-pipewire.patch # PGO/LTO patches Patch600: pgo.patch @@ -204,9 +186,7 @@ BuildRequires: clang-libs %if 0%{?build_with_clang} BuildRequires: lld %endif -%if 0%{?fedora} > 28 BuildRequires: pipewire-devel -%endif %if !0%{?use_bundled_cbindgen} BuildRequires: cbindgen %endif @@ -351,7 +331,7 @@ This package contains results of tests executed during build. %patch227 -p1 -b .locale-debug %patch402 -p1 -b .1196777 -%patch413 -p1 -b .1353817 +#%patch413 -p1 -b .1353817 %ifarch %{arm} %patch415 -p1 -b .1238661 %endif @@ -359,22 +339,9 @@ This package contains results of tests executed during build. %if 0%{?big_endian} %patch26 -p1 -b .icu %endif -%patch418 -p1 -b .mozilla-1526243 -%patch419 -p1 -b .mozilla-1540145 # Wayland specific upstream patches -%if 0%{?fedora} > 28 -%patch574 -p1 -b .firefox-pipewire -%endif -%patch575 -p1 -b .mozilla-1423598-popup -%patch576 -p1 -b .mozilla-1532643-popup -%patch577 -p1 -b .mozilla-1535567 -%patch579 -p1 -b .mozilla-1468911 -%patch580 -p1 -b .mozilla-1539471 -%patch581 -p1 -b .mozilla-1517205 -%patch582 -p1 -b .mozilla-1508378 -#%patch583 -p1 -b .mozilla-1467127 -#%patch584 -p1 -b .mozilla-1552590 +#%patch574 -p1 -b .firefox-pipewire # PGO patches %patch600 -p1 -b .pgo @@ -944,6 +911,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Tue Jul 2 2019 Martin Stransky <stransky@redhat.com> - 68.0-1 +- Updated to 68.0 + * Thu Jun 20 2019 Martin Stransky <stransky@redhat.com> - 67.0.4-1 - Updated to 67.0.4 diff --git a/mozilla-1196777.patch b/mozilla-1196777.patch index 6606fe3..ed3ab16 100644 --- a/mozilla-1196777.patch +++ b/mozilla-1196777.patch @@ -1,6 +1,6 @@ -diff -up firefox-65.0/widget/gtk/nsWindow.cpp.1196777 firefox-65.0/widget/gtk/nsWindow.cpp ---- firefox-65.0/widget/gtk/nsWindow.cpp.1196777 2019-01-28 14:37:27.470163867 +0100 -+++ firefox-65.0/widget/gtk/nsWindow.cpp 2019-01-28 14:41:52.479064393 +0100 +diff -up firefox-68.0/widget/gtk/nsWindow.cpp.1196777 firefox-68.0/widget/gtk/nsWindow.cpp +--- firefox-68.0/widget/gtk/nsWindow.cpp.1196777 2019-07-02 11:47:06.864726826 +0200 ++++ firefox-68.0/widget/gtk/nsWindow.cpp 2019-07-02 11:48:09.896544339 +0200 @@ -156,7 +156,8 @@ const gint kEvents = #if GTK_CHECK_VERSION(3, 4, 0) GDK_SMOOTH_SCROLL_MASK | GDK_TOUCH_MASK | @@ -9,5 +9,5 @@ diff -up firefox-65.0/widget/gtk/nsWindow.cpp.1196777 firefox-65.0/widget/gtk/ns + GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK | + GDK_FOCUS_CHANGE_MASK; - /* utility functions */ - static bool is_mouse_in_window(GdkWindow *aWindow, gdouble aMouseX, + #if !GTK_CHECK_VERSION(3, 22, 0) + typedef enum { diff --git a/mozilla-1423598-popup.patch b/mozilla-1423598-popup.patch deleted file mode 100644 index bacac7d..0000000 --- a/mozilla-1423598-popup.patch +++ /dev/null @@ -1,203 +0,0 @@ -diff -up firefox-67.0/widget/gtk/nsWindow.cpp.mozilla-1423598-popup firefox-67.0/widget/gtk/nsWindow.cpp ---- firefox-67.0/widget/gtk/nsWindow.cpp.mozilla-1423598-popup 2019-05-15 15:21:25.590222702 +0200 -+++ firefox-67.0/widget/gtk/nsWindow.cpp 2019-05-15 15:24:26.925439991 +0200 -@@ -1115,13 +1115,89 @@ void nsWindow::Move(double aX, double aY - NotifyRollupGeometryChange(); - } - -+#ifdef DEBUG -+static void NativeMoveResizeWaylandPopupCallback(GdkWindow *window, -+ const GdkRectangle *flipped_rect, const GdkRectangle *final_rect, -+ gboolean flipped_x, gboolean flipped_y, void *unused) -+{ -+ LOG(("NativeMoveResizeWaylandPopupCallback flipped %d %d\n", -+ flipped_rect->x, flipped_rect->y)); -+ LOG(("NativeMoveResizeWaylandPopupCallback final %d %d\n", -+ final_rect->x, final_rect->y)); -+} -+#endif -+ -+void nsWindow::NativeMoveResizeWaylandPopup(GdkPoint* aPosition, GdkRectangle* aSize) { -+ // Available as of GTK 3.24+ -+ static auto sGdkWindowMoveToRect = -+ (void (*)(GdkWindow *, const GdkRectangle *, GdkGravity, GdkGravity, -+ GdkAnchorHints, gint, gint)) -+ dlsym(RTLD_DEFAULT, "gdk_window_move_to_rect"); -+ -+ if (aSize) { -+ gtk_window_resize(GTK_WINDOW(mShell), aSize->width, aSize->height); -+ } -+ if (!sGdkWindowMoveToRect) { -+ gtk_window_move(GTK_WINDOW(mShell), aPosition->x, aPosition->y); -+ return; -+ } -+ -+ GdkWindow *gdkWindow = gtk_widget_get_window(GTK_WIDGET(mShell)); -+ if (!gdkWindow) { -+ return; -+ } -+ -+ GtkWidget* parentWidget = -+ GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); -+ -+ int x_parent, y_parent; -+ gdk_window_get_origin(gtk_widget_get_window(parentWidget), &x_parent, &y_parent); -+ -+ GdkRectangle rect = { aPosition->x - x_parent, -+ aPosition->y - y_parent, -+ 1, 1}; -+ if (aSize) { -+ rect.width = aSize->width; -+ rect.height = aSize->height; -+ } -+ -+#ifdef DEBUG -+ LOG(("NativeMoveResizeWaylandPopup request position %d,%d\n", -+ aPosition->x, aPosition->y)); -+ if (aSize) { -+ LOG(("NativeMoveResizeWaylandPopup request size %d,%d\n", -+ aSize->width, aSize->height)); -+ } -+ LOG(("NativeMoveResizeWaylandPopup result %d %d\n", rect.x, rect.y)); -+ g_signal_connect(gdkWindow, "moved-to-rect", -+ G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this); -+#endif -+ -+ GdkGravity rectAnchor = GDK_GRAVITY_NORTH_WEST; -+ GdkGravity menuAnchor = GDK_GRAVITY_NORTH_WEST; -+ if (GetTextDirection() == GTK_TEXT_DIR_RTL) { -+ rectAnchor = GDK_GRAVITY_NORTH_EAST; -+ menuAnchor = GDK_GRAVITY_NORTH_EAST; -+ } -+ -+ GdkAnchorHints hints = GdkAnchorHints(GDK_ANCHOR_SLIDE | GDK_ANCHOR_FLIP); -+ if (aSize) { -+ hints = GdkAnchorHints(hints|GDK_ANCHOR_RESIZE); -+ } -+ -+ sGdkWindowMoveToRect(gdkWindow, &rect, rectAnchor, menuAnchor, hints, 0, 0); -+} -+ - void nsWindow::NativeMove() { - GdkPoint point = DevicePixelsToGdkPointRoundDown(mBounds.TopLeft()); -- -- if (mIsTopLevel) { -- gtk_window_move(GTK_WINDOW(mShell), point.x, point.y); -- } else if (mGdkWindow) { -- gdk_window_move(mGdkWindow, point.x, point.y); -+ if (!mIsX11Display && mIsTopLevel && mWindowType == eWindowType_popup) { -+ NativeMoveResizeWaylandPopup(&point, nullptr); -+ } else { -+ if (mIsTopLevel) { -+ gtk_window_move(GTK_WINDOW(mShell), point.x, point.y); -+ } else if (mGdkWindow) { -+ gdk_window_move(mGdkWindow, point.x, point.y); -+ } - } - } - -@@ -3412,11 +3488,6 @@ nsresult nsWindow::Create(nsIWidget *aPa - GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent); - } else if (mWindowType == eWindowType_popup) { -- // With popup windows, we want to control their position, so don't -- // wait for the window manager to place them (which wouldn't -- // happen with override-redirect windows anyway). -- NativeMove(); -- - gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", - gdk_get_program_class()); - -@@ -3475,6 +3546,14 @@ nsresult nsWindow::Create(nsIWidget *aPa - if (topLevelParent) { - gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent); - } -+ -+ // We need realized mShell at NativeMove(). -+ gtk_widget_realize(mShell); -+ -+ // With popup windows, we want to control their position, so don't -+ // wait for the window manager to place them (which wouldn't -+ // happen with override-redirect windows anyway). -+ NativeMove(); - } else { // must be eWindowType_toplevel - SetDefaultIcon(); - gtk_window_set_wmclass(GTK_WINDOW(mShell), "Toplevel", -@@ -3918,23 +3997,27 @@ void nsWindow::NativeMoveResize() { - LOG(("nsWindow::NativeMoveResize [%p] %d %d %d %d\n", (void *)this, topLeft.x, - topLeft.y, size.width, size.height)); - -- if (mIsTopLevel) { -- // x and y give the position of the window manager frame top-left. -- gtk_window_move(GTK_WINDOW(mShell), topLeft.x, topLeft.y); -- // This sets the client window size. -- MOZ_ASSERT(size.width > 0 && size.height > 0, -- "Can't resize window smaller than 1x1."); -- gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height); -- } else if (mContainer) { -- GtkAllocation allocation; -- allocation.x = topLeft.x; -- allocation.y = topLeft.y; -- allocation.width = size.width; -- 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); -+ if (!mIsX11Display && mIsTopLevel && mWindowType == eWindowType_popup) { -+ NativeMoveResizeWaylandPopup(&topLeft, &size); -+ } else { -+ if (mIsTopLevel) { -+ // x and y give the position of the window manager frame top-left. -+ gtk_window_move(GTK_WINDOW(mShell), topLeft.x, topLeft.y); -+ // This sets the client window size. -+ MOZ_ASSERT(size.width > 0 && size.height > 0, -+ "Can't resize window smaller than 1x1."); -+ gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height); -+ } else if (mContainer) { -+ GtkAllocation allocation; -+ allocation.x = topLeft.x; -+ allocation.y = topLeft.y; -+ allocation.width = size.width; -+ 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 -@@ -6818,3 +6901,18 @@ void nsWindow::ForceTitlebarRedraw(void) - RestyleHint{0}, nsChangeHint_RepaintFrame); - } - } -+ -+GtkTextDirection nsWindow::GetTextDirection() { -+ nsView *view = nsView::GetViewFor(this); -+ if (!view) { -+ return GTK_TEXT_DIR_LTR; -+ } -+ nsIFrame *frame = view->GetFrame(); -+ if (!frame) { -+ return GTK_TEXT_DIR_LTR; -+ } -+ -+ WritingMode wm = frame->GetWritingMode(); -+ bool isFrameRTL = !(wm.IsVertical() ? wm.IsVerticalLR() : wm.IsBidiLTR()); -+ return isFrameRTL ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR; -+} -diff -up firefox-67.0/widget/gtk/nsWindow.h.mozilla-1423598-popup firefox-67.0/widget/gtk/nsWindow.h ---- firefox-67.0/widget/gtk/nsWindow.h.mozilla-1423598-popup 2019-05-14 01:08:37.000000000 +0200 -+++ firefox-67.0/widget/gtk/nsWindow.h 2019-05-15 15:21:25.890221541 +0200 -@@ -460,6 +460,10 @@ class nsWindow final : public nsBaseWidg - nsWindow* GetTransientForWindowIfPopup(); - bool IsHandlingTouchSequence(GdkEventSequence* aSequence); - -+ void NativeMoveResizeWaylandPopup(GdkPoint* aPosition, GdkRectangle* aSize); -+ -+ GtkTextDirection GetTextDirection(); -+ - #ifdef MOZ_X11 - typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0, - GTK_WIDGET_COMPOSIDED_DISABLED = 1, diff --git a/mozilla-1467127.patch b/mozilla-1467127.patch deleted file mode 100644 index 69a8903..0000000 --- a/mozilla-1467127.patch +++ /dev/null @@ -1,256 +0,0 @@ -diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp ---- a/gfx/thebes/gfxPlatform.cpp -+++ b/gfx/thebes/gfxPlatform.cpp -@@ -70,6 +70,10 @@ - # include "mozilla/gfx/DeviceManagerDx.h" - #endif - -+#ifdef MOZ_WAYLAND -+# include "mozilla/widget/nsWaylandDisplayShutdown.h" -+#endif -+ - #include "nsGkAtoms.h" - #include "gfxPlatformFontList.h" - #include "gfxContext.h" -@@ -1276,6 +1280,9 @@ - layers::PaintThread::Shutdown(); - } - } else if (XRE_IsParentProcess()) { -+#ifdef MOZ_WAYLAND -+ widget::WaylandDisplayShutdown(); -+#endif - gfx::VRManagerChild::ShutDown(); - layers::CompositorManagerChild::Shutdown(); - layers::ImageBridgeChild::ShutDown(); -diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp ---- a/widget/gtk/WindowSurfaceWayland.cpp -+++ b/widget/gtk/WindowSurfaceWayland.cpp -@@ -144,6 +144,8 @@ - (wl_buffer/wl_surface). - */ - -+#define EVENT_LOOP_DELAY (1000 / 240) -+ - #define BUFFER_BPP 4 - gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8; - -diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build ---- a/widget/gtk/moz.build -+++ b/widget/gtk/moz.build -@@ -101,6 +101,9 @@ - 'nsWaylandDisplay.cpp', - 'WindowSurfaceWayland.cpp', - ] -+ EXPORTS.mozilla.widget += [ -+ 'nsWaylandDisplayShutdown.h' -+ ] - - if CONFIG['ACCESSIBILITY']: - UNIFIED_SOURCES += [ -diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp ---- a/widget/gtk/nsAppShell.cpp -+++ b/widget/gtk/nsAppShell.cpp -@@ -27,6 +27,9 @@ - #include "ScreenHelperGTK.h" - #include "HeadlessScreenHelper.h" - #include "mozilla/widget/ScreenManager.h" -+#ifdef MOZ_WAYLAND -+# include "nsWaylandDisplay.h" -+#endif - - using mozilla::LazyLogModule; - using mozilla::Unused; -@@ -267,5 +270,9 @@ - } - - bool nsAppShell::ProcessNextNativeEvent(bool mayWait) { -- return g_main_context_iteration(nullptr, mayWait); -+ bool ret = g_main_context_iteration(nullptr, mayWait); -+#ifdef MOZ_WAYLAND -+ WaylandDispatchDisplays(); -+#endif -+ return ret; - } -diff --git a/widget/gtk/nsWaylandDisplay.h b/widget/gtk/nsWaylandDisplay.h ---- a/widget/gtk/nsWaylandDisplay.h -+++ b/widget/gtk/nsWaylandDisplay.h -@@ -14,10 +14,6 @@ - namespace mozilla { - namespace widget { - --// TODO: Bug 1467125 - We need to integrate wl_display_dispatch_queue_pending() --// with compositor event loop. --#define EVENT_LOOP_DELAY (1000 / 240) -- - // Our general connection to Wayland display server, - // holds our display connection and runs event loop. - class nsWaylandDisplay { -@@ -25,9 +21,10 @@ - explicit nsWaylandDisplay(wl_display* aDisplay); - virtual ~nsWaylandDisplay(); - -- bool DisplayLoop(); -+ bool DispatchEventQueue(); - bool Matches(wl_display* aDisplay); - -+ MessageLoop* GetDispatcherThreadLoop() { return mDispatcherThreadLoop; } - wl_display* GetDisplay() { return mDisplay; }; - wl_event_queue* GetEventQueue() { return mEventQueue; }; - wl_subcompositor* GetSubcompositor(void) { return mSubcompositor; }; -@@ -47,7 +44,10 @@ - void SetPrimarySelectionDeviceManager( - gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager); - -+ void Shutdown(); -+ - private: -+ MessageLoop* mDispatcherThreadLoop; - PRThread* mThreadId; - wl_display* mDisplay; - wl_event_queue* mEventQueue; -@@ -59,6 +59,7 @@ - wl_registry* mRegistry; - }; - -+void WaylandDispatchDisplays(); - nsWaylandDisplay* WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr); - - } // namespace widget -diff --git a/widget/gtk/nsWaylandDisplay.cpp b/widget/gtk/nsWaylandDisplay.cpp ---- a/widget/gtk/nsWaylandDisplay.cpp -+++ b/widget/gtk/nsWaylandDisplay.cpp -@@ -21,6 +21,15 @@ - static nsWaylandDisplay *gWaylandDisplays[MAX_DISPLAY_CONNECTIONS]; - static StaticMutex gWaylandDisplaysMutex; - -+void WaylandDisplayShutdown() { -+ StaticMutexAutoLock lock(gWaylandDisplaysMutex); -+ for (auto &display : gWaylandDisplays) { -+ if (display) { -+ display->Shutdown(); -+ } -+ } -+} -+ - static void ReleaseDisplaysAtExit() { - for (int i = 0; i < MAX_DISPLAY_CONNECTIONS; i++) { - delete gWaylandDisplays[i]; -@@ -28,6 +37,10 @@ - } - } - -+static void DispatchDisplay(nsWaylandDisplay *aDisplay) { -+ aDisplay->DispatchEventQueue(); -+} -+ - // Each thread which is using wayland connection (wl_display) has to operate - // its own wl_event_queue. Main Firefox thread wl_event_queue is handled - // by Gtk main loop, other threads/wl_event_queue has to be handled by us. -@@ -35,7 +48,15 @@ - // nsWaylandDisplay is our interface to wayland compositor. It provides wayland - // global objects as we need (wl_display, wl_shm) and operates wl_event_queue on - // compositor (not the main) thread. --static void WaylandDisplayLoop(wl_display *aDisplay); -+void WaylandDispatchDisplays() { -+ StaticMutexAutoLock lock(gWaylandDisplaysMutex); -+ for (auto &display : gWaylandDisplays) { -+ if (display && display->GetDispatcherThreadLoop()) { -+ display->GetDispatcherThreadLoop()->PostTask(NewRunnableFunction( -+ "WaylandDisplayDispatch", &DispatchDisplay, display)); -+ } -+ } -+} - - // Get WaylandDisplay for given wl_display and actual calling thread. - static nsWaylandDisplay *WaylandDisplayGetLocked(GdkDisplay *aGdkDisplay, -@@ -73,27 +94,6 @@ - return WaylandDisplayGetLocked(aGdkDisplay, lock); - } - --static void WaylandDisplayLoopLocked(wl_display *aDisplay, -- const StaticMutexAutoLock &) { -- for (auto &display : gWaylandDisplays) { -- if (display && display->Matches(aDisplay)) { -- if (display->DisplayLoop()) { -- MessageLoop::current()->PostDelayedTask( -- NewRunnableFunction("WaylandDisplayLoop", &WaylandDisplayLoop, -- aDisplay), -- EVENT_LOOP_DELAY); -- } -- break; -- } -- } --} -- --static void WaylandDisplayLoop(wl_display *aDisplay) { -- MOZ_ASSERT(!NS_IsMainThread()); -- StaticMutexAutoLock lock(gWaylandDisplaysMutex); -- WaylandDisplayLoopLocked(aDisplay, lock); --} -- - void nsWaylandDisplay::SetShm(wl_shm *aShm) { mShm = aShm; } - - void nsWaylandDisplay::SetSubcompositor(wl_subcompositor *aSubcompositor) { -@@ -158,7 +158,7 @@ - static const struct wl_registry_listener registry_listener = { - global_registry_handler, global_registry_remover}; - --bool nsWaylandDisplay::DisplayLoop() { -+bool nsWaylandDisplay::DispatchEventQueue() { - wl_display_dispatch_queue_pending(mDisplay, mEventQueue); - return true; - } -@@ -168,7 +168,8 @@ - } - - nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay) -- : mThreadId(PR_GetCurrentThread()), -+ : mDispatcherThreadLoop(nullptr), -+ mThreadId(PR_GetCurrentThread()), - mDisplay(aDisplay), - mEventQueue(nullptr), - mDataDeviceManager(nullptr), -@@ -186,15 +187,16 @@ - wl_display_roundtrip(mDisplay); - wl_display_roundtrip(mDisplay); - } else { -+ mDispatcherThreadLoop = MessageLoop::current(); - mEventQueue = wl_display_create_queue(mDisplay); -- MessageLoop::current()->PostTask(NewRunnableFunction( -- "WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay)); - wl_proxy_set_queue((struct wl_proxy *)mRegistry, mEventQueue); - wl_display_roundtrip_queue(mDisplay, mEventQueue); - wl_display_roundtrip_queue(mDisplay, mEventQueue); - } - } - -+void nsWaylandDisplay::Shutdown() { mDispatcherThreadLoop = nullptr; } -+ - nsWaylandDisplay::~nsWaylandDisplay() { - // Owned by Gtk+, we don't need to release - mDisplay = nullptr; -diff --git a/widget/gtk/nsWaylandDisplayShutdown.h b/widget/gtk/nsWaylandDisplayShutdown.h -new file mode 100644 ---- /dev/null -+++ b/widget/gtk/nsWaylandDisplayShutdown.h -@@ -0,0 +1,19 @@ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim:expandtab:shiftwidth=4:tabstop=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 __MOZ_WAYLAND_DISPLAY_SHUTDOWN_H__ -+#define __MOZ_WAYLAND_DISPLAY_SHUTDOWN_H__ -+ -+namespace mozilla { -+namespace widget { -+ -+void WaylandDisplayShutdown(); -+ -+} // namespace widget -+} // namespace mozilla -+ -+#endif // __MOZ_WAYLAND_DISPLAY_SHUTDOWN_H__ - diff --git a/mozilla-1468911.patch b/mozilla-1468911.patch deleted file mode 100644 index 209a5a7..0000000 --- a/mozilla-1468911.patch +++ /dev/null @@ -1,276 +0,0 @@ -changeset: 465236:be9a6c98a4a7 -tag: tip -user: Martin Stransky <stransky@redhat.com> -date: Mon Mar 18 10:42:48 2019 +0100 -summary: tearing - - -diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp ---- a/widget/gtk/nsAppShell.cpp -+++ b/widget/gtk/nsAppShell.cpp -@@ -35,16 +35,17 @@ using mozilla::widget::ScreenHelperGTK; - using mozilla::widget::ScreenManager; - - #define NOTIFY_TOKEN 0xFA - - LazyLogModule gWidgetLog("Widget"); - LazyLogModule gWidgetFocusLog("WidgetFocus"); - LazyLogModule gWidgetDragLog("WidgetDrag"); - LazyLogModule gWidgetDrawLog("WidgetDraw"); -+LazyLogModule gWidgetWaylandLog("WidgetWayland"); - - static GPollFunc sPollFunc; - - // Wrapper function to disable hang monitoring while waiting in poll(). - static gint PollWrapper(GPollFD* ufds, guint nfsd, gint timeout_) { - mozilla::BackgroundHangMonitor().NotifyWait(); - gint result; - { - -diff -up firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp.old firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp ---- firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp.old 2019-03-20 15:48:52.265966904 +0100 -+++ firefox-66.0/widget/gtk/WindowSurfaceWayland.cpp 2019-03-20 14:48:21.082035284 +0100 -@@ -20,6 +20,18 @@ - #include <fcntl.h> - #include <errno.h> - -+#undef LOG -+#ifdef MOZ_LOGGING -+# include "mozilla/Logging.h" -+# include "nsTArray.h" -+# include "Units.h" -+extern mozilla::LazyLogModule gWidgetWaylandLog; -+# define LOGWAYLAND(args) \ -+ MOZ_LOG(gWidgetWaylandLog, mozilla::LogLevel::Debug, args) -+#else -+# define LOGWAYLAND(args) -+#endif /* MOZ_LOGGING */ -+ - namespace mozilla { - namespace widget { - -@@ -241,7 +253,7 @@ WaylandShmPool::~WaylandShmPool() { - - static void buffer_release(void* data, wl_buffer* buffer) { - auto surface = reinterpret_cast<WindowBackBuffer*>(data); -- surface->Detach(); -+ surface->Detach(buffer); - } - - static const struct wl_buffer_listener buffer_listener = {buffer_release}; -@@ -261,9 +273,16 @@ void WindowBackBuffer::Create(int aWidth - - mWidth = aWidth; - mHeight = aHeight; -+ -+ LOGWAYLAND(( -+ "%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this, -+ (void*)mWaylandBuffer, -+ mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); - } - - void WindowBackBuffer::Release() { -+ LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); -+ - wl_buffer_destroy(mWaylandBuffer); - mWidth = mHeight = 0; - } -@@ -288,6 +307,9 @@ WindowBackBuffer::~WindowBackBuffer() { - bool WindowBackBuffer::Resize(int aWidth, int aHeight) { - if (aWidth == mWidth && aHeight == mHeight) return true; - -+ LOGWAYLAND( -+ ("%s [%p] %d %d\n", __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight)); -+ - Release(); - Create(aWidth, aHeight); - -@@ -295,13 +317,26 @@ bool WindowBackBuffer::Resize(int aWidth - } - - void WindowBackBuffer::Attach(wl_surface* aSurface) { -+ LOGWAYLAND(( -+ "%s [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, -+ (void*)this, (void*)aSurface, -+ aSurface ? wl_proxy_get_id((struct wl_proxy*)aSurface) : -1, -+ (void*)mWaylandBuffer, -+ mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); -+ - wl_surface_attach(aSurface, mWaylandBuffer, 0, 0); - wl_surface_commit(aSurface); - wl_display_flush(mWaylandDisplay->GetDisplay()); - mAttached = true; - } - --void WindowBackBuffer::Detach() { mAttached = false; } -+void WindowBackBuffer::Detach(wl_buffer* aBuffer) { -+ LOGWAYLAND(("%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this, -+ (void*)aBuffer, -+ aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1)); -+ -+ mAttached = false; -+} - - bool WindowBackBuffer::SetImageDataFromBuffer( - class WindowBackBuffer* aSourceBuffer) { -@@ -316,6 +351,11 @@ bool WindowBackBuffer::SetImageDataFromB - } - - already_AddRefed<gfx::DrawTarget> WindowBackBuffer::Lock() { -+ LOGWAYLAND(( -+ "%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, -+ (void*)this, mWidth, mHeight, (void*)mWaylandBuffer, -+ mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); -+ - gfx::IntSize lockSize(mWidth, mHeight); - return gfxPlatform::CreateDrawTargetForData( - static_cast<unsigned char*>(mShmPool.GetImageData()), lockSize, -@@ -345,7 +385,8 @@ WindowSurfaceWayland::WindowSurfaceWayla - mPendingCommit(false), - mWaylandBufferFullScreenDamage(false), - mIsMainThread(NS_IsMainThread()), -- mNeedScaleFactorUpdate(true) { -+ mNeedScaleFactorUpdate(true), -+ mWaitToFullScreenUpdate(true) { - for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr; - } - -@@ -387,7 +428,11 @@ WindowSurfaceWayland::~WindowSurfaceWayl - WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, - int aHeight) { - if (!mWaylandBuffer) { -+ LOGWAYLAND(("%s [%p] Create [%d x %d]\n", __PRETTY_FUNCTION__, (void*)this, -+ aWidth, aHeight)); -+ - mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -+ mWaitToFullScreenUpdate = true; - return mWaylandBuffer; - } - -@@ -396,8 +441,11 @@ WindowBackBuffer* WindowSurfaceWayland:: - mWaylandBuffer->Resize(aWidth, aHeight); - // There's a chance that scale factor has been changed - // when buffer size changed -- mNeedScaleFactorUpdate = true; -+ mWaitToFullScreenUpdate = true; - } -+ LOGWAYLAND(("%s [%p] Reuse buffer [%d x %d]\n", __PRETTY_FUNCTION__, -+ (void*)this, aWidth, aHeight)); -+ - return mWaylandBuffer; - } - -@@ -420,6 +468,8 @@ WindowBackBuffer* WindowSurfaceWayland:: - } - - if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) { -+ LOGWAYLAND(("%s [%p] No drawing buffer available!\n", __PRETTY_FUNCTION__, -+ (void*)this)); - NS_WARNING("No drawing buffer available"); - return nullptr; - } -@@ -429,6 +479,8 @@ WindowBackBuffer* WindowSurfaceWayland:: - mBackupBuffer[availableBuffer] = lastWaylandBuffer; - - if (lastWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { -+ LOGWAYLAND(("%s [%p] Copy from old buffer [%d x %d]\n", __PRETTY_FUNCTION__, -+ (void*)this, aWidth, aHeight)); - // Former front buffer has the same size as a requested one. - // Gecko may expect a content already drawn on screen so copy - // existing data to the new buffer. -@@ -437,9 +489,12 @@ WindowBackBuffer* WindowSurfaceWayland:: - // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260) - mWaylandBufferFullScreenDamage = true; - } else { -+ LOGWAYLAND(("%s [%p] Resize to [%d x %d]\n", __PRETTY_FUNCTION__, -+ (void*)this, aWidth, aHeight)); - // Former buffer has different size from the new request. Only resize - // the new buffer and leave gecko to render new whole content. - mWaylandBuffer->Resize(aWidth, aHeight); -+ mWaitToFullScreenUpdate = true; - } - - return mWaylandBuffer; -@@ -499,6 +554,10 @@ already_AddRefed<gfx::DrawTarget> Window - gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); - gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); - -+ LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n", -+ __PRETTY_FUNCTION__, (void*)this, lockSize.width, lockSize.height, -+ screenRect.width, lockSize.height)); -+ - // Are we asked for entire nsWindow to draw? - mDrawToWaylandBufferDirectly = - (aRegion.GetNumRects() == 1 && bounds.x == 0 && bounds.y == 0 && -@@ -510,6 +569,13 @@ already_AddRefed<gfx::DrawTarget> Window - LockWaylandBuffer(screenRect.width, screenRect.height, - mWindow->WaylandSurfaceNeedsClear()); - if (dt) { -+ // When we have a request to update whole screen at once -+ // (surface was created, resized or changed somehow) -+ // we also need update scale factor of the screen. -+ if (mWaitToFullScreenUpdate) { -+ mWaitToFullScreenUpdate = false; -+ mNeedScaleFactorUpdate = true; -+ } - return dt.forget(); - } - -@@ -576,6 +642,10 @@ static void WaylandBufferDelayCommitHand - void WindowSurfaceWayland::CommitWaylandBuffer() { - MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); - -+ if (mWaitToFullScreenUpdate) { -+ return; -+ } -+ - wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (!waylandSurface) { - // Target window is not created yet - delay the commit. This can happen only -@@ -619,6 +689,7 @@ void WindowSurfaceWayland::CommitWayland - LayoutDeviceIntRect rect = mWindow->GetBounds(); - wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height); - mWaylandBufferFullScreenDamage = false; -+ mNeedScaleFactorUpdate = true; - } else { - gint scaleFactor = mWindow->GdkScaleFactor(); - for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); -@@ -653,6 +724,18 @@ void WindowSurfaceWayland::CommitWayland - void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) { - MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); - -+#ifdef DEBUG -+ { -+ LayoutDeviceIntRect screenRect = mWindow->GetBounds(); -+ gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect(); -+ gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); -+ -+ LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n", -+ __PRETTY_FUNCTION__, (void*)this, lockSize.width, -+ lockSize.height, screenRect.width, lockSize.height)); -+ } -+#endif -+ - // We have new content at mImageSurface - copy data to mWaylandBuffer first. - if (!mDrawToWaylandBufferDirectly) { - CommitImageSurfaceToWaylandBuffer(aInvalidRegion); -diff -up firefox-66.0/widget/gtk/WindowSurfaceWayland.h.old firefox-66.0/widget/gtk/WindowSurfaceWayland.h ---- firefox-66.0/widget/gtk/WindowSurfaceWayland.h.old 2019-03-20 15:48:56.218949138 +0100 -+++ firefox-66.0/widget/gtk/WindowSurfaceWayland.h 2019-03-20 14:48:21.082035284 +0100 -@@ -46,7 +46,7 @@ class WindowBackBuffer { - already_AddRefed<gfx::DrawTarget> Lock(); - - void Attach(wl_surface* aSurface); -- void Detach(); -+ void Detach(wl_buffer* aBuffer); - bool IsAttached() { return mAttached; } - - void Clear(); -@@ -118,6 +118,7 @@ class WindowSurfaceWayland : public Wind - bool mWaylandBufferFullScreenDamage; - bool mIsMainThread; - bool mNeedScaleFactorUpdate; -+ bool mWaitToFullScreenUpdate; - }; - - } // namespace widget diff --git a/mozilla-1508378.patch b/mozilla-1508378.patch deleted file mode 100644 index bbbce4b..0000000 --- a/mozilla-1508378.patch +++ /dev/null @@ -1,92 +0,0 @@ -changeset: 468935:3b964face103 -tag: tip -user: Martin Stransky <stransky@redhat.com> -date: Wed Apr 10 15:14:32 2019 +0200 -summary: Bug 1508378 - Fix round error when damage rect size/position is odd number and scale factor is used, r=lsalzman - -diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp ---- a/widget/gtk/WindowSurfaceWayland.cpp -+++ b/widget/gtk/WindowSurfaceWayland.cpp -@@ -624,16 +624,33 @@ static void WaylandBufferDelayCommitHand - } else { - // Referenced WindowSurfaceWayland is already deleted. - // Do nothing but just release the mDelayedCommitHandle allocated at - // WindowSurfaceWayland::CommitWaylandBuffer(). - free(aSurface); - } - } - -+void WindowSurfaceWayland::CalcRectScale(LayoutDeviceIntRect& aRect, int aScale) { -+ if (aRect.x & 0x1) { -+ aRect.width += 1; -+ } -+ aRect.x = aRect.x / aScale; -+ -+ if (aRect.y & 0x1) { -+ aRect.height += 1; -+ } -+ aRect.y = aRect.y / aScale; -+ -+ aRect.width = (aRect.width & 0x1) ? aRect.width / aScale + 1 : -+ aRect.width / aScale; -+ aRect.height = (aRect.height & 0x1) ? aRect.height / aScale + 1 : -+ aRect.height / aScale; -+} -+ - void WindowSurfaceWayland::CommitWaylandBuffer() { - MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); - - if (mWaitToFullScreenUpdate) { - return; - } - - wl_surface* waylandSurface = mWindow->GetWaylandSurface(); -@@ -679,21 +696,23 @@ void WindowSurfaceWayland::CommitWayland - LayoutDeviceIntRect rect = mWindow->GetBounds(); - wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height); - mWaylandBufferFullScreenDamage = false; - mNeedScaleFactorUpdate = true; - } else { - gint scaleFactor = mWindow->GdkScaleFactor(); - for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); - iter.Next()) { -- const mozilla::LayoutDeviceIntRect& r = iter.Get(); -+ mozilla::LayoutDeviceIntRect r = iter.Get(); - // We need to remove the scale factor because the wl_surface_damage - // also multiplies by current scale factor. -- wl_surface_damage(waylandSurface, r.x / scaleFactor, r.y / scaleFactor, -- r.width / scaleFactor, r.height / scaleFactor); -+ if (scaleFactor > 1) { -+ CalcRectScale(r, scaleFactor); -+ } -+ wl_surface_damage(waylandSurface, r.x, r.y, r.width, r.height); - } - } - - // Clear all back buffer damage as we're committing - // all requested regions. - mWaylandBufferDamage.SetEmpty(); - - mFrameCallback = wl_surface_frame(waylandSurface); -diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h ---- a/widget/gtk/WindowSurfaceWayland.h -+++ b/widget/gtk/WindowSurfaceWayland.h -@@ -96,16 +96,17 @@ class WindowSurfaceWayland : public Wind - WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight); - - already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(int aWidth, int aHeight, - bool aClearBuffer); - already_AddRefed<gfx::DrawTarget> LockImageSurface( - const gfx::IntSize& aLockSize); - bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); - void CommitWaylandBuffer(); -+ void CalcRectScale(LayoutDeviceIntRect& aRect, int scale); - - // TODO: Do we need to hold a reference to nsWindow object? - nsWindow* mWindow; - nsWaylandDisplay* mWaylandDisplay; - WindowBackBuffer* mWaylandBuffer; - LayoutDeviceIntRegion mWaylandBufferDamage; - WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM]; - RefPtr<gfxImageSurface> mImageSurface; - diff --git a/mozilla-1517205.patch b/mozilla-1517205.patch deleted file mode 100644 index f200cbe..0000000 --- a/mozilla-1517205.patch +++ /dev/null @@ -1,209 +0,0 @@ -diff -up firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1517205 firefox-67.0/widget/gtk/mozcontainer.cpp ---- firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1517205 2019-05-15 16:00:23.366366060 +0200 -+++ firefox-67.0/widget/gtk/mozcontainer.cpp 2019-05-15 16:02:01.596967825 +0200 -@@ -567,8 +567,7 @@ struct wl_surface *moz_container_get_wl_ - moz_container_get_scale(container)); - - wl_surface_commit(container->surface); -- wl_display_flush(waylandDisplay->GetDisplay()); -- WaylandDisplayRelease(waylandDisplay); -+ wl_display_flush(waylandDisplay->GetDisplay()); - } - - return container->surface; -diff -up firefox-67.0/widget/gtk/nsClipboardWayland.cpp.mozilla-1517205 firefox-67.0/widget/gtk/nsClipboardWayland.cpp ---- firefox-67.0/widget/gtk/nsClipboardWayland.cpp.mozilla-1517205 2019-05-14 01:08:37.000000000 +0200 -+++ firefox-67.0/widget/gtk/nsClipboardWayland.cpp 2019-05-15 16:00:23.367366056 +0200 -@@ -639,7 +639,6 @@ static gboolean offer_hash_remove(gpoint - nsRetrievalContextWayland::~nsRetrievalContextWayland(void) { - g_hash_table_foreach_remove(mActiveOffers, offer_hash_remove, nullptr); - g_hash_table_destroy(mActiveOffers); -- WaylandDisplayRelease(mDisplay); - } - - GdkAtom *nsRetrievalContextWayland::GetTargets(int32_t aWhichClipboard, -diff -up firefox-67.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1517205 firefox-67.0/widget/gtk/nsWaylandDisplay.cpp ---- firefox-67.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1517205 2019-05-14 01:08:37.000000000 +0200 -+++ firefox-67.0/widget/gtk/nsWaylandDisplay.cpp 2019-05-15 16:00:23.368366052 +0200 -@@ -21,6 +21,13 @@ namespace widget { - static nsWaylandDisplay *gWaylandDisplays[MAX_DISPLAY_CONNECTIONS]; - static StaticMutex gWaylandDisplaysMutex; - -+static void ReleaseDisplaysAtExit() { -+ for (int i = 0; i < MAX_DISPLAY_CONNECTIONS; i++) { -+ delete gWaylandDisplays[i]; -+ gWaylandDisplays[i] = nullptr; -+ } -+} -+ - // Each thread which is using wayland connection (wl_display) has to operate - // its own wl_event_queue. Main Firefox thread wl_event_queue is handled - // by Gtk main loop, other threads/wl_event_queue has to be handled by us. -@@ -35,7 +42,6 @@ static nsWaylandDisplay *WaylandDisplayG - const StaticMutexAutoLock &) { - for (auto &display : gWaylandDisplays) { - if (display && display->Matches(aDisplay)) { -- NS_ADDREF(display); - return display; - } - } -@@ -43,7 +49,7 @@ static nsWaylandDisplay *WaylandDisplayG - for (auto &display : gWaylandDisplays) { - if (display == nullptr) { - display = new nsWaylandDisplay(aDisplay); -- NS_ADDREF(display); -+ atexit(ReleaseDisplaysAtExit); - return display; - } - } -@@ -67,26 +73,6 @@ nsWaylandDisplay *WaylandDisplayGet(GdkD - return WaylandDisplayGetLocked(display, lock); - } - --static bool WaylandDisplayReleaseLocked(nsWaylandDisplay *aDisplay, -- const StaticMutexAutoLock &) { -- for (auto &display : gWaylandDisplays) { -- if (display == aDisplay) { -- int rc = display->Release(); -- if (rc == 0) { -- display = nullptr; -- } -- return true; -- } -- } -- MOZ_ASSERT(false, "Missing nsWaylandDisplay for this thread!"); -- return false; --} -- --void WaylandDisplayRelease(nsWaylandDisplay *aDisplay) { -- StaticMutexAutoLock lock(gWaylandDisplaysMutex); -- WaylandDisplayReleaseLocked(aDisplay, lock); --} -- - static void WaylandDisplayLoopLocked(wl_display *aDisplay, - const StaticMutexAutoLock &) { - for (auto &display : gWaylandDisplays) { -@@ -130,6 +116,8 @@ static void global_registry_handler(void - uint32_t id, const char *interface, - uint32_t version) { - auto display = reinterpret_cast<nsWaylandDisplay *>(data); -+ if (!display) -+ return; - - if (strcmp(interface, "wl_shm") == 0) { - auto shm = static_cast<wl_shm *>( -@@ -180,9 +168,7 @@ bool nsWaylandDisplay::Matches(wl_displa - return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay; - } - --NS_IMPL_ISUPPORTS(nsWaylandDisplay, nsISupports); -- --nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay) -+nsWaylandDisplay::nsWaylandDisplay(wl_display* aDisplay) - : mThreadId(PR_GetCurrentThread()), - mDisplay(aDisplay), - mEventQueue(nullptr), -@@ -190,9 +176,10 @@ nsWaylandDisplay::nsWaylandDisplay(wl_di - mSubcompositor(nullptr), - mSeat(nullptr), - mShm(nullptr), -- mPrimarySelectionDeviceManager(nullptr) { -- wl_registry *registry = wl_display_get_registry(mDisplay); -- wl_registry_add_listener(registry, ®istry_listener, this); -+ mPrimarySelectionDeviceManager(nullptr), -+ mRegistry(nullptr) { -+ mRegistry = wl_display_get_registry(mDisplay); -+ wl_registry_add_listener(mRegistry, ®istry_listener, this); - - if (NS_IsMainThread()) { - // Use default event queue in main thread operated by Gtk+. -@@ -203,17 +190,19 @@ nsWaylandDisplay::nsWaylandDisplay(wl_di - mEventQueue = wl_display_create_queue(mDisplay); - MessageLoop::current()->PostTask(NewRunnableFunction( - "WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay)); -- wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue); -+ wl_proxy_set_queue((struct wl_proxy *)mRegistry, mEventQueue); - wl_display_roundtrip_queue(mDisplay, mEventQueue); - wl_display_roundtrip_queue(mDisplay, mEventQueue); - } - } - - nsWaylandDisplay::~nsWaylandDisplay() { -- MOZ_ASSERT(mThreadId == PR_GetCurrentThread()); - // Owned by Gtk+, we don't need to release - mDisplay = nullptr; - -+ wl_registry_destroy(mRegistry); -+ mRegistry = nullptr; -+ - if (mEventQueue) { - wl_event_queue_destroy(mEventQueue); - mEventQueue = nullptr; -diff -up firefox-67.0/widget/gtk/nsWaylandDisplay.h.mozilla-1517205 firefox-67.0/widget/gtk/nsWaylandDisplay.h ---- firefox-67.0/widget/gtk/nsWaylandDisplay.h.mozilla-1517205 2019-05-14 01:08:27.000000000 +0200 -+++ firefox-67.0/widget/gtk/nsWaylandDisplay.h 2019-05-15 16:00:23.368366052 +0200 -@@ -20,11 +20,10 @@ namespace widget { - - // Our general connection to Wayland display server, - // holds our display connection and runs event loop. --class nsWaylandDisplay : public nsISupports { -- NS_DECL_THREADSAFE_ISUPPORTS -- -+class nsWaylandDisplay { - public: - explicit nsWaylandDisplay(wl_display* aDisplay); -+ virtual ~nsWaylandDisplay(); - - bool DisplayLoop(); - bool Matches(wl_display* aDisplay); -@@ -41,7 +40,6 @@ class nsWaylandDisplay : public nsISuppo - return mPrimarySelectionDeviceManager; - }; - -- public: - void SetShm(wl_shm* aShm); - void SetSubcompositor(wl_subcompositor* aSubcompositor); - void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager); -@@ -49,9 +47,7 @@ class nsWaylandDisplay : public nsISuppo - void SetPrimarySelectionDeviceManager( - gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager); - -- private: -- virtual ~nsWaylandDisplay(); -- -+private: - PRThread* mThreadId; - wl_display* mDisplay; - wl_event_queue* mEventQueue; -@@ -60,10 +56,10 @@ class nsWaylandDisplay : public nsISuppo - wl_seat* mSeat; - wl_shm* mShm; - gtk_primary_selection_device_manager* mPrimarySelectionDeviceManager; -+ wl_registry *mRegistry; - }; - - nsWaylandDisplay* WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr); --void WaylandDisplayRelease(nsWaylandDisplay* aDisplay); - - } // namespace widget - } // namespace mozilla -diff -up firefox-67.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1517205 firefox-67.0/widget/gtk/WindowSurfaceWayland.cpp ---- firefox-67.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1517205 2019-05-15 16:00:23.335366185 +0200 -+++ firefox-67.0/widget/gtk/WindowSurfaceWayland.cpp 2019-05-15 16:00:23.368366052 +0200 -@@ -413,16 +413,6 @@ WindowSurfaceWayland::~WindowSurfaceWayl - delete mBackupBuffer[i]; - } - } -- -- if (!mIsMainThread) { -- // We can be destroyed from main thread even though we was created/used -- // in compositor thread. We have to unref/delete WaylandDisplay in -- // compositor thread then and we can't use MessageLoop::current() here. -- mDisplayThreadMessageLoop->PostTask(NewRunnableFunction( -- "WaylandDisplayRelease", &WaylandDisplayRelease, mWaylandDisplay)); -- } else { -- WaylandDisplayRelease(mWaylandDisplay); -- } - } - - WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, diff --git a/mozilla-1526243.patch b/mozilla-1526243.patch deleted file mode 100644 index 2d12378..0000000 --- a/mozilla-1526243.patch +++ /dev/null @@ -1,340 +0,0 @@ -changeset: 465480:a86f3560fb17 -parent: 465477:26d9b7ffbd6b -user: Martin Stransky <stransky@redhat.com> -date: Fri Mar 29 15:30:15 2019 +0100 -summary: Bug 1526243 - [Linux] Don't use nsGConfService in nsGNOMEShellService.cpp, r=glandium - -diff --git a/browser/components/shell/nsGNOMEShellService.cpp b/browser/components/shell/nsGNOMEShellService.cpp ---- a/browser/components/shell/nsGNOMEShellService.cpp -+++ b/browser/components/shell/nsGNOMEShellService.cpp -@@ -10,17 +10,16 @@ - #include "nsShellService.h" - #include "nsIServiceManager.h" - #include "nsIFile.h" - #include "nsIProperties.h" - #include "nsDirectoryServiceDefs.h" - #include "nsIPrefService.h" - #include "prenv.h" - #include "nsString.h" --#include "nsIGConfService.h" - #include "nsIGIOService.h" - #include "nsIGSettingsService.h" - #include "nsIStringBundle.h" - #include "nsIOutputStream.h" - #include "nsIProcess.h" - #include "nsServiceManagerUtils.h" - #include "nsComponentManagerUtils.h" - #include "nsIImageLoadingContent.h" -@@ -65,48 +64,39 @@ static const ProtocolAssociation appProt - - static const MimeTypeAssociation appTypes[] = { - // clang-format off - { "text/html", "htm html shtml" }, - { "application/xhtml+xml", "xhtml xht" } - // clang-format on - }; - --// GConf registry key constants --#define DG_BACKGROUND "/desktop/gnome/background" -- --#define kDesktopImageKey DG_BACKGROUND "/picture_filename" --#define kDesktopOptionsKey DG_BACKGROUND "/picture_options" --#define kDesktopDrawBGKey DG_BACKGROUND "/draw_background" --#define kDesktopColorKey DG_BACKGROUND "/primary_color" -- - #define kDesktopBGSchema "org.gnome.desktop.background" - #define kDesktopImageGSKey "picture-uri" - #define kDesktopOptionGSKey "picture-options" - #define kDesktopDrawBGGSKey "draw-background" - #define kDesktopColorGSKey "primary-color" - - static bool IsRunningAsASnap() { return (PR_GetEnv("SNAP") != nullptr); } - - nsresult nsGNOMEShellService::Init() { - nsresult rv; - - if (gfxPlatform::IsHeadless()) { - return NS_ERROR_NOT_AVAILABLE; - } - -- // GConf, GSettings or GIO _must_ be available, or we do not allow -+ // GSettings or GIO _must_ be available, or we do not allow - // CreateInstance to succeed. - -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - nsCOMPtr<nsIGSettingsService> gsettings = - do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); - -- if (!gconf && !giovfs && !gsettings) return NS_ERROR_NOT_AVAILABLE; -+ if (!giovfs && !gsettings) return NS_ERROR_NOT_AVAILABLE; - - // Check G_BROKEN_FILENAMES. If it's set, then filenames in glib use - // the locale encoding. If it's not set, they use UTF-8. - mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nullptr; - - if (GetAppPathFromLauncher()) return NS_OK; - - nsCOMPtr<nsIProperties> dirSvc( -@@ -212,35 +202,23 @@ nsGNOMEShellService::IsDefaultBrowser(bo - } - if (strcmp(output, "yes\n") == 0) { - *aIsDefaultBrowser = true; - } - g_free(output); - return NS_OK; - } - -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); -- -- bool enabled; - nsAutoCString handler; - nsCOMPtr<nsIGIOMimeApp> gioApp; - - for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) { - if (!appProtocols[i].essential) continue; - -- if (gconf) { -- handler.Truncate(); -- gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name), -- &enabled, handler); -- -- if (!CheckHandlerMatchesAppName(handler) || !enabled) -- return NS_OK; // the handler is disabled or set to another app -- } -- - if (giovfs) { - handler.Truncate(); - nsCOMPtr<nsIHandlerApp> handlerApp; - giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name), - getter_AddRefs(handlerApp)); - gioApp = do_QueryInterface(handlerApp); - if (!gioApp) return NS_OK; - -@@ -270,39 +248,17 @@ nsGNOMEShellService::SetDefaultBrowser(b - GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH | - G_SPAWN_STDOUT_TO_DEV_NULL | - G_SPAWN_STDERR_TO_DEV_NULL); - g_spawn_sync(nullptr, (gchar **)argv, nullptr, flags, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr); - return NS_OK; - } - -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); -- if (gconf) { -- nsAutoCString appKeyValue; -- if (mAppIsInPath) { -- // mAppPath is in the users path, so use only the basename as the launcher -- gchar *tmp = g_path_get_basename(mAppPath.get()); -- appKeyValue = tmp; -- g_free(tmp); -- } else { -- appKeyValue = mAppPath; -- } -- -- appKeyValue.AppendLiteral(" %s"); -- -- for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) { -- if (appProtocols[i].essential || aClaimAllTypes) { -- gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name), -- appKeyValue); -- } -- } -- } -- - if (giovfs) { - nsresult rv; - nsCOMPtr<nsIStringBundleService> bundleService = - do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIStringBundle> brandBundle; - rv = bundleService->CreateBundle(BRAND_PROPERTIES, -@@ -353,19 +309,21 @@ nsGNOMEShellService::SetDefaultBrowser(b - } - - return NS_OK; - } - - NS_IMETHODIMP - nsGNOMEShellService::GetCanSetDesktopBackground(bool *aResult) { - // setting desktop background is currently only supported -- // for Gnome or desktops using the same GSettings and GConf keys -- const char *gnomeSession = getenv("GNOME_DESKTOP_SESSION_ID"); -- if (gnomeSession) { -+ // for Gnome or desktops using the same GSettings keys -+ const char *currentDesktop = getenv("XDG_CURRENT_DESKTOP"); -+ if (currentDesktop && -+ (strstr(currentDesktop, "GNOME-Flashback:GNOME") != nullptr || -+ strstr(currentDesktop, "GNOME") != nullptr)) { - *aResult = true; - } else { - *aResult = false; - } - - return NS_OK; - } - -@@ -439,20 +397,16 @@ nsGNOMEShellService::SetDesktopBackgroun - filePath.Append('/'); - filePath.Append(NS_ConvertUTF16toUTF8(brandName)); - filePath.AppendLiteral("_wallpaper.png"); - - // write the image to a file in the home dir - rv = WriteImage(filePath, container); - NS_ENSURE_SUCCESS(rv, rv); - -- // Try GSettings first. If we don't have GSettings or the right schema, fall -- // back to using GConf instead. Note that if GSettings works ok, the changes -- // get mirrored to GConf by the gsettings->gconf bridge in -- // gnome-settings-daemon - nsCOMPtr<nsIGSettingsService> gsettings = - do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); - if (gsettings) { - nsCOMPtr<nsIGSettingsCollection> background_settings; - gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(kDesktopBGSchema), - getter_AddRefs(background_settings)); - if (background_settings) { - gchar *file_uri = g_filename_to_uri(filePath.get(), nullptr, nullptr); -@@ -465,32 +419,17 @@ nsGNOMEShellService::SetDesktopBackgroun - nsDependentCString(file_uri)); - g_free(file_uri); - background_settings->SetBoolean(NS_LITERAL_CSTRING(kDesktopDrawBGGSKey), - true); - return rv; - } - } - -- // if the file was written successfully, set it as the system wallpaper -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- -- if (gconf) { -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); -- -- // Set the image to an empty string first to force a refresh -- // (since we could be writing a new image on top of an existing -- // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), EmptyCString()); -- -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath); -- gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), true); -- } -- -- return rv; -+ return NS_ERROR_FAILURE; - } - - #define COLOR_16_TO_8_BIT(_c) ((_c) >> 8) - #define COLOR_8_TO_16_BIT(_c) ((_c) << 8 | (_c)) - - NS_IMETHODIMP - nsGNOMEShellService::GetDesktopBackgroundColor(uint32_t *aColor) { - nsCOMPtr<nsIGSettingsService> gsettings = -@@ -502,22 +441,16 @@ nsGNOMEShellService::GetDesktopBackgroun - gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(kDesktopBGSchema), - getter_AddRefs(background_settings)); - if (background_settings) { - background_settings->GetString(NS_LITERAL_CSTRING(kDesktopColorGSKey), - background); - } - } - -- if (!background_settings) { -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- if (gconf) -- gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); -- } -- - if (background.IsEmpty()) { - *aColor = 0; - return NS_OK; - } - - GdkColor color; - gboolean success = gdk_color_parse(background.get(), &color); - -@@ -555,23 +488,17 @@ nsGNOMEShellService::SetDesktopBackgroun - getter_AddRefs(background_settings)); - if (background_settings) { - background_settings->SetString(NS_LITERAL_CSTRING(kDesktopColorGSKey), - colorString); - return NS_OK; - } - } - -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- -- if (gconf) { -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); -- } -- -- return NS_OK; -+ return NS_ERROR_FAILURE; - } - - NS_IMETHODIMP - nsGNOMEShellService::OpenApplication(int32_t aApplication) { - nsAutoCString scheme; - if (aApplication == APPLICATION_MAIL) - scheme.AssignLiteral("mailto"); - else if (aApplication == APPLICATION_NEWS) -@@ -581,55 +508,17 @@ nsGNOMEShellService::OpenApplication(int - - nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (giovfs) { - nsCOMPtr<nsIHandlerApp> handlerApp; - giovfs->GetAppForURIScheme(scheme, getter_AddRefs(handlerApp)); - if (handlerApp) return handlerApp->LaunchWithURI(nullptr, nullptr); - } - -- nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- if (!gconf) return NS_ERROR_FAILURE; -- -- bool enabled; -- nsAutoCString appCommand; -- gconf->GetAppForProtocol(scheme, &enabled, appCommand); -- -- if (!enabled) return NS_ERROR_FAILURE; -- -- // XXX we don't currently handle launching a terminal window. -- // If the handler requires a terminal, bail. -- bool requiresTerminal; -- gconf->HandlerRequiresTerminal(scheme, &requiresTerminal); -- if (requiresTerminal) return NS_ERROR_FAILURE; -- -- // Perform shell argument expansion -- int argc; -- char **argv; -- if (!g_shell_parse_argv(appCommand.get(), &argc, &argv, nullptr)) -- return NS_ERROR_FAILURE; -- -- char **newArgv = new char *[argc + 1]; -- int newArgc = 0; -- -- // Run through the list of arguments. Copy all of them to the new -- // argv except for %s, which we skip. -- for (int i = 0; i < argc; ++i) { -- if (strcmp(argv[i], "%s") != 0) newArgv[newArgc++] = argv[i]; -- } -- -- newArgv[newArgc] = nullptr; -- -- gboolean err = g_spawn_async(nullptr, newArgv, nullptr, G_SPAWN_SEARCH_PATH, -- nullptr, nullptr, nullptr, nullptr); -- -- g_strfreev(argv); -- delete[] newArgv; -- -- return err ? NS_OK : NS_ERROR_FAILURE; -+ return NS_ERROR_FAILURE; - } - - NS_IMETHODIMP - nsGNOMEShellService::OpenApplicationWithURI(nsIFile *aApplication, - const nsACString &aURI) { - nsresult rv; - nsCOMPtr<nsIProcess> process = - do_CreateInstance("@mozilla.org/process/util;1", &rv); - diff --git a/mozilla-1532643-popup.patch b/mozilla-1532643-popup.patch deleted file mode 100644 index 3b870a2..0000000 --- a/mozilla-1532643-popup.patch +++ /dev/null @@ -1,71 +0,0 @@ -diff -up firefox-67.0/layout/xul/moz.build.mozilla-1532643-popup firefox-67.0/layout/xul/moz.build ---- firefox-67.0/layout/xul/moz.build.mozilla-1532643-popup 2019-05-14 01:08:24.000000000 +0200 -+++ firefox-67.0/layout/xul/moz.build 2019-05-15 15:31:39.714299754 +0200 -@@ -88,3 +88,6 @@ LOCAL_INCLUDES += [ - - if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-error=shadow'] -+ -+CFLAGS += CONFIG['TK_CFLAGS'] -+CXXFLAGS += CONFIG['TK_CFLAGS'] -diff -up firefox-67.0/layout/xul/nsMenuPopupFrame.cpp.mozilla-1532643-popup firefox-67.0/layout/xul/nsMenuPopupFrame.cpp ---- firefox-67.0/layout/xul/nsMenuPopupFrame.cpp.mozilla-1532643-popup 2019-05-14 01:08:24.000000000 +0200 -+++ firefox-67.0/layout/xul/nsMenuPopupFrame.cpp 2019-05-15 15:37:01.121215863 +0200 -@@ -55,6 +55,10 @@ - #include "mozilla/dom/KeyboardEvent.h" - #include "mozilla/dom/KeyboardEventBinding.h" - #include <algorithm> -+#ifdef MOZ_WAYLAND -+#include <gdk/gdk.h> -+#include <gdk/gdkx.h> -+#endif /* MOZ_WAYLAND */ - - using namespace mozilla; - using mozilla::dom::Document; -@@ -301,11 +305,29 @@ nsresult nsMenuPopupFrame::CreateWidgetF - !(mode == eTransparencyTransparent || tag == nsGkAtoms::menulist); - widgetData.mPopupLevel = PopupLevel(widgetData.mNoAutoHide); - -+ static bool waylandBackend = -+#ifdef MOZ_WAYLAND -+ !GDK_IS_X11_DISPLAY(gdk_display_get_default()); -+#else -+ false; -+#endif -+ - // panels which have a parent level need a parent widget. This allows them to - // always appear in front of the parent window but behind other windows that - // should be in front of it. - nsCOMPtr<nsIWidget> parentWidget; -- if (widgetData.mPopupLevel != ePopupLevelTop) { -+ if (waylandBackend) { -+ // On Wayland we always need to connect menu to its parent menu widget -+ // otherwise it's not shown. -+ nsMenuFrame* menuFrame = do_QueryFrame(GetParent()); -+ if (menuFrame) { -+ nsMenuParent* parentPopup = menuFrame->GetMenuParent(); -+ if (parentPopup && parentPopup->IsMenu()) { -+ parentWidget = -+ static_cast<nsMenuPopupFrame*>(parentPopup)->GetWidget(); -+ } -+ } -+ } else if (widgetData.mPopupLevel != ePopupLevelTop) { - nsCOMPtr<nsIDocShellTreeItem> dsti = PresContext()->GetDocShell(); - if (!dsti) return NS_ERROR_FAILURE; - -diff -up firefox-67.0/widget/gtk/nsWindow.cpp.mozilla-1532643-popup firefox-67.0/widget/gtk/nsWindow.cpp ---- firefox-67.0/widget/gtk/nsWindow.cpp.mozilla-1532643-popup 2019-05-15 15:31:39.712299764 +0200 -+++ firefox-67.0/widget/gtk/nsWindow.cpp 2019-05-15 15:31:39.716299744 +0200 -@@ -3527,11 +3527,7 @@ nsresult nsWindow::Create(nsIWidget *aPa - } else { - switch (aInitData->mPopupHint) { - case ePopupTypeMenu: -- // Use GDK_WINDOW_TYPE_HINT_UTILITY on Wayland which -- // guides Gtk to create the popup as subsurface -- // instead of xdg_shell popup (see Bug 1423598). -- gtkTypeHint = mIsX11Display ? GDK_WINDOW_TYPE_HINT_POPUP_MENU -- : GDK_WINDOW_TYPE_HINT_UTILITY; -+ gtkTypeHint = GDK_WINDOW_TYPE_HINT_POPUP_MENU; - break; - case ePopupTypeTooltip: - gtkTypeHint = GDK_WINDOW_TYPE_HINT_TOOLTIP; diff --git a/mozilla-1535567.patch b/mozilla-1535567.patch deleted file mode 100644 index 43b606c..0000000 --- a/mozilla-1535567.patch +++ /dev/null @@ -1,136 +0,0 @@ -diff -up firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1535567 firefox-67.0/widget/gtk/mozcontainer.cpp ---- firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1535567 2019-05-14 01:08:37.000000000 +0200 -+++ firefox-67.0/widget/gtk/mozcontainer.cpp 2019-05-15 15:56:19.645336209 +0200 -@@ -157,6 +157,7 @@ void moz_container_init(MozContainer *co - container->subsurface = nullptr; - container->eglwindow = nullptr; - container->frame_callback_handler = nullptr; -+ container->frame_callback_handler_surface_id = -1; - // We can draw to x11 window any time. - container->ready_to_draw = GDK_IS_X11_DISPLAY(gdk_display_get_default()); - container->surface_needs_clear = true; -@@ -165,6 +166,11 @@ void moz_container_init(MozContainer *co - } - - #if defined(MOZ_WAYLAND) -+void moz_container_set_initial_draw_callback( -+ MozContainer *container, std::function<void(void)> inital_draw_cb) { -+ container->inital_draw_cb = inital_draw_cb; -+} -+ - static wl_surface *moz_container_get_gtk_container_surface( - MozContainer *container) { - static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *)) -@@ -178,37 +184,61 @@ static void frame_callback_handler(void - uint32_t time) { - MozContainer *container = MOZ_CONTAINER(data); - g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy); -+ container->frame_callback_handler_surface_id = -1; - if (!container->ready_to_draw && container->inital_draw_cb) { - container->inital_draw_cb(); - } - container->ready_to_draw = true; - } - --void moz_container_set_initial_draw_callback( -- MozContainer *container, std::function<void(void)> inital_draw_cb) { -- container->inital_draw_cb = inital_draw_cb; --} -- - static const struct wl_callback_listener frame_listener = { - frame_callback_handler}; - --static gboolean moz_container_map_wayland(GtkWidget *widget, -- GdkEventAny *event) { -- MozContainer *container = MOZ_CONTAINER(widget); -- -- if (container->ready_to_draw || container->frame_callback_handler) { -- return FALSE; -- } -- -+static void moz_container_request_parent_frame_callback( -+ MozContainer *container) { - wl_surface *gtk_container_surface = - moz_container_get_gtk_container_surface(container); -+ int gtk_container_surface_id = -+ gtk_container_surface -+ ? wl_proxy_get_id((struct wl_proxy *)gtk_container_surface) -+ : -1; -+ -+ -+ -+ -+ -+ -+ -+ if (container->frame_callback_handler && -+ container->frame_callback_handler_surface_id == -+ gtk_container_surface_id) { -+ return; -+ } -+ -+ // If there's pending frame callback, delete it. -+ if (container->frame_callback_handler) { -+ g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy); -+ } - - if (gtk_container_surface) { -+ container->frame_callback_handler_surface_id = gtk_container_surface_id; - container->frame_callback_handler = wl_surface_frame(gtk_container_surface); - wl_callback_add_listener(container->frame_callback_handler, &frame_listener, - container); -+ } else { -+ container->frame_callback_handler_surface_id = -1; -+ } -+} -+ -+static gboolean moz_container_map_wayland(GtkWidget *widget, -+ GdkEventAny *event) { -+ MozContainer *container = MOZ_CONTAINER(widget); -+ -+ if (container->ready_to_draw) { -+ return FALSE; - } - -+ moz_container_request_parent_frame_callback(MOZ_CONTAINER(widget)); - return FALSE; - } - -@@ -217,6 +247,7 @@ static void moz_container_unmap_wayland( - g_clear_pointer(&container->subsurface, wl_subsurface_destroy); - g_clear_pointer(&container->surface, wl_surface_destroy); - g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy); -+ container->frame_callback_handler_surface_id = -1; - - container->surface_needs_clear = true; - container->ready_to_draw = false; -@@ -329,6 +360,10 @@ void moz_container_realize(GtkWidget *wi - : gtk_widget_get_visual(widget); - - window = gdk_window_new(parent, &attributes, attributes_mask); -+ -+ -+ -+ - gdk_window_set_user_data(window, widget); - } else { - window = parent; -@@ -498,6 +533,7 @@ static void moz_container_add(GtkContain - struct wl_surface *moz_container_get_wl_surface(MozContainer *container) { - if (!container->surface) { - if (!container->ready_to_draw) { -+ moz_container_request_parent_frame_callback(container); - return nullptr; - } - GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container)); -diff -up firefox-67.0/widget/gtk/mozcontainer.h.mozilla-1535567 firefox-67.0/widget/gtk/mozcontainer.h ---- firefox-67.0/widget/gtk/mozcontainer.h.mozilla-1535567 2019-05-14 01:08:37.000000000 +0200 -+++ firefox-67.0/widget/gtk/mozcontainer.h 2019-05-15 15:50:59.440570372 +0200 -@@ -77,6 +77,7 @@ struct _MozContainer { - struct wl_subsurface *subsurface; - struct wl_egl_window *eglwindow; - struct wl_callback *frame_callback_handler; -+ int frame_callback_handler_surface_id; - gboolean surface_needs_clear; - gboolean ready_to_draw; - std::function<void(void)> inital_draw_cb; diff --git a/mozilla-1539471.patch b/mozilla-1539471.patch deleted file mode 100644 index 1a321d2..0000000 --- a/mozilla-1539471.patch +++ /dev/null @@ -1,206 +0,0 @@ -diff -up firefox-66.0.1/widget/gtk/nsWindow.cpp.mozilla-1539471 firefox-66.0.1/widget/gtk/nsWindow.cpp ---- firefox-66.0.1/widget/gtk/nsWindow.cpp.mozilla-1539471 2019-03-28 14:08:42.351128620 +0100 -+++ firefox-66.0.1/widget/gtk/nsWindow.cpp 2019-03-28 14:20:23.282890178 +0100 -@@ -312,6 +312,9 @@ static nsWindow *gFocusWindow = nullptr; - static bool gBlockActivateEvent = false; - static bool gGlobalsInitialized = false; - static bool gRaiseWindows = true; -+#ifdef MOZ_WAYLAND -+static GList *gCurrentPopupWindows = nullptr; -+#endif - - #if GTK_CHECK_VERSION(3, 4, 0) - static uint32_t gLastTouchID = 0; -@@ -1136,8 +1139,16 @@ void nsWindow::NativeMoveResizeWaylandPo - return; - } - -- GtkWidget* parentWidget = -- GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); -+ GtkWidget *parentWidget; -+ if (mPopupType == ePopupTypeTooltip && gCurrentPopupWindows) { -+ // Attach tooltip window to the latest popup window -+ // to have both visible. -+ parentWidget = GTK_WIDGET(gCurrentPopupWindows->data); -+ gtk_window_set_transient_for(GTK_WINDOW(mShell), -+ GTK_WINDOW(parentWidget)); -+ } else { -+ parentWidget = GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); -+ } - - int x_parent, y_parent; - gdk_window_get_origin(gtk_widget_get_window(parentWidget), &x_parent, &y_parent); -@@ -3489,7 +3500,7 @@ nsresult nsWindow::Create(nsIWidget *aPa - gtkTypeHint = GDK_WINDOW_TYPE_HINT_DND; - mIsDragPopup = true; - } else { -- switch (aInitData->mPopupHint) { -+ switch (mPopupType) { - case ePopupTypeMenu: - gtkTypeHint = GDK_WINDOW_TYPE_HINT_POPUP_MENU; - break; -@@ -3610,6 +3621,8 @@ nsresult nsWindow::Create(nsIWidget *aPa - return NS_ERROR_FAILURE; - - case eWindowType_child: { -+ MOZ_ASSERT(mIsX11Display, -+ "eWindowType_child is not supported on Wayland!"); - if (parentMozContainer) { - mGdkWindow = CreateGdkWindow(parentGdkWindow, parentMozContainer); - mHasMappedToplevel = parentnsWindow->mHasMappedToplevel; -@@ -3979,6 +3992,49 @@ void nsWindow::NativeMoveResize() { - } - } - -+#ifdef MOZ_WAYLAND -+void nsWindow::OpenToplevelWaylandWindow() { -+ // Wayland keeps strong popup window hierarchy. We need to track active -+ // (visible) popup windows and make sure we hide popup on the same level -+ // before we open another one on that level. It means that every open -+ // popup needs to have an unique parent. -+ if (mWindowType == eWindowType_popup) { -+ GtkWidget *parentWidget = -+ GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell))); -+ -+ if (gCurrentPopupWindows) { -+ do { -+ GtkWidget *widget = GTK_WIDGET(gCurrentPopupWindows->data); -+ if (widget == parentWidget) { -+ break; -+ } -+ nsWindow* window = get_window_for_gtk_widget(widget); -+ NS_ASSERTION(window, "Unknown window in popup widget list!"); -+ window->CloseToplevelWaylandWindow(); -+ -+ } while (gCurrentPopupWindows != nullptr); -+ } -+ gCurrentPopupWindows = g_list_prepend(gCurrentPopupWindows, mShell); -+ } -+ -+ gtk_widget_show(mShell); -+} -+ -+void nsWindow::CloseToplevelWaylandWindow() { -+ if (mContainer && moz_container_has_wl_egl_window(mContainer)) { -+ // Because wl_egl_window is destroyed on moz_container_unmap(), -+ // the current compositor cannot use it anymore. To avoid crash, -+ // destroy the compositor & recreate a new compositor on next -+ // expose event. -+ DestroyLayerManager(); -+ } -+ if (mWindowType == eWindowType_popup) { -+ gCurrentPopupWindows = g_list_remove(gCurrentPopupWindows, mShell); -+ } -+ gtk_widget_hide(mShell); -+} -+#endif -+ - void nsWindow::NativeShow(bool aAction) { - if (aAction) { - // unset our flag now that our window has been shown -@@ -3990,51 +4046,55 @@ void nsWindow::NativeShow(bool aAction) - SetUserTimeAndStartupIDForActivatedWindow(mShell); - } - -- gtk_widget_show(mShell); -+#ifdef MOZ_WAYLAND -+ if (!mIsX11Display) { -+ OpenToplevelWaylandWindow(); -+ } else -+#endif -+ { -+ gtk_widget_show(mShell); -+ } - } else if (mContainer) { - gtk_widget_show(GTK_WIDGET(mContainer)); - } else if (mGdkWindow) { - gdk_window_show_unraised(mGdkWindow); - } - } else { --#ifdef MOZ_WAYLAND -- if (mContainer && moz_container_has_wl_egl_window(mContainer)) { -- // Because wl_egl_window is destroyed on moz_container_unmap(), -- // the current compositor cannot use it anymore. To avoid crash, -- // destroy the compositor & recreate a new compositor on next -- // expose event. -- DestroyLayerManager(); -- } --#endif -- - if (mIsTopLevel) { -- // Workaround window freezes on GTK versions before 3.21.2 by -- // ensuring that configure events get dispatched to windows before -- // they are unmapped. See bug 1225044. -- if (gtk_check_version(3, 21, 2) != nullptr && mPendingConfigures > 0) { -- GtkAllocation allocation; -- gtk_widget_get_allocation(GTK_WIDGET(mShell), &allocation); -- -- GdkEventConfigure event; -- PodZero(&event); -- event.type = GDK_CONFIGURE; -- event.window = mGdkWindow; -- event.send_event = TRUE; -- event.x = allocation.x; -- event.y = allocation.y; -- event.width = allocation.width; -- event.height = allocation.height; -- -- auto shellClass = GTK_WIDGET_GET_CLASS(mShell); -- for (unsigned int i = 0; i < mPendingConfigures; i++) { -- Unused << shellClass->configure_event(mShell, &event); -+#ifdef MOZ_WAYLAND -+ if (!mIsX11Display) { -+ CloseToplevelWaylandWindow(); -+ } else -+#endif -+ { -+ // Workaround window freezes on GTK versions before 3.21.2 by -+ // ensuring that configure events get dispatched to windows before -+ // they are unmapped. See bug 1225044. -+ if (gtk_check_version(3, 21, 2) != nullptr && mPendingConfigures > 0) { -+ GtkAllocation allocation; -+ gtk_widget_get_allocation(GTK_WIDGET(mShell), &allocation); -+ -+ GdkEventConfigure event; -+ PodZero(&event); -+ event.type = GDK_CONFIGURE; -+ event.window = mGdkWindow; -+ event.send_event = TRUE; -+ event.x = allocation.x; -+ event.y = allocation.y; -+ event.width = allocation.width; -+ event.height = allocation.height; -+ -+ auto shellClass = GTK_WIDGET_GET_CLASS(mShell); -+ for (unsigned int i = 0; i < mPendingConfigures; i++) { -+ Unused << shellClass->configure_event(mShell, &event); -+ } -+ mPendingConfigures = 0; - } -- mPendingConfigures = 0; -- } - -- gtk_widget_hide(mShell); -+ gtk_widget_hide(mShell); - -- ClearTransparencyBitmap(); // Release some resources -+ ClearTransparencyBitmap(); // Release some resources -+ } - } else if (mContainer) { - gtk_widget_hide(GTK_WIDGET(mContainer)); - } else if (mGdkWindow) { -diff -up firefox-66.0.1/widget/gtk/nsWindow.h.mozilla-1539471 firefox-66.0.1/widget/gtk/nsWindow.h ---- firefox-66.0.1/widget/gtk/nsWindow.h.mozilla-1539471 2019-03-28 14:08:42.345128639 +0100 -+++ firefox-66.0.1/widget/gtk/nsWindow.h 2019-03-28 14:08:42.355128607 +0100 -@@ -603,6 +603,11 @@ class nsWindow final : public nsBaseWidg - - void ForceTitlebarRedraw(); - -+#ifdef MOZ_WAYLAND -+ void OpenToplevelWaylandWindow(); -+ void CloseToplevelWaylandWindow(); -+#endif -+ - /** - * |mIMContext| takes all IME related stuff. - * diff --git a/mozilla-1540145.patch b/mozilla-1540145.patch deleted file mode 100644 index 755aa13..0000000 --- a/mozilla-1540145.patch +++ /dev/null @@ -1,156 +0,0 @@ -diff -up firefox-67.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.mozilla-1540145 firefox-67.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp ---- firefox-67.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.mozilla-1540145 2019-05-14 01:08:35.000000000 +0200 -+++ firefox-67.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2019-05-15 15:20:13.365502186 +0200 -@@ -34,16 +34,10 @@ class nsUnixSystemProxySettings final : - private: - ~nsUnixSystemProxySettings() = default; - -- nsCOMPtr<nsIGConfService> mGConf; -- nsCOMPtr<nsIGSettingsService> mGSettings; -+ nsCOMPtr<nsIGSettingsService> mGSettings; - nsCOMPtr<nsIGSettingsCollection> mProxySettings; - nsInterfaceHashtable<nsCStringHashKey, nsIGSettingsCollection> - mSchemeProxySettings; -- bool IsProxyMode(const char* aMode); -- nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, -- nsACString& aResult); -- nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, -- int32_t aPort, nsACString& aResult); - nsresult GetProxyFromGSettings(const nsACString& aScheme, - const nsACString& aHost, int32_t aPort, - nsACString& aResult); -@@ -68,16 +62,6 @@ void nsUnixSystemProxySettings::Init() { - NS_LITERAL_CSTRING("org.gnome.system.proxy"), - getter_AddRefs(mProxySettings)); - } -- if (!mProxySettings) { -- mGConf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- } --} -- --bool nsUnixSystemProxySettings::IsProxyMode(const char* aMode) { -- nsAutoCString mode; -- return NS_SUCCEEDED(mGConf->GetString( -- NS_LITERAL_CSTRING("/system/proxy/mode"), mode)) && -- mode.EqualsASCII(aMode); - } - - nsresult nsUnixSystemProxySettings::GetPACURI(nsACString& aResult) { -@@ -92,14 +76,8 @@ nsresult nsUnixSystemProxySettings::GetP - } - /* The org.gnome.system.proxy schema has been found, but auto mode is not - * set. Don't try the GConf and return empty string. */ -- aResult.Truncate(); -- return NS_OK; - } - -- if (mGConf && IsProxyMode("auto")) { -- return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"), -- aResult); -- } - // Return an empty string when auto mode is not set. - aResult.Truncate(); - return NS_OK; -@@ -217,30 +195,6 @@ static nsresult GetProxyFromEnvironment( - return NS_OK; - } - --nsresult nsUnixSystemProxySettings::SetProxyResultFromGConf( -- const char* aKeyBase, const char* aType, nsACString& aResult) { -- nsAutoCString hostKey; -- hostKey.AppendASCII(aKeyBase); -- hostKey.AppendLiteral("host"); -- nsAutoCString host; -- nsresult rv = mGConf->GetString(hostKey, host); -- NS_ENSURE_SUCCESS(rv, rv); -- if (host.IsEmpty()) return NS_ERROR_FAILURE; -- -- nsAutoCString portKey; -- portKey.AppendASCII(aKeyBase); -- portKey.AppendLiteral("port"); -- int32_t port; -- rv = mGConf->GetInt(portKey, &port); -- NS_ENSURE_SUCCESS(rv, rv); -- -- /* When port is 0, proxy is not considered as enabled even if host is set. */ -- if (port == 0) return NS_ERROR_FAILURE; -- -- SetProxyResult(aType, host, port, aResult); -- return NS_OK; --} -- - nsresult nsUnixSystemProxySettings::SetProxyResultFromGSettings( - const char* aKeyBase, const char* aType, nsACString& aResult) { - nsDependentCString key(aKeyBase); -@@ -366,63 +320,6 @@ static bool HostIgnoredByProxy(const nsA - return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0; - } - --nsresult nsUnixSystemProxySettings::GetProxyFromGConf(const nsACString& aScheme, -- const nsACString& aHost, -- int32_t aPort, -- nsACString& aResult) { -- bool masterProxySwitch = false; -- mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_http_proxy"), -- &masterProxySwitch); -- // if no proxy is set in GConf return NS_ERROR_FAILURE -- if (!(IsProxyMode("manual") || masterProxySwitch)) { -- return NS_ERROR_FAILURE; -- } -- -- nsCOMPtr<nsIArray> ignoreList; -- if (NS_SUCCEEDED(mGConf->GetStringList( -- NS_LITERAL_CSTRING("/system/http_proxy/ignore_hosts"), -- getter_AddRefs(ignoreList))) && -- ignoreList) { -- uint32_t len = 0; -- ignoreList->GetLength(&len); -- for (uint32_t i = 0; i < len; ++i) { -- nsCOMPtr<nsISupportsString> str = do_QueryElementAt(ignoreList, i); -- if (str) { -- nsAutoString s; -- if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) { -- if (HostIgnoredByProxy(NS_ConvertUTF16toUTF8(s), aHost)) { -- aResult.AppendLiteral("DIRECT"); -- return NS_OK; -- } -- } -- } -- } -- } -- -- bool useHttpProxyForAll = false; -- // This setting sometimes doesn't exist, don't bail on failure -- mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_same_proxy"), -- &useHttpProxyForAll); -- -- nsresult rv; -- if (!useHttpProxyForAll) { -- rv = SetProxyResultFromGConf("/system/proxy/socks_", "SOCKS", aResult); -- if (NS_SUCCEEDED(rv)) return rv; -- } -- -- if (aScheme.LowerCaseEqualsLiteral("http") || useHttpProxyForAll) { -- rv = SetProxyResultFromGConf("/system/http_proxy/", "PROXY", aResult); -- } else if (aScheme.LowerCaseEqualsLiteral("https")) { -- rv = SetProxyResultFromGConf("/system/proxy/secure_", "PROXY", aResult); -- } else if (aScheme.LowerCaseEqualsLiteral("ftp")) { -- rv = SetProxyResultFromGConf("/system/proxy/ftp_", "PROXY", aResult); -- } else { -- rv = NS_ERROR_FAILURE; -- } -- -- return rv; --} -- - nsresult nsUnixSystemProxySettings::GetProxyFromGSettings( - const nsACString& aScheme, const nsACString& aHost, int32_t aPort, - nsACString& aResult) { -@@ -494,7 +391,6 @@ nsresult nsUnixSystemProxySettings::GetP - nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); - if (NS_SUCCEEDED(rv)) return rv; - } -- if (mGConf) return GetProxyFromGConf(aScheme, aHost, aPort, aResult); - - return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); - } diff --git a/mozilla-1552590.patch b/mozilla-1552590.patch deleted file mode 100644 index 58d5b18..0000000 --- a/mozilla-1552590.patch +++ /dev/null @@ -1,2701 +0,0 @@ -changeset: 474982:24c0dda573b3 -parent: 474915:839cdad764d7 -user: Martin Stransky <stransky@redhat.com> -date: Fri May 17 11:24:33 2019 +0200 -summary: Implement dmabuf surfaces - -diff --git a/gfx/2d/WaylandDMABufSurface.cpp b/gfx/2d/WaylandDMABufSurface.cpp -new file mode 100644 ---- /dev/null -+++ b/gfx/2d/WaylandDMABufSurface.cpp -@@ -0,0 +1,274 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -+/* 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/. */ -+ -+// Based on weston/simple-dmabuf-egl.c -+ -+#include "WaylandDMABufSurface.h" -+ -+#include <fcntl.h> -+#include <getopt.h> -+#include <signal.h> -+#include <stdbool.h> -+#include <stdint.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <unistd.h> -+#include <sys/time.h> -+#include <dlfcn.h> -+ -+#include <gbm.h> -+ -+using namespace mozilla; -+using namespace mozilla::widget; -+ -+#ifndef DRM_FORMAT_MOD_INVALID -+# define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) -+#endif -+#define BUFFER_FLAGS 0 -+ -+bool WaylandDMABufSurface::mAvailable = false; -+bool WaylandDMABufSurface::mInitialized = false; -+ -+bool WaylandDMABufSurface::IsAvailable() { -+ if (!mInitialized) { -+ mInitialized = true; -+ if (!nsGbmLib::IsAvailable()) { -+ return false; -+ } -+ -+ // Test Alpha and non-alpha formats -+ nsWaylandDisplay* display = WaylandDisplayGet(); -+ if (!display->GetGbmFormat(false) || !display->GetGbmFormat(true)) { -+ return false; -+ } -+ mAvailable = true; -+ } -+ return static_cast<bool>(mAvailable); -+} -+ -+static void buffer_release(void* data, wl_buffer* buffer) { -+ auto surface = reinterpret_cast<WaylandDMABufSurface*>(data); -+ surface->WLBufferDetach(); -+} -+ -+static const struct wl_buffer_listener buffer_listener = {buffer_release}; -+ -+static void buffer_created(void* data, -+ struct zwp_linux_buffer_params_v1* params, -+ struct wl_buffer* new_buffer) { -+ auto surface = static_cast<WaylandDMABufSurface*>(data); -+ -+ surface->SetWLBuffer(new_buffer); -+ -+ nsWaylandDisplay* display = WaylandDisplayGet(); -+ /* When not using explicit synchronization listen to wl_buffer.release -+ * for release notifications, otherwise we are going to use -+ * zwp_linux_buffer_release_v1. */ -+ if (!display->IsExplicitSyncEnabled()) { -+ wl_buffer_add_listener(new_buffer, &buffer_listener, surface); -+ } -+ zwp_linux_buffer_params_v1_destroy(params); -+} -+ -+static void buffer_create_failed(void* data, -+ struct zwp_linux_buffer_params_v1* params) { -+ zwp_linux_buffer_params_v1_destroy(params); -+} -+ -+static const struct zwp_linux_buffer_params_v1_listener params_listener = { -+ buffer_created, buffer_create_failed}; -+ -+WaylandDMABufSurface::WaylandDMABufSurface() -+ : mWidth(0), -+ mHeight(0), -+ mGmbFormat(nullptr), -+ mWLBuffer(nullptr), -+ mMappedRegion(nullptr), -+ mGbmBufferObject(nullptr), -+ mBufferModifier(DRM_FORMAT_MOD_INVALID), -+ mBufferPlaneCount(1), -+ mWLBufferAttached(false), -+ mFastWLBufferCreation(true) { -+ for (int i = 0; i < DMABUF_BUFFER_PLANES; i++) { -+ mDmabufFds[i] = -1; -+ mStrides[i] = 0; -+ mOffsets[i] = 0; -+ } -+} -+ -+WaylandDMABufSurface::~WaylandDMABufSurface() { Release(); } -+ -+bool WaylandDMABufSurface::Create(int aWidth, int aHeight, bool aHasAlpha) { -+ MOZ_ASSERT(mWLBuffer == nullptr); -+ -+ mWidth = aWidth; -+ mHeight = aHeight; -+ -+ nsWaylandDisplay* display = WaylandDisplayGet(); -+ mGmbFormat = display->GetGbmFormat(aHasAlpha); -+ if (!mGmbFormat) { -+ // Requested DRM format is not supposed. -+ return false; -+ } -+ -+#ifdef HAVE_GBM_MODIFIERS -+ if (nsGbmLib::IsModifierAvailable() && mGmbFormat->mModifiersCount > 0) { -+ mGbmBufferObject = nsGbmLib::CreateWithModifiers( -+ display->GetGbmDevice(), mWidth, mHeight, mGmbFormat->mFormat, -+ mGmbFormat->mModifiers, mGmbFormat->mModifiersCount); -+ if (mGbmBufferObject) { -+ mBufferModifier = nsGbmLib::GetModifier(mGbmBufferObject); -+ } -+ } -+#endif -+ -+ if (!mGbmBufferObject) { -+ mGbmBufferObject = -+ nsGbmLib::Create(display->GetGbmDevice(), mWidth, mHeight, -+ mGmbFormat->mFormat, GBM_BO_USE_RENDERING); -+ } -+ -+ if (!mGbmBufferObject) { -+ return false; -+ } -+ -+#ifdef HAVE_GBM_MODIFIERS -+ if (nsGbmLib::IsModifierAvailable()) { -+ mBufferPlaneCount = nsGbmLib::GetPlaneCount(mGbmBufferObject); -+ for (int i = 0; i < mBufferPlaneCount; i++) { -+ uint32_t handle = nsGbmLib::GetHandleForPlane(mGbmBufferObject, i).u32; -+ int ret = nsGbmLib::DrmPrimeHandleToFD(display->GetGbmDeviceFd(), handle, -+ 0, &mDmabufFds[i]); -+ if (ret < 0 || mDmabufFds[i] < 0) { -+ Release(); -+ return false; -+ } -+ mStrides[i] = nsGbmLib::GetStrideForPlane(mGbmBufferObject, i); -+ mOffsets[i] = nsGbmLib::GetOffset(mGbmBufferObject, i); -+ } -+ } else -+#endif -+ { -+ mBufferPlaneCount = 1; -+ mStrides[0] = nsGbmLib::GetStride(mGbmBufferObject); -+ mDmabufFds[0] = nsGbmLib::GetFd(mGbmBufferObject); -+ if (mDmabufFds[0] < 0) { -+ Release(); -+ return false; -+ } -+ } -+ -+ struct zwp_linux_buffer_params_v1* params = -+ zwp_linux_dmabuf_v1_create_params(display->GetDmabuf()); -+ for (int i = 0; i < mBufferPlaneCount; i++) { -+ zwp_linux_buffer_params_v1_add(params, mDmabufFds[i], i, mOffsets[i], -+ mStrides[i], mBufferModifier >> 32, -+ mBufferModifier & 0xffffffff); -+ } -+ zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, this); -+ -+ if (mFastWLBufferCreation) { -+ mWLBuffer = zwp_linux_buffer_params_v1_create_immed( -+ params, mWidth, mHeight, mGmbFormat->mFormat, BUFFER_FLAGS); -+ /* When not using explicit synchronization listen to -+ * wl_buffer.release for release notifications, otherwise we -+ * are going to use zwp_linux_buffer_release_v1. */ -+ if (!display->IsExplicitSyncEnabled()) { -+ wl_buffer_add_listener(mWLBuffer, &buffer_listener, this); -+ } -+ } else { -+ zwp_linux_buffer_params_v1_create(params, mWidth, mHeight, -+ mGmbFormat->mFormat, BUFFER_FLAGS); -+ } -+ -+ return true; -+} -+ -+void WaylandDMABufSurface::Release() { -+ MOZ_ASSERT(!IsMapped(), "We can't release mapped buffer!"); -+ -+ if (mWLBuffer) { -+ wl_buffer_destroy(mWLBuffer); -+ mWLBuffer = nullptr; -+ } -+ -+ if (mGbmBufferObject) { -+ nsGbmLib::Destroy(mGbmBufferObject); -+ mGbmBufferObject = nullptr; -+ } -+ -+ for (int i = 0; i < mBufferPlaneCount; i++) { -+ if (mDmabufFds[i] >= 0) { -+ close(mDmabufFds[i]); -+ mDmabufFds[i] = 0; -+ } -+ } -+} -+ -+void* WaylandDMABufSurface::MapReadOnly(uint32_t aX, uint32_t aY, -+ uint32_t aWidth, uint32_t aHeight, -+ uint32_t* aStride) { -+ NS_ASSERTION(mMappedRegion == nullptr, "Already mapped?"); -+ void* map_data = nullptr; -+ *aStride = 0; -+ mMappedRegion = nsGbmLib::Map(mGbmBufferObject, aX, aY, aWidth, aHeight, -+ GBM_BO_TRANSFER_READ, aStride, &map_data); -+ return mMappedRegion; -+} -+ -+void* WaylandDMABufSurface::MapReadOnly(uint32_t* aStride) { -+ return MapReadOnly(0, 0, mWidth, mHeight, aStride); -+} -+ -+void* WaylandDMABufSurface::Map(uint32_t aX, uint32_t aY, uint32_t aWidth, -+ uint32_t aHeight, uint32_t* aStride) { -+ NS_ASSERTION(mMappedRegion == nullptr, "Already mapped?"); -+ void* map_data = nullptr; -+ *aStride = 0; -+ mMappedRegion = nsGbmLib::Map(mGbmBufferObject, aX, aY, aWidth, aHeight, -+ GBM_BO_TRANSFER_READ_WRITE, aStride, &map_data); -+ return mMappedRegion; -+} -+ -+void* WaylandDMABufSurface::Map(uint32_t* aStride) { -+ return Map(0, 0, mWidth, mHeight, aStride); -+} -+ -+void WaylandDMABufSurface::Unmap() { -+ if (mMappedRegion) { -+ nsGbmLib::Unmap(mGbmBufferObject, mMappedRegion); -+ mMappedRegion = nullptr; -+ } -+} -+ -+bool WaylandDMABufSurface::Resize(int aWidth, int aHeight) { -+ if (aWidth == mWidth && aHeight == mHeight) { -+ return true; -+ } -+ -+ if (IsMapped()) { -+ NS_WARNING("We can't resize mapped surface!"); -+ return false; -+ } -+ -+ Release(); -+ return Create(aWidth, aHeight, mGmbFormat->mHasAlpha); -+} -+ -+bool WaylandDMABufSurface::CopyFrom( -+ class WaylandDMABufSurface* aSourceSurface) { -+ // Not implemented - we should not call that. -+ MOZ_CRASH(); -+} -+ -+// TODO - EGL clear -+void WaylandDMABufSurface::Clear() { -+ uint32_t destStride; -+ void* destData = Map(&destStride); -+ memset(destData, 0, GetHeight() * destStride); -+ Unmap(); -+} -diff --git a/gfx/2d/WaylandDMABufSurface.h b/gfx/2d/WaylandDMABufSurface.h -new file mode 100644 ---- /dev/null -+++ b/gfx/2d/WaylandDMABufSurface.h -@@ -0,0 +1,73 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -+/* 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 WaylandDMABufSurface_h__ -+#define WaylandDMABufSurface_h__ -+ -+#include <stdint.h> -+#include "mozilla/widget/nsWaylandDisplay.h" -+ -+#define DMABUF_BUFFER_PLANES 4 -+ -+class WaylandDMABufSurface { -+ public: -+ static bool IsAvailable(); -+ -+ bool CreateFrameBuffer(int aWidth, int aHeight); -+ bool CreateEGLImage(int aWidth, int aHeight); -+ -+ bool Create(int aWidth, int aHeight, bool aHasAlpha = true); -+ bool Resize(int aWidth, int aHeight); -+ void Release(); -+ void Clear(); -+ -+ bool CopyFrom(class WaylandDMABufSurface* aSourceSurface); -+ -+ int GetWidth() { return mWidth; }; -+ int GetHeight() { return mHeight; }; -+ -+ void* MapReadOnly(uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight, -+ uint32_t* aStride); -+ void* MapReadOnly(uint32_t* aStride); -+ void* Map(uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight, -+ uint32_t* aStride); -+ void* Map(uint32_t* aStride); -+ bool IsMapped() { return mMappedRegion; }; -+ void Unmap(); -+ -+ void SetWLBuffer(struct wl_buffer* aWLBuffer) { mWLBuffer = aWLBuffer; }; -+ wl_buffer* GetWLBuffer() { return mWLBuffer; }; -+ -+ void WLBufferDetach() { mWLBufferAttached = false; }; -+ bool WLBufferIsAttached() { return mWLBufferAttached; }; -+ void WLBufferSetAttached() { mWLBufferAttached = true; }; -+ -+ WaylandDMABufSurface(); -+ ~WaylandDMABufSurface(); -+ -+ private: -+ int mWidth; -+ int mHeight; -+ mozilla::widget::GbmFormat* mGmbFormat; -+ -+ wl_buffer* mWLBuffer; -+ void* mMappedRegion; -+ -+ struct gbm_bo* mGbmBufferObject; -+ uint64_t mBufferModifier; -+ int mBufferPlaneCount; -+ int mDmabufFds[DMABUF_BUFFER_PLANES]; -+ uint32_t mStrides[DMABUF_BUFFER_PLANES]; -+ uint32_t mOffsets[DMABUF_BUFFER_PLANES]; -+ -+ bool mWLBufferAttached; -+ bool mFastWLBufferCreation; -+ -+ static bool mAvailable; -+ static bool mInitialized; -+}; -+ -+#endif -diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build ---- a/gfx/2d/moz.build -+++ b/gfx/2d/moz.build -@@ -255,8 +255,20 @@ if CONFIG['MOZ_ENABLE_SKIA']: - '/gfx/skia/skia/include/private', - '/gfx/skia/skia/src/core', - '/gfx/skia/skia/src/image', - ] - if CONFIG['MOZ_ENABLE_SKIA_GPU']: - LOCAL_INCLUDES += [ - '/gfx/skia/skia/src/gpu', - ] -+ -+#if CONFIG['MOZ_WAYLAND'] and CONFIG['HAVE_LIBDRM']: -+if CONFIG['HAVE_LIBDRM']: -+ SOURCES += [ -+ 'WaylandDMABufSurface.cpp', -+ ] -+ EXPORTS.mozilla.gfx += [ -+ 'WaylandDMABufSurface.h', -+ ] -+ CFLAGS += CONFIG['TK_CFLAGS'] -+ CXXFLAGS += CONFIG['TK_CFLAGS'] -+ -diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js ---- a/modules/libpref/init/all.js -+++ b/modules/libpref/init/all.js -@@ -5091,16 +5091,21 @@ pref("gfx.apitrace.enabled",false); - - #ifdef MOZ_X11 - #ifdef MOZ_WIDGET_GTK - pref("gfx.xrender.enabled",false); - pref("widget.chrome.allow-gtk-dark-theme", false); - pref("widget.content.allow-gtk-dark-theme", false); - #endif - #endif -+#ifdef MOZ_WAYLAND -+#ifdef HAVE_LIBDRM -+pref("gfx.wayland_dmabuf_backend.enabled", false); -+#endif -+#endif - - pref("widget.window-transforms.disabled", false); - - #ifdef XP_WIN - // Whether to disable the automatic detection and use of direct2d. - pref("gfx.direct2d.disabled", false); - - // Whether to attempt to enable Direct2D regardless of automatic detection or -diff --git a/toolkit/moz.configure b/toolkit/moz.configure ---- a/toolkit/moz.configure -+++ b/toolkit/moz.configure -@@ -260,16 +260,24 @@ def wayland_headers(wayland, toolkit_gtk - if toolkit_gtk and artifacts: - return True - return wayland - - - set_config('MOZ_WAYLAND', depends_if(wayland_headers)(lambda _: True)) - set_define('MOZ_WAYLAND', depends_if(wayland_headers)(lambda _: True)) - -+drm_headers = pkg_check_modules('HAVE_LIBDRM', 'libdrm > 2.4', when=wayland_headers) -+set_config('HAVE_LIBDRM', depends_if(drm_headers)(lambda _: True)) -+set_define('HAVE_LIBDRM', depends_if(drm_headers)(lambda _: True)) -+ -+gbm_modifiers = pkg_check_modules('HAVE_GBM_MODIFIERS', 'gbm >= 17.1', when=drm_headers) -+set_config('HAVE_GBM_MODIFIERS', depends_if(gbm_modifiers)(lambda _: True)) -+set_define('HAVE_GBM_MODIFIERS', depends_if(gbm_modifiers)(lambda _: True)) -+ - # GL Provider - # ============================================================== - option('--with-gl-provider', nargs=1, help='Set GL provider backend type') - - @depends('--with-gl-provider') - def gl_provider(value): - if value: - return value[0] -diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp ---- a/widget/gtk/WindowSurfaceWayland.cpp -+++ b/widget/gtk/WindowSurfaceWayland.cpp -@@ -30,16 +30,19 @@ extern mozilla::LazyLogModule gWidgetWay - MOZ_LOG(gWidgetWaylandLog, mozilla::LogLevel::Debug, args) - #else - # define LOGWAYLAND(args) - #endif /* MOZ_LOGGING */ - - namespace mozilla { - namespace widget { - -+bool WindowSurfaceWayland::mUseDMABuf = false; -+bool WindowSurfaceWayland::mUseDMABufInitialized = false; -+ - /* - Wayland multi-thread rendering scheme - - Every rendering thread (main thread, compositor thread) contains its own - nsWaylandDisplay object connected to Wayland compositor (Mutter, Weston, etc.) - - WindowSurfaceWayland implements WindowSurface class and draws nsWindow by - WindowSurface interface (Lock, Commit) to screen through nsWaylandDisplay. -@@ -255,120 +258,183 @@ WaylandShmPool::~WaylandShmPool() { - - static void buffer_release(void* data, wl_buffer* buffer) { - auto surface = reinterpret_cast<WindowBackBuffer*>(data); - surface->Detach(buffer); - } - - static const struct wl_buffer_listener buffer_listener = {buffer_release}; - --void WindowBackBuffer::Create(int aWidth, int aHeight) { -+void WindowBackBufferShm::Create(int aWidth, int aHeight) { - MOZ_ASSERT(!IsAttached(), "We can't resize attached buffers."); - - int newBufferSize = aWidth * aHeight * BUFFER_BPP; - mShmPool.Resize(newBufferSize); - - mWaylandBuffer = - wl_shm_pool_create_buffer(mShmPool.GetShmPool(), 0, aWidth, aHeight, - aWidth * BUFFER_BPP, WL_SHM_FORMAT_ARGB8888); - wl_proxy_set_queue((struct wl_proxy*)mWaylandBuffer, -- mWaylandDisplay->GetEventQueue()); -+ GetWaylandDisplay()->GetEventQueue()); - wl_buffer_add_listener(mWaylandBuffer, &buffer_listener, this); - - mWidth = aWidth; - mHeight = aHeight; - - LOGWAYLAND(( - "%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this, - (void*)mWaylandBuffer, - mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); - } - --void WindowBackBuffer::Release() { -+void WindowBackBufferShm::Release() { - LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); - - wl_buffer_destroy(mWaylandBuffer); - mWidth = mHeight = 0; - } - --void WindowBackBuffer::Clear() { -+void WindowBackBufferShm::Clear() { - memset(mShmPool.GetImageData(), 0, mHeight * mWidth * BUFFER_BPP); - } - --WindowBackBuffer::WindowBackBuffer(nsWaylandDisplay* aWaylandDisplay, -- int aWidth, int aHeight) -- : mShmPool(aWaylandDisplay, aWidth * aHeight * BUFFER_BPP), -+WindowBackBufferShm::WindowBackBufferShm(nsWaylandDisplay* aWaylandDisplay, -+ int aWidth, int aHeight) -+ : WindowBackBuffer(aWaylandDisplay), -+ mShmPool(aWaylandDisplay, aWidth * aHeight * BUFFER_BPP), - mWaylandBuffer(nullptr), - mWidth(aWidth), - mHeight(aHeight), -- mAttached(false), -- mWaylandDisplay(aWaylandDisplay) { -+ mAttached(false) { - Create(aWidth, aHeight); - } - --WindowBackBuffer::~WindowBackBuffer() { Release(); } -+WindowBackBufferShm::~WindowBackBufferShm() { Release(); } - --bool WindowBackBuffer::Resize(int aWidth, int aHeight) { -+bool WindowBackBufferShm::Resize(int aWidth, int aHeight) { - if (aWidth == mWidth && aHeight == mHeight) return true; - - LOGWAYLAND( - ("%s [%p] %d %d\n", __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight)); - - Release(); - Create(aWidth, aHeight); - - return (mWaylandBuffer != nullptr); - } - - void WindowBackBuffer::Attach(wl_surface* aSurface) { -- LOGWAYLAND(( -- "%s [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, -- (void*)this, (void*)aSurface, -- aSurface ? wl_proxy_get_id((struct wl_proxy*)aSurface) : -1, -- (void*)mWaylandBuffer, -- mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); -+ LOGWAYLAND( -+ ("%s [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, -+ (void*)this, (void*)aSurface, -+ aSurface ? wl_proxy_get_id((struct wl_proxy*)aSurface) : -1, -+ (void*)GetWlBuffer(), -+ GetWlBuffer() ? wl_proxy_get_id((struct wl_proxy*)GetWlBuffer()) : -1)); - -- wl_surface_attach(aSurface, mWaylandBuffer, 0, 0); -+ wl_surface_attach(aSurface, GetWlBuffer(), 0, 0); - wl_surface_commit(aSurface); -- wl_display_flush(mWaylandDisplay->GetDisplay()); -- mAttached = true; -+ wl_display_flush(GetWaylandDisplay()->GetDisplay()); -+ SetAttached(); - } - --void WindowBackBuffer::Detach(wl_buffer* aBuffer) { -+void WindowBackBufferShm::Detach(wl_buffer* aBuffer) { - LOGWAYLAND(("%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this, - (void*)aBuffer, - aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1)); - - mAttached = false; - } - --bool WindowBackBuffer::SetImageDataFromBuffer( -+bool WindowBackBufferShm::SetImageDataFromBuffer( - class WindowBackBuffer* aSourceBuffer) { -- if (!IsMatchingSize(aSourceBuffer)) { -- Resize(aSourceBuffer->mWidth, aSourceBuffer->mHeight); -+ auto sourceBuffer = static_cast<class WindowBackBufferShm*>(aSourceBuffer); -+ if (!IsMatchingSize(sourceBuffer)) { -+ Resize(sourceBuffer->mWidth, sourceBuffer->mHeight); - } - - mShmPool.SetImageDataFromPool( -- &aSourceBuffer->mShmPool, -- aSourceBuffer->mWidth * aSourceBuffer->mHeight * BUFFER_BPP); -+ &sourceBuffer->mShmPool, -+ sourceBuffer->mWidth * sourceBuffer->mHeight * BUFFER_BPP); - return true; - } - --already_AddRefed<gfx::DrawTarget> WindowBackBuffer::Lock() { -+already_AddRefed<gfx::DrawTarget> WindowBackBufferShm::Lock() { - LOGWAYLAND(( - "%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, - (void*)this, mWidth, mHeight, (void*)mWaylandBuffer, - mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); - - gfx::IntSize lockSize(mWidth, mHeight); - return gfxPlatform::CreateDrawTargetForData( - static_cast<unsigned char*>(mShmPool.GetImageData()), lockSize, -- BUFFER_BPP * mWidth, mFormat); -+ BUFFER_BPP * mWidth, GetSurfaceFormat()); -+} -+ -+#ifdef HAVE_LIBDRM -+WindowBackBufferDMABuf::WindowBackBufferDMABuf( -+ nsWaylandDisplay* aWaylandDisplay, int aWidth, int aHeight) -+ : WindowBackBuffer(aWaylandDisplay) { -+ mDMAbufSurface.Create(aWidth, aHeight); -+} -+ -+WindowBackBufferDMABuf::~WindowBackBufferDMABuf() { mDMAbufSurface.Release(); } -+ -+already_AddRefed<gfx::DrawTarget> WindowBackBufferDMABuf::Lock() { -+ LOGWAYLAND( -+ ("%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, -+ (void*)this, GetWidth(), GetHeight(), (void*)GetWlBuffer(), -+ GetWlBuffer() ? wl_proxy_get_id((struct wl_proxy*)GetWlBuffer()) : -1)); -+ -+ uint32_t stride; -+ void* pixels = mDMAbufSurface.Map(&stride); -+ gfx::IntSize lockSize(GetWidth(), GetHeight()); -+ return gfxPlatform::CreateDrawTargetForData( -+ static_cast<unsigned char*>(pixels), lockSize, stride, -+ GetSurfaceFormat()); -+} -+ -+void WindowBackBufferDMABuf::Unlock() { mDMAbufSurface.Unmap(); } -+ -+bool WindowBackBufferDMABuf::IsAttached() { -+ return mDMAbufSurface.WLBufferIsAttached(); - } - -+void WindowBackBufferDMABuf::SetAttached() { -+ return mDMAbufSurface.WLBufferSetAttached(); -+} -+ -+int WindowBackBufferDMABuf::GetWidth() { return mDMAbufSurface.GetWidth(); } -+ -+int WindowBackBufferDMABuf::GetHeight() { return mDMAbufSurface.GetHeight(); } -+ -+wl_buffer* WindowBackBufferDMABuf::GetWlBuffer() { -+ return mDMAbufSurface.GetWLBuffer(); -+} -+ -+bool WindowBackBufferDMABuf::IsLocked() { return mDMAbufSurface.IsMapped(); } -+ -+bool WindowBackBufferDMABuf::Resize(int aWidth, int aHeight) { -+ return mDMAbufSurface.Resize(aWidth, aHeight); -+} -+ -+bool WindowBackBufferDMABuf::SetImageDataFromBuffer( -+ class WindowBackBuffer* aSourceBuffer) { -+ WindowBackBufferDMABuf* source = -+ static_cast<WindowBackBufferDMABuf*>(aSourceBuffer); -+ mDMAbufSurface.CopyFrom(&source->mDMAbufSurface); -+ return true; -+} -+ -+void WindowBackBufferDMABuf::Detach(wl_buffer* aBuffer) { -+ mDMAbufSurface.WLBufferDetach(); -+} -+ -+void WindowBackBufferDMABuf::Clear() { mDMAbufSurface.Clear(); } -+#endif -+ - static void frame_callback_handler(void* data, struct wl_callback* callback, - uint32_t time) { - auto surface = reinterpret_cast<WindowSurfaceWayland*>(data); - surface->FrameCallbackHandler(); - - gfxPlatformGtk::GetPlatform()->SetWaylandLastVsync(time); - } - -@@ -412,23 +478,60 @@ WindowSurfaceWayland::~WindowSurfaceWayl - - for (int i = 0; i < BACK_BUFFER_NUM; i++) { - if (mBackupBuffer[i]) { - delete mBackupBuffer[i]; - } - } - } - --WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, -- int aHeight) { -+bool WindowSurfaceWayland::UseDMABufBackend() { -+ if (!mUseDMABufInitialized) { -+#ifdef HAVE_LIBDRM -+ if (WaylandDMABufSurface::IsAvailable()) { -+ mUseDMABuf = -+ Preferences::GetBool("gfx.wayland_dmabuf_backend.enabled", false); -+ } -+#endif -+ mUseDMABufInitialized = true; -+ } -+ return mUseDMABuf; -+} -+ -+WindowBackBuffer* WindowSurfaceWayland::CreateWaylandBuffer(int aWidth, -+ int aHeight) { -+ if (UseDMABufBackend()) { -+ static bool sDMABufBufferCreated = false; -+ WindowBackBuffer* buffer = -+ new WindowBackBufferDMABuf(mWaylandDisplay, aWidth, aHeight); -+ if (buffer) { -+ sDMABufBufferCreated = true; -+ return buffer; -+ } -+ // If this is the first failure and there's no dmabuf already active -+ // we can safely fallback to Shm. Otherwise we can't mix DMAbuf and -+ // SHM buffers so just fails now. -+ if (sDMABufBufferCreated) { -+ NS_WARNING("Failed to allocate DMABuf buffer!"); -+ return nullptr; -+ } else { -+ NS_WARNING("Wayland DMABuf failed, switched back to Shm backend!"); -+ mUseDMABuf = false; -+ } -+ } -+ return new WindowBackBufferShm(mWaylandDisplay, aWidth, aHeight); -+} -+ -+WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw( -+ int aWidth, int aHeight, bool aFullScreenUpdate, bool aNoBackBufferCopy) { - if (!mWaylandBuffer) { - LOGWAYLAND(("%s [%p] Create [%d x %d]\n", __PRETTY_FUNCTION__, (void*)this, - aWidth, aHeight)); - -- mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -+ mWaylandBuffer = CreateWaylandBuffer(aWidth, aHeight); - mWaitToFullScreenUpdate = true; - return mWaylandBuffer; - } - - if (!mWaylandBuffer->IsAttached()) { - if (!mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { - mWaylandBuffer->Resize(aWidth, aHeight); - // There's a chance that scale factor has been changed -@@ -444,75 +547,89 @@ WindowBackBuffer* WindowSurfaceWayland:: - MOZ_ASSERT(!mPendingCommit, - "Uncommitted buffer switch, screen artifacts ahead."); - - // Front buffer is used by compositor, select a back buffer - int availableBuffer; - for (availableBuffer = 0; availableBuffer < BACK_BUFFER_NUM; - availableBuffer++) { - if (!mBackupBuffer[availableBuffer]) { -- mBackupBuffer[availableBuffer] = -- new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -+ mBackupBuffer[availableBuffer] = CreateWaylandBuffer(aWidth, aHeight); - break; - } - - if (!mBackupBuffer[availableBuffer]->IsAttached()) { - break; - } - } - - if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) { - LOGWAYLAND(("%s [%p] No drawing buffer available!\n", __PRETTY_FUNCTION__, - (void*)this)); - NS_WARNING("No drawing buffer available"); - return nullptr; - } - -+ bool bufferFlip = mWaylandBuffer->IsMatchingSize(aWidth, aHeight); -+ if (bufferFlip && aNoBackBufferCopy && !aFullScreenUpdate) { -+ LOGWAYLAND(("%s [%p] Delayed hard copy from old buffer [%d x %d]\n", -+ __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight)); -+ return nullptr; -+ } -+ - WindowBackBuffer* lastWaylandBuffer = mWaylandBuffer; - mWaylandBuffer = mBackupBuffer[availableBuffer]; - mBackupBuffer[availableBuffer] = lastWaylandBuffer; - -- if (lastWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { -- LOGWAYLAND(("%s [%p] Copy from old buffer [%d x %d]\n", __PRETTY_FUNCTION__, -- (void*)this, aWidth, aHeight)); -+ if (bufferFlip) { - // Former front buffer has the same size as a requested one. - // Gecko may expect a content already drawn on screen so copy -- // existing data to the new buffer. -- mWaylandBuffer->SetImageDataFromBuffer(lastWaylandBuffer); -+ // existing data to the new buffer if we don't do fullscreen redraw. -+ if (!aFullScreenUpdate) { -+ LOGWAYLAND(("%s [%p] Copy from old buffer [%d x %d]\n", -+ __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight)); -+ mWaylandBuffer->SetImageDataFromBuffer(lastWaylandBuffer); -+ } - // When buffer switches we need to damage whole screen - // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260) - mWaylandBufferFullScreenDamage = true; - } else { - LOGWAYLAND(("%s [%p] Resize to [%d x %d]\n", __PRETTY_FUNCTION__, - (void*)this, aWidth, aHeight)); - // Former buffer has different size from the new request. Only resize - // the new buffer and leave gecko to render new whole content. - mWaylandBuffer->Resize(aWidth, aHeight); - mWaitToFullScreenUpdate = true; - } - - return mWaylandBuffer; - } - - already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer( -- int aWidth, int aHeight, bool aClearBuffer) { -- WindowBackBuffer* buffer = GetWaylandBufferToDraw(aWidth, aHeight); -+ int aWidth, int aHeight, bool aClearBuffer, bool aFullScreenUpdate, -+ bool aNoBackBufferCopy) { -+ WindowBackBuffer* buffer = GetWaylandBufferToDraw( -+ aWidth, aHeight, aFullScreenUpdate, aNoBackBufferCopy); - if (!buffer) { -- NS_WARNING( -- "WindowSurfaceWayland::LockWaylandBuffer(): No buffer available"); -+ if (!aNoBackBufferCopy) { -+ NS_WARNING( -+ "WindowSurfaceWayland::LockWaylandBuffer(): No buffer available"); -+ } - return nullptr; - } - - if (aClearBuffer) { - buffer->Clear(); - } - - return buffer->Lock(); - } - -+void WindowSurfaceWayland::UnlockWaylandBuffer() { mWaylandBuffer->Unlock(); } -+ - already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockImageSurface( - const gfx::IntSize& aLockSize) { - if (!mImageSurface || mImageSurface->CairoStatus() || - !(aLockSize <= mImageSurface->GetSize())) { - mImageSurface = new gfxImageSurface( - aLockSize, - SurfaceFormatToImageFormat(WindowBackBuffer::GetSurfaceFormat())); - if (mImageSurface->CairoStatus()) { -@@ -552,20 +669,28 @@ already_AddRefed<gfx::DrawTarget> Window - - // Are we asked for entire nsWindow to draw? - mDrawToWaylandBufferDirectly = - (aRegion.GetNumRects() == 1 && bounds.x == 0 && bounds.y == 0 && - lockSize.width == screenRect.width && - lockSize.height == screenRect.height); - - if (mDrawToWaylandBufferDirectly) { -- RefPtr<gfx::DrawTarget> dt = -- LockWaylandBuffer(screenRect.width, screenRect.height, -- mWindow->WaylandSurfaceNeedsClear()); -+ // If there's any pending image commit scratch them as we're going -+ // to redraw the whole sceen anyway. -+ mDelayedImageCommits.Clear(); -+ -+ bool needsClear = mWindow->WaylandSurfaceNeedsClear(); -+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer( -+ screenRect.width, screenRect.height, needsClear, -+ /* aFullScreenUpdate */ true, /* aNoBackBufferCopy */ true); - if (dt) { -+ if (needsClear) { -+ mWindow->WaylandSurfaceCleared(); -+ } - // When we have a request to update whole screen at once - // (surface was created, resized or changed somehow) - // we also need update scale factor of the screen. - if (mWaitToFullScreenUpdate) { - mWaitToFullScreenUpdate = false; - mNeedScaleFactorUpdate = true; - } - return dt.forget(); -@@ -574,52 +699,94 @@ already_AddRefed<gfx::DrawTarget> Window - // We don't have any front buffer available. Try indirect drawing - // to mImageSurface which is mirrored to front buffer at commit. - mDrawToWaylandBufferDirectly = false; - } - - return LockImageSurface(lockSize); - } - -+void WindowImageSurface::Draw(gfx::SourceSurface* aSurface, -+ gfx::DrawTarget* aDest, -+ const LayoutDeviceIntRegion& aRegion) { -+ uint32_t numRects = aRegion.GetNumRects(); -+ if (numRects != 1) { -+ AutoTArray<IntRect, 32> rects; -+ rects.SetCapacity(numRects); -+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) { -+ rects.AppendElement(iter.Get().ToUnknownRect()); -+ } -+ aDest->PushDeviceSpaceClipRects(rects.Elements(), rects.Length()); -+ } -+ -+ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); -+ gfx::Rect rect(bounds); -+ aDest->DrawSurface(aSurface, rect, rect); -+ -+ if (numRects != 1) { -+ aDest->PopClip(); -+ } -+} -+ -+void WindowImageSurface::Draw(gfx::DrawTarget* aDest, -+ LayoutDeviceIntRegion& aWaylandBufferDamage) { -+ Draw(mSurface.get(), aDest, mUpdateRegion); -+ aWaylandBufferDamage.OrWith(mUpdateRegion); -+} -+ -+WindowImageSurface::WindowImageSurface( -+ gfx::SourceSurface* aSurface, const LayoutDeviceIntRegion& aUpdateRegion) -+ : mSurface(aSurface), mUpdateRegion(aUpdateRegion){}; -+ -+void WindowSurfaceWayland::DrawDelayedImageCommits( -+ gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) { -+ for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) { -+ mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage); -+ } -+ mDelayedImageCommits.Clear(); -+} -+ - bool WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer( -- const LayoutDeviceIntRegion& aRegion) { -+ const LayoutDeviceIntRegion& aRegion, -+ LayoutDeviceIntRegion& aWaylandBufferDamage) { - MOZ_ASSERT(!mDrawToWaylandBufferDirectly); - - LayoutDeviceIntRect screenRect = mWindow->GetBounds(); - gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); - - gfx::Rect rect(bounds); - if (rect.IsEmpty()) { - return false; - } - -- RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer( -- screenRect.width, screenRect.height, mWindow->WaylandSurfaceNeedsClear()); - RefPtr<gfx::SourceSurface> surf = - gfx::Factory::CreateSourceSurfaceForCairoSurface( - mImageSurface->CairoSurface(), mImageSurface->GetSize(), - mImageSurface->Format()); -- if (!dt || !surf) { -+ if (!surf) { - return false; - } - -- uint32_t numRects = aRegion.GetNumRects(); -- if (numRects != 1) { -- AutoTArray<IntRect, 32> rects; -- rects.SetCapacity(numRects); -- for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) { -- rects.AppendElement(iter.Get().ToUnknownRect()); -+ bool needsClear = mWindow->WaylandSurfaceNeedsClear(); -+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer( -+ screenRect.width, screenRect.height, needsClear, -+ /* fullscreenDrawing */ false, /* aNoBackBufferCopy */ true); -+ if (dt) { -+ if (needsClear) { -+ mWindow->WaylandSurfaceCleared(); - } -- dt->PushDeviceSpaceClipRects(rects.Elements(), rects.Length()); -- } -- -- dt->DrawSurface(surf, rect, rect); -- -- if (numRects != 1) { -- dt->PopClip(); -+ // Draw any delayed image commits first -+ DrawDelayedImageCommits(dt, aWaylandBufferDamage); -+ WindowImageSurface::Draw(surf, dt, aRegion); -+ // Submit all drawing to final Wayland buffer upload -+ aWaylandBufferDamage.OrWith(aRegion); -+ UnlockWaylandBuffer(); -+ } else { -+ mDelayedImageCommits.AppendElement(WindowImageSurface(surf, aRegion)); -+ return false; - } - - return true; - } - - static void WaylandBufferDelayCommitHandler(WindowSurfaceWayland** aSurface) { - if (*aSurface) { - (*aSurface)->DelayedCommitHandler(); -@@ -643,16 +810,34 @@ void WindowSurfaceWayland::CalcRectScale - - void WindowSurfaceWayland::CommitWaylandBuffer() { - MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); - - if (mWaitToFullScreenUpdate) { - return; - } - -+ if (!mDrawToWaylandBufferDirectly) { -+ // There's some cached drawings - try to flush them now. -+ LayoutDeviceIntRect screenRect = mWindow->GetBounds(); -+ bool needsClear = mWindow->WaylandSurfaceNeedsClear(); -+ RefPtr<gfx::DrawTarget> dt = -+ LockWaylandBuffer(screenRect.width, screenRect.height, needsClear, -+ /* fullscreenInvalidate */ false, -+ /* aNoBackBufferCopy */ true); -+ if (dt) { -+ if (needsClear) { -+ mWindow->WaylandSurfaceCleared(); -+ } -+ DrawDelayedImageCommits(dt, mWaylandBufferDamage); -+ UnlockWaylandBuffer(); -+ mDrawToWaylandBufferDirectly = true; -+ } -+ } -+ - wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (!waylandSurface) { - // Target window is not created yet - delay the commit. This can happen only - // when the window is newly created and there's no active - // frame callback pending. - MOZ_ASSERT(!mFrameCallback || waylandSurface != mLastCommittedSurface, - "Missing wayland surface at frame callback!"); - -@@ -735,24 +920,31 @@ void WindowSurfaceWayland::Commit(const - gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); - - LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n", - __PRETTY_FUNCTION__, (void*)this, lockSize.width, - lockSize.height, screenRect.width, lockSize.height)); - } - #endif - -- // We have new content at mImageSurface - copy data to mWaylandBuffer first. -- if (!mDrawToWaylandBufferDirectly) { -- CommitImageSurfaceToWaylandBuffer(aInvalidRegion); -- } -- -- // If we're not at fullscreen damage add drawing area from aInvalidRegion -- if (!mWaylandBufferFullScreenDamage) { -- mWaylandBufferDamage.OrWith(aInvalidRegion); -+ if (mDrawToWaylandBufferDirectly) { -+ MOZ_ASSERT(mWaylandBuffer->IsLocked()); -+ // If we're not at fullscreen damage add drawing area from aInvalidRegion -+ if (!mWaylandBufferFullScreenDamage) { -+ mWaylandBufferDamage.OrWith(aInvalidRegion); -+ } -+ UnlockWaylandBuffer(); -+ } else { -+ MOZ_ASSERT(!mWaylandBuffer->IsLocked(), -+ "Drawing to already locked buffer?"); -+ if (CommitImageSurfaceToWaylandBuffer(aInvalidRegion, -+ mWaylandBufferDamage)) { -+ // Our cached drawing is flushed, we can draw fullscreen again. -+ mDrawToWaylandBufferDirectly = true; -+ } - } - - // We're ready to commit. - mPendingCommit = true; - CommitWaylandBuffer(); - } - - void WindowSurfaceWayland::FrameCallbackHandler() { -diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h ---- a/widget/gtk/WindowSurfaceWayland.h -+++ b/widget/gtk/WindowSurfaceWayland.h -@@ -5,16 +5,19 @@ - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - #ifndef _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H - #define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H - - #include <prthread.h> - #include "mozilla/gfx/Types.h" - #include "nsWaylandDisplay.h" -+#ifdef HAVE_LIBDRM -+# include "mozilla/gfx/WaylandDMABufSurface.h" -+#endif - - #define BACK_BUFFER_NUM 2 - - namespace mozilla { - namespace widget { - - // Allocates and owns shared memory for Wayland drawing surface - class WaylandShmPool { -@@ -35,94 +38,192 @@ class WaylandShmPool { - int mShmPoolFd; - int mAllocatedSize; - void* mImageData; - }; - - // Holds actual graphics data for wl_surface - class WindowBackBuffer { - public: -- WindowBackBuffer(nsWaylandDisplay* aDisplay, int aWidth, int aHeight); -- ~WindowBackBuffer(); -+ virtual already_AddRefed<gfx::DrawTarget> Lock() = 0; -+ virtual void Unlock(){}; -+ virtual bool IsLocked() { return false; }; -+ -+ void Attach(wl_surface* aSurface); -+ virtual void Detach(wl_buffer* aBuffer) = 0; -+ virtual bool IsAttached() = 0; -+ -+ virtual void Clear() = 0; -+ virtual bool Resize(int aWidth, int aHeight) = 0; -+ -+ virtual int GetWidth() = 0; -+ virtual int GetHeight() = 0; -+ virtual wl_buffer* GetWlBuffer() = 0; -+ virtual void SetAttached() = 0; -+ -+ virtual bool SetImageDataFromBuffer( -+ class WindowBackBuffer* aSourceBuffer) = 0; -+ -+ bool IsMatchingSize(int aWidth, int aHeight) { -+ return aWidth == GetWidth() && aHeight == GetHeight(); -+ } -+ bool IsMatchingSize(class WindowBackBuffer* aBuffer) { -+ return aBuffer->IsMatchingSize(GetWidth(), GetHeight()); -+ } -+ -+ static gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; } -+ -+ nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; }; -+ -+ WindowBackBuffer(nsWaylandDisplay* aWaylandDisplay) -+ : mWaylandDisplay(aWaylandDisplay){}; -+ virtual ~WindowBackBuffer(){}; -+ -+ private: -+ static gfx::SurfaceFormat mFormat; -+ nsWaylandDisplay* mWaylandDisplay; -+}; -+ -+class WindowBackBufferShm : public WindowBackBuffer { -+ public: -+ WindowBackBufferShm(nsWaylandDisplay* aWaylandDisplay, int aWidth, -+ int aHeight); -+ ~WindowBackBufferShm(); - - already_AddRefed<gfx::DrawTarget> Lock(); - -- void Attach(wl_surface* aSurface); - void Detach(wl_buffer* aBuffer); - bool IsAttached() { return mAttached; } - - void Clear(); - bool Resize(int aWidth, int aHeight); - bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); - -- bool IsMatchingSize(int aWidth, int aHeight) { -- return aWidth == mWidth && aHeight == mHeight; -- } -- bool IsMatchingSize(class WindowBackBuffer* aBuffer) { -- return aBuffer->mWidth == mWidth && aBuffer->mHeight == mHeight; -- } -+ int GetWidth() { return mWidth; }; -+ int GetHeight() { return mHeight; }; - -- static gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; } -+ wl_buffer* GetWlBuffer() { return mWaylandBuffer; }; -+ void SetAttached() { mAttached = true; }; - - private: - void Create(int aWidth, int aHeight); - void Release(); - - // WaylandShmPool provides actual shared memory we draw into - WaylandShmPool mShmPool; - - // wl_buffer is a wayland object that encapsulates the shared memory - // and passes it to wayland compositor by wl_surface object. - wl_buffer* mWaylandBuffer; - int mWidth; - int mHeight; - bool mAttached; -- nsWaylandDisplay* mWaylandDisplay; -- static gfx::SurfaceFormat mFormat; -+}; -+ -+#ifdef HAVE_LIBDRM -+class WindowBackBufferDMABuf : public WindowBackBuffer { -+ public: -+ WindowBackBufferDMABuf(nsWaylandDisplay* aWaylandDisplay, int aWidth, -+ int aHeight); -+ ~WindowBackBufferDMABuf(); -+ -+ bool IsAttached(); -+ void SetAttached(); -+ -+ int GetWidth(); -+ int GetHeight(); -+ wl_buffer* GetWlBuffer(); -+ -+ bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); -+ -+ already_AddRefed<gfx::DrawTarget> Lock(); -+ bool IsLocked(); -+ void Unlock(); -+ -+ void Clear(); -+ void Detach(wl_buffer* aBuffer); -+ bool Resize(int aWidth, int aHeight); -+ -+ private: -+ WaylandDMABufSurface mDMAbufSurface; -+}; -+#endif -+ -+class WindowImageSurface { -+ public: -+ static void Draw(gfx::SourceSurface* aSurface, gfx::DrawTarget* aDest, -+ const LayoutDeviceIntRegion& aRegion); -+ -+ void Draw(gfx::DrawTarget* aDest, -+ LayoutDeviceIntRegion& aWaylandBufferDamage); -+ -+ WindowImageSurface(gfx::SourceSurface* aSurface, -+ const LayoutDeviceIntRegion& aUpdateRegion); -+ -+ private: -+ RefPtr<gfx::SourceSurface> mSurface; -+ const LayoutDeviceIntRegion mUpdateRegion; - }; - - // WindowSurfaceWayland is an abstraction for wl_surface - // and related management - class WindowSurfaceWayland : public WindowSurface { - public: - explicit WindowSurfaceWayland(nsWindow* aWindow); - ~WindowSurfaceWayland(); - - already_AddRefed<gfx::DrawTarget> Lock( - const LayoutDeviceIntRegion& aRegion) override; - void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final; - void FrameCallbackHandler(); - void DelayedCommitHandler(); - - private: -- WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight); -+ WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight); -+ WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight, -+ bool aFullScreenUpdate, -+ bool aNoBackBufferCopy); - - already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(int aWidth, int aHeight, -- bool aClearBuffer); -+ bool aClearBuffer, -+ bool aFullScreenUpdate, -+ bool aNoBackBufferCopy); -+ void UnlockWaylandBuffer(); -+ - already_AddRefed<gfx::DrawTarget> LockImageSurface( - const gfx::IntSize& aLockSize); -- bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); -+ bool CommitImageSurfaceToWaylandBuffer( -+ const LayoutDeviceIntRegion& aRegion, -+ LayoutDeviceIntRegion& aWaylandBufferDamage); - void CommitWaylandBuffer(); - void CalcRectScale(LayoutDeviceIntRect& aRect, int scale); - -+ void DrawDelayedImageCommits(gfx::DrawTarget* aDrawTarget, -+ LayoutDeviceIntRegion& aWaylandBufferDamage); -+ - // TODO: Do we need to hold a reference to nsWindow object? - nsWindow* mWindow; - nsWaylandDisplay* mWaylandDisplay; - WindowBackBuffer* mWaylandBuffer; - LayoutDeviceIntRegion mWaylandBufferDamage; - WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM]; -- RefPtr<gfxImageSurface> mImageSurface; - wl_callback* mFrameCallback; - wl_surface* mLastCommittedSurface; - MessageLoop* mDisplayThreadMessageLoop; - WindowSurfaceWayland** mDelayedCommitHandle; -+ RefPtr<gfxImageSurface> mImageSurface; -+ AutoTArray<WindowImageSurface, 30> mDelayedImageCommits; - bool mDrawToWaylandBufferDirectly; - bool mPendingCommit; - bool mWaylandBufferFullScreenDamage; - bool mIsMainThread; - bool mNeedScaleFactorUpdate; - bool mWaitToFullScreenUpdate; -+ -+ static bool UseDMABufBackend(); -+ static bool mUseDMABufInitialized; -+ static bool mUseDMABuf; - }; - - } // namespace widget - } // namespace mozilla - - #endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H -diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build ---- a/widget/gtk/moz.build -+++ b/widget/gtk/moz.build -@@ -97,17 +97,18 @@ if CONFIG['MOZ_X11']: - - if CONFIG['MOZ_WAYLAND']: - UNIFIED_SOURCES += [ - 'nsClipboardWayland.cpp', - 'nsWaylandDisplay.cpp', - 'WindowSurfaceWayland.cpp', - ] - EXPORTS.mozilla.widget += [ -- 'nsWaylandDisplayShutdown.h' -+ 'nsWaylandDisplay.h', -+ 'nsWaylandDisplayShutdown.h', - ] - - if CONFIG['ACCESSIBILITY']: - UNIFIED_SOURCES += [ - 'maiRedundantObjectFactory.c', - ] - - UNIFIED_SOURCES += [ -diff --git a/widget/gtk/mozcontainer.cpp b/widget/gtk/mozcontainer.cpp ---- a/widget/gtk/mozcontainer.cpp -+++ b/widget/gtk/mozcontainer.cpp -@@ -641,17 +641,19 @@ struct wl_egl_window* moz_container_get_ - return container->eglwindow; - } - - gboolean moz_container_has_wl_egl_window(MozContainer* container) { - return container->eglwindow ? true : false; - } - - gboolean moz_container_surface_needs_clear(MozContainer* container) { -- gboolean state = container->surface_needs_clear; -+ return container->surface_needs_clear; -+} -+ -+void moz_container_surface_cleared(MozContainer* container) { - container->surface_needs_clear = false; -- return state; - } - #endif - - void moz_container_force_default_visual(MozContainer* container) { - container->force_default_visual = true; - } -diff --git a/widget/gtk/mozcontainer.h b/widget/gtk/mozcontainer.h ---- a/widget/gtk/mozcontainer.h -+++ b/widget/gtk/mozcontainer.h -@@ -96,15 +96,16 @@ void moz_container_put(MozContainer* con - void moz_container_force_default_visual(MozContainer* container); - - #ifdef MOZ_WAYLAND - struct wl_surface* moz_container_get_wl_surface(MozContainer* container); - struct wl_egl_window* moz_container_get_wl_egl_window(MozContainer* container); - - gboolean moz_container_has_wl_egl_window(MozContainer* container); - gboolean moz_container_surface_needs_clear(MozContainer* container); -+void moz_container_surface_cleared(MozContainer* container); - void moz_container_scale_changed(MozContainer* container, - GtkAllocation* aAllocation); - void moz_container_set_initial_draw_callback( - MozContainer* container, std::function<void(void)> inital_draw_cb); - #endif - - #endif /* __MOZ_CONTAINER_H__ */ -diff --git a/widget/gtk/mozwayland/moz.build b/widget/gtk/mozwayland/moz.build ---- a/widget/gtk/mozwayland/moz.build -+++ b/widget/gtk/mozwayland/moz.build -@@ -2,12 +2,16 @@ - # vim: set filetype=python: - # 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/. - - SOURCES += [ - 'mozwayland.c', - ] -+EXPORTS.mozilla.widget += [ -+ 'mozwayland.h', -+] - - SharedLibrary('mozwayland') - - CFLAGS += CONFIG['TK_CFLAGS'] -+ -diff --git a/widget/gtk/nsWaylandDisplay.cpp b/widget/gtk/nsWaylandDisplay.cpp ---- a/widget/gtk/nsWaylandDisplay.cpp -+++ b/widget/gtk/nsWaylandDisplay.cpp -@@ -2,20 +2,16 @@ - /* vim:expandtab:shiftwidth=4:tabstop=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 "nsWaylandDisplay.h" - --#include "base/message_loop.h" // for MessageLoop --#include "base/task.h" // for NewRunnableMethod, etc --#include "mozilla/StaticMutex.h" -- - namespace mozilla { - namespace widget { - - // nsWaylandDisplay needs to be created for each calling thread(main thread, - // compositor thread and render thread) - #define MAX_DISPLAY_CONNECTIONS 3 - - static nsWaylandDisplay* gWaylandDisplays[MAX_DISPLAY_CONNECTIONS]; -@@ -107,16 +103,67 @@ void nsWaylandDisplay::SetDataDeviceMana - - void nsWaylandDisplay::SetSeat(wl_seat* aSeat) { mSeat = aSeat; } - - void nsWaylandDisplay::SetPrimarySelectionDeviceManager( - gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager) { - mPrimarySelectionDeviceManager = aPrimarySelectionDeviceManager; - } - -+#ifdef HAVE_LIBDRM -+void nsWaylandDisplay::SetDmabuf(zwp_linux_dmabuf_v1* aDmabuf) { -+ mDmabuf = aDmabuf; -+} -+ -+GbmFormat* nsWaylandDisplay::GetGbmFormat(bool aHasAlpha) { -+ GbmFormat* format = aHasAlpha ? &mARGBFormat : &mXRGBFormat; -+ return format->mIsSupported ? format : nullptr; -+} -+ -+void nsWaylandDisplay::AddFormatModifier(bool aHasAlpha, int aFormat, -+ uint32_t mModifierHi, -+ uint32_t mModifierLo) { -+ GbmFormat* format = aHasAlpha ? &mARGBFormat : &mXRGBFormat; -+ format->mIsSupported = true; -+ format->mHasAlpha = aHasAlpha; -+ format->mFormat = aFormat; -+ format->mModifiersCount++; -+ format->mModifiers = -+ (uint64_t*)realloc(format->mModifiers, -+ format->mModifiersCount * sizeof(*format->mModifiers)); -+ format->mModifiers[format->mModifiersCount - 1] = -+ ((uint64_t)mModifierHi << 32) | mModifierLo; -+} -+ -+static void dmabuf_modifiers(void* data, -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf, -+ uint32_t format, uint32_t modifier_hi, -+ uint32_t modifier_lo) { -+ auto display = reinterpret_cast<nsWaylandDisplay*>(data); -+ switch (format) { -+ case DRM_FORMAT_ARGB8888: -+ display->AddFormatModifier(true, format, modifier_hi, modifier_lo); -+ break; -+ case DRM_FORMAT_XRGB8888: -+ display->AddFormatModifier(false, format, modifier_hi, modifier_lo); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void dmabuf_format(void* data, -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf, -+ uint32_t format) { -+ // XXX: deprecated -+} -+ -+static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { -+ dmabuf_format, dmabuf_modifiers}; -+ - static void global_registry_handler(void* data, wl_registry* registry, - uint32_t id, const char* interface, - uint32_t version) { - auto display = reinterpret_cast<nsWaylandDisplay*>(data); - if (!display) return; - - if (strcmp(interface, "wl_shm") == 0) { - auto shm = static_cast<wl_shm*>( -@@ -144,16 +191,21 @@ static void global_registry_handler(void - display->GetEventQueue()); - display->SetPrimarySelectionDeviceManager(primary_selection_device_manager); - } else if (strcmp(interface, "wl_subcompositor") == 0) { - auto subcompositor = static_cast<wl_subcompositor*>( - wl_registry_bind(registry, id, &wl_subcompositor_interface, 1)); - wl_proxy_set_queue((struct wl_proxy*)subcompositor, - display->GetEventQueue()); - display->SetSubcompositor(subcompositor); -+ } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version > 2) { -+ auto dmabuf = static_cast<zwp_linux_dmabuf_v1*>( -+ wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 3)); -+ display->SetDmabuf(dmabuf); -+ zwp_linux_dmabuf_v1_add_listener(dmabuf, &dmabuf_listener, data); - } - } - - static void global_registry_remover(void* data, wl_registry* registry, - uint32_t id) {} - - static const struct wl_registry_listener registry_listener = { - global_registry_handler, global_registry_remover}; -@@ -162,27 +214,85 @@ bool nsWaylandDisplay::DispatchEventQueu - wl_display_dispatch_queue_pending(mDisplay, mEventQueue); - return true; - } - - bool nsWaylandDisplay::Matches(wl_display* aDisplay) { - return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay; - } - -+bool nsWaylandDisplay::ConfigureGbm() { -+ if (!nsGbmLib::IsAvailable()) { -+ return false; -+ } -+ -+ // TODO -+ const char* drm_render_node = getenv("MOZ_WAYLAND_DRM_DEVICE"); -+ if (!drm_render_node) { -+ drm_render_node = "/dev/dri/renderD128"; -+ } -+ -+ mGbmFd = open(drm_render_node, O_RDWR); -+ if (mGbmFd < 0) { -+ NS_WARNING( -+ nsPrintfCString("Failed to open drm render node %s\n", drm_render_node) -+ .get()); -+ return false; -+ } -+ -+ mGbmDevice = nsGbmLib::CreateDevice(mGbmFd); -+ if (mGbmDevice == nullptr) { -+ NS_WARNING(nsPrintfCString("Failed to create drm render device %s\n", -+ drm_render_node) -+ .get()); -+ close(mGbmFd); -+ return false; -+ } -+ -+ return true; -+} -+ -+gbm_device* nsWaylandDisplay::GetGbmDevice() { -+ if (!mGdmConfigured) { -+ ConfigureGbm(); -+ mGdmConfigured = true; -+ } -+ return mGbmDevice; -+} -+ -+int nsWaylandDisplay::GetGbmDeviceFd() { -+ if (!mGdmConfigured) { -+ ConfigureGbm(); -+ mGdmConfigured = true; -+ } -+ return mGbmFd; -+} -+#endif -+ - nsWaylandDisplay::nsWaylandDisplay(wl_display* aDisplay) - : mDispatcherThreadLoop(nullptr), - mThreadId(PR_GetCurrentThread()), - mDisplay(aDisplay), - mEventQueue(nullptr), - mDataDeviceManager(nullptr), - mSubcompositor(nullptr), - mSeat(nullptr), - mShm(nullptr), - mPrimarySelectionDeviceManager(nullptr), -- mRegistry(nullptr) { -+ mRegistry(nullptr) -+#ifdef HAVE_LIBDRM -+ , -+ mGbmDevice(nullptr), -+ mGbmFd(-1), -+ mGdmConfigured(false), -+ mExplicitSync(false), -+ mXRGBFormat({false, false, -1, nullptr, 0}), -+ mARGBFormat({false, false, -1, nullptr, 0}) -+#endif -+{ - mRegistry = wl_display_get_registry(mDisplay); - wl_registry_add_listener(mRegistry, ®istry_listener, this); - - if (NS_IsMainThread()) { - // Use default event queue in main thread operated by Gtk+. - mEventQueue = nullptr; - wl_display_roundtrip(mDisplay); - wl_display_roundtrip(mDisplay); -@@ -205,10 +315,84 @@ nsWaylandDisplay::~nsWaylandDisplay() { - mRegistry = nullptr; - - if (mEventQueue) { - wl_event_queue_destroy(mEventQueue); - mEventQueue = nullptr; - } - } - -+#ifdef HAVE_LIBDRM -+void* nsGbmLib::sGbmLibHandle = nullptr; -+void* nsGbmLib::sXf86DrmLibHandle = nullptr; -+bool nsGbmLib::sLibLoaded = false; -+CreateDeviceFunc nsGbmLib::sCreateDevice; -+CreateFunc nsGbmLib::sCreate; -+CreateWithModifiersFunc nsGbmLib::sCreateWithModifiers; -+GetModifierFunc nsGbmLib::sGetModifier; -+GetStrideFunc nsGbmLib::sGetStride; -+GetFdFunc nsGbmLib::sGetFd; -+DestroyFunc nsGbmLib::sDestroy; -+MapFunc nsGbmLib::sMap; -+UnmapFunc nsGbmLib::sUnmap; -+GetPlaneCountFunc nsGbmLib::sGetPlaneCount; -+GetHandleForPlaneFunc nsGbmLib::sGetHandleForPlane; -+GetStrideForPlaneFunc nsGbmLib::sGetStrideForPlane; -+GetOffsetFunc nsGbmLib::sGetOffset; -+DrmPrimeHandleToFDFunc nsGbmLib::sDrmPrimeHandleToFD; -+ -+bool nsGbmLib::IsAvailable() { -+ if (!Load()) { -+ return false; -+ } -+ return sCreateDevice != nullptr && sCreate != nullptr && -+ sCreateWithModifiers != nullptr && sGetModifier != nullptr && -+ sGetStride != nullptr && sGetFd != nullptr && sDestroy != nullptr && -+ sMap != nullptr && sUnmap != nullptr; -+} -+ -+bool nsGbmLib::IsModifierAvailable() { -+ if (!Load()) { -+ return false; -+ } -+ return sDrmPrimeHandleToFD != nullptr; -+} -+ -+bool nsGbmLib::Load() { -+ if (!sGbmLibHandle && !sLibLoaded) { -+ sLibLoaded = true; -+ -+ sGbmLibHandle = dlopen("libgbm.so", RTLD_LAZY | RTLD_LOCAL); -+ if (!sGbmLibHandle) { -+ return false; -+ } -+ -+ sCreateDevice = (CreateDeviceFunc)dlsym(sGbmLibHandle, "gbm_create_device"); -+ sCreate = (CreateFunc)dlsym(sGbmLibHandle, "gbm_bo_create"); -+ sCreateWithModifiers = (CreateWithModifiersFunc)dlsym( -+ sGbmLibHandle, "gbm_bo_create_with_modifiers"); -+ sGetModifier = (GetModifierFunc)dlsym(sGbmLibHandle, "gbm_bo_get_modifier"); -+ sGetStride = (GetStrideFunc)dlsym(sGbmLibHandle, "gbm_bo_get_stride"); -+ sGetFd = (GetFdFunc)dlsym(sGbmLibHandle, "gbm_bo_get_fd"); -+ sDestroy = (DestroyFunc)dlsym(sGbmLibHandle, "gbm_bo_destroy"); -+ sMap = (MapFunc)dlsym(sGbmLibHandle, "gbm_bo_map"); -+ sUnmap = (UnmapFunc)dlsym(sGbmLibHandle, "gbm_bo_unmap"); -+ sGetPlaneCount = -+ (GetPlaneCountFunc)dlsym(sGbmLibHandle, "gbm_bo_get_plane_count"); -+ sGetHandleForPlane = (GetHandleForPlaneFunc)dlsym( -+ sGbmLibHandle, "gbm_bo_get_handle_for_plane"); -+ sGetStrideForPlane = (GetStrideForPlaneFunc)dlsym( -+ sGbmLibHandle, "gbm_bo_get_stride_for_plane"); -+ sGetOffset = (GetOffsetFunc)dlsym(sGbmLibHandle, "gbm_bo_get_offset"); -+ -+ sXf86DrmLibHandle = dlopen("libdrm.so", RTLD_LAZY | RTLD_LOCAL); -+ if (sXf86DrmLibHandle) { -+ sDrmPrimeHandleToFD = (DrmPrimeHandleToFDFunc)dlsym(sXf86DrmLibHandle, -+ "drmPrimeHandleToFD"); -+ } -+ } -+ -+ return sGbmLibHandle; -+} -+#endif -+ - } // namespace widget - } // namespace mozilla -diff --git a/widget/gtk/nsWaylandDisplay.h b/widget/gtk/nsWaylandDisplay.h ---- a/widget/gtk/nsWaylandDisplay.h -+++ b/widget/gtk/nsWaylandDisplay.h -@@ -1,24 +1,43 @@ - /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=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 __MOZ_WAYLAND_REGISTRY_H__ --#define __MOZ_WAYLAND_REGISTRY_H__ -+#ifndef __MOZ_WAYLAND_DISPLAY_H__ -+#define __MOZ_WAYLAND_DISPLAY_H__ -+ -+#include "mozilla/widget/mozwayland.h" -+#include "mozilla/widget/gtk-primary-selection-client-protocol.h" - --#include "mozwayland/mozwayland.h" --#include "wayland/gtk-primary-selection-client-protocol.h" -+#include "base/message_loop.h" // for MessageLoop -+#include "base/task.h" // for NewRunnableMethod, etc -+#include "mozilla/StaticMutex.h" -+ -+#ifdef HAVE_LIBDRM -+# include <drm/drm_fourcc.h> -+# include <xf86drm.h> -+# include <gbm.h> -+# include "mozilla/widget/linux-dmabuf-unstable-v1-client-protocol.h" -+#endif - - namespace mozilla { - namespace widget { - -+struct GbmFormat { -+ bool mIsSupported; -+ bool mHasAlpha; -+ int mFormat; -+ uint64_t* mModifiers; -+ int mModifiersCount; -+}; -+ - // Our general connection to Wayland display server, - // holds our display connection and runs event loop. - class nsWaylandDisplay { - public: - explicit nsWaylandDisplay(wl_display* aDisplay); - virtual ~nsWaylandDisplay(); - - bool DispatchEventQueue(); -@@ -41,28 +60,143 @@ class nsWaylandDisplay { - void SetSubcompositor(wl_subcompositor* aSubcompositor); - void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager); - void SetSeat(wl_seat* aSeat); - void SetPrimarySelectionDeviceManager( - gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager); - - void Shutdown(); - -+#ifdef HAVE_LIBDRM -+ void SetDmabuf(zwp_linux_dmabuf_v1* aDmabuf); -+ zwp_linux_dmabuf_v1* GetDmabuf() { return mDmabuf; }; -+ gbm_device* GetGbmDevice(); -+ int GetGbmDeviceFd(); -+ bool IsExplicitSyncEnabled() { return mExplicitSync; } -+ GbmFormat* GetGbmFormat(bool aHasAlpha); -+ void AddFormatModifier(bool aHasAlpha, int aFormat, uint32_t mModifierHi, -+ uint32_t mModifierLo); -+#endif -+ - private: -+#ifdef HAVE_LIBDRM -+ bool ConfigureGbm(); -+#endif -+ - MessageLoop* mDispatcherThreadLoop; - PRThread* mThreadId; - wl_display* mDisplay; - wl_event_queue* mEventQueue; - wl_data_device_manager* mDataDeviceManager; - wl_subcompositor* mSubcompositor; - wl_seat* mSeat; - wl_shm* mShm; - gtk_primary_selection_device_manager* mPrimarySelectionDeviceManager; - wl_registry* mRegistry; -+#ifdef HAVE_LIBDRM -+ zwp_linux_dmabuf_v1* mDmabuf; -+ gbm_device* mGbmDevice; -+ int mGbmFd; -+ bool mGdmConfigured; -+ bool mExplicitSync; -+ GbmFormat mXRGBFormat; -+ GbmFormat mARGBFormat; -+#endif - }; - - void WaylandDispatchDisplays(); - nsWaylandDisplay* WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr); - -+#ifdef HAVE_LIBDRM -+typedef struct gbm_device* (*CreateDeviceFunc)(int); -+typedef struct gbm_bo* (*CreateFunc)(struct gbm_device*, uint32_t, uint32_t, -+ uint32_t, uint32_t); -+typedef struct gbm_bo* (*CreateFunc)(struct gbm_device*, uint32_t, uint32_t, -+ uint32_t, uint32_t); -+typedef struct gbm_bo* (*CreateWithModifiersFunc)(struct gbm_device*, uint32_t, -+ uint32_t, uint32_t, -+ const uint64_t*, -+ const unsigned int); -+typedef uint64_t (*GetModifierFunc)(struct gbm_bo*); -+typedef uint32_t (*GetStrideFunc)(struct gbm_bo*); -+typedef int (*GetFdFunc)(struct gbm_bo*); -+typedef void (*DestroyFunc)(struct gbm_bo*); -+typedef void* (*MapFunc)(struct gbm_bo*, uint32_t, uint32_t, uint32_t, uint32_t, -+ uint32_t, uint32_t*, void**); -+typedef void (*UnmapFunc)(struct gbm_bo*, void*); -+typedef int (*GetPlaneCountFunc)(struct gbm_bo*); -+typedef union gbm_bo_handle (*GetHandleForPlaneFunc)(struct gbm_bo*, int); -+typedef uint32_t (*GetStrideForPlaneFunc)(struct gbm_bo*, int); -+typedef uint32_t (*GetOffsetFunc)(struct gbm_bo*, int); -+ -+typedef int (*DrmPrimeHandleToFDFunc)(int, uint32_t, uint32_t, int*); -+ -+class nsGbmLib { -+ public: -+ static bool Load(); -+ static bool IsAvailable(); -+ static bool IsModifierAvailable(); -+ -+ static struct gbm_device* CreateDevice(int fd) { return sCreateDevice(fd); }; -+ static struct gbm_bo* Create(struct gbm_device* gbm, uint32_t width, -+ uint32_t height, uint32_t format, -+ uint32_t flags) { -+ return sCreate(gbm, width, height, format, flags); -+ } -+ static void Destroy(struct gbm_bo* bo) { sDestroy(bo); } -+ static uint32_t GetStride(struct gbm_bo* bo) { return sGetStride(bo); } -+ static int GetFd(struct gbm_bo* bo) { return sGetFd(bo); } -+ static void* Map(struct gbm_bo* bo, uint32_t x, uint32_t y, uint32_t width, -+ uint32_t height, uint32_t flags, uint32_t* stride, -+ void** map_data) { -+ return sMap(bo, x, y, width, height, flags, stride, map_data); -+ } -+ static void Unmap(struct gbm_bo* bo, void* map_data) { sUnmap(bo, map_data); } -+ static struct gbm_bo* CreateWithModifiers(struct gbm_device* gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, -+ const uint64_t* modifiers, -+ const unsigned int count) { -+ return sCreateWithModifiers(gbm, width, height, format, modifiers, count); -+ } -+ static uint64_t GetModifier(struct gbm_bo* bo) { return sGetModifier(bo); } -+ static int GetPlaneCount(struct gbm_bo* bo) { return sGetPlaneCount(bo); } -+ static union gbm_bo_handle GetHandleForPlane(struct gbm_bo* bo, int plane) { -+ return sGetHandleForPlane(bo, plane); -+ } -+ static uint32_t GetStrideForPlane(struct gbm_bo* bo, int plane) { -+ return sGetStrideForPlane(bo, plane); -+ } -+ static uint32_t GetOffset(struct gbm_bo* bo, int plane) { -+ return sGetOffset(bo, plane); -+ } -+ -+ static int DrmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, -+ int* prime_fd) { -+ return sDrmPrimeHandleToFD(fd, handle, flags, prime_fd); -+ } -+ -+ private: -+ static CreateDeviceFunc sCreateDevice; -+ static CreateFunc sCreate; -+ static CreateWithModifiersFunc sCreateWithModifiers; -+ static GetModifierFunc sGetModifier; -+ static GetStrideFunc sGetStride; -+ static GetFdFunc sGetFd; -+ static DestroyFunc sDestroy; -+ static MapFunc sMap; -+ static UnmapFunc sUnmap; -+ static GetPlaneCountFunc sGetPlaneCount; -+ static GetHandleForPlaneFunc sGetHandleForPlane; -+ static GetStrideForPlaneFunc sGetStrideForPlane; -+ static GetOffsetFunc sGetOffset; -+ static DrmPrimeHandleToFDFunc sDrmPrimeHandleToFD; -+ -+ static void* sGbmLibHandle; -+ static void* sXf86DrmLibHandle; -+ static bool sLibLoaded; -+}; -+#endif -+ - } // namespace widget - } // namespace mozilla - --#endif // __MOZ_WAYLAND_REGISTRY_H__ -+#endif // __MOZ_WAYLAND_DISPLAY_H__ -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -4237,17 +4237,18 @@ LayoutDeviceIntSize nsWindow::GetSafeWin - // reads it as CARD16. Sizes of pixmaps, used for drawing, are (unsigned) - // CARD16 in the protocol, but the server's ProcCreatePixmap returns - // BadAlloc if dimensions cannot be represented by signed shorts. - // Because we are creating Cairo surfaces to represent window buffers, - // we also must ensure that the window can fit in a Cairo surface. - LayoutDeviceIntSize result = aSize; - int32_t maxSize = 32767; - if (mLayerManager && mLayerManager->AsKnowsCompositor()) { -- maxSize = std::min(maxSize, mLayerManager->AsKnowsCompositor()->GetMaxTextureSize()); -+ maxSize = std::min(maxSize, -+ mLayerManager->AsKnowsCompositor()->GetMaxTextureSize()); - } - if (result.width > maxSize) { - result.width = maxSize; - } - if (result.height > maxSize) { - result.height = maxSize; - } - return result; -@@ -6827,21 +6828,24 @@ wl_surface* nsWindow::GetWaylandSurface( - "drawing!"); - return nullptr; - } - - bool nsWindow::WaylandSurfaceNeedsClear() { - if (mContainer) { - return moz_container_surface_needs_clear(MOZ_CONTAINER(mContainer)); - } -- -- NS_WARNING( -- "nsWindow::WaylandSurfaceNeedsClear(): We don't have any mContainer!"); - return false; - } -+ -+void nsWindow::WaylandSurfaceCleared() { -+ if (mContainer) { -+ return moz_container_surface_cleared(MOZ_CONTAINER(mContainer)); -+ } -+} - #endif - - #ifdef MOZ_X11 - /* XApp progress support currently works by setting a property - * on a window with this Atom name. A supporting window manager - * will notice this and pass it along to whatever handling has - * been implemented on that end (e.g. passing it on to a taskbar - * widget.) There is no issue if WM support is lacking, this is -diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h ---- a/widget/gtk/nsWindow.h -+++ b/widget/gtk/nsWindow.h -@@ -341,16 +341,17 @@ class nsWindow final : public nsBaseWidg - - #ifdef MOZ_X11 - Display* XDisplay() { return mXDisplay; } - #endif - #ifdef MOZ_WAYLAND - wl_display* GetWaylandDisplay(); - wl_surface* GetWaylandSurface(); - bool WaylandSurfaceNeedsClear(); -+ void WaylandSurfaceCleared(); - #endif - virtual void GetCompositorWidgetInitData( - mozilla::widget::CompositorWidgetInitData* aInitData) override; - - virtual nsresult SetNonClientMargins( - LayoutDeviceIntMargin& aMargins) override; - void SetDrawsInTitlebar(bool aState) override; - virtual void UpdateWindowDraggingRegion( -diff --git a/widget/gtk/wayland/linux-dmabuf-unstable-v1-client-protocol.h b/widget/gtk/wayland/linux-dmabuf-unstable-v1-client-protocol.h -new file mode 100644 ---- /dev/null -+++ b/widget/gtk/wayland/linux-dmabuf-unstable-v1-client-protocol.h -@@ -0,0 +1,650 @@ -+/* Generated by wayland-scanner 1.17.0 */ -+ -+#ifndef LINUX_DMABUF_UNSTABLE_V1_CLIENT_PROTOCOL_H -+#define LINUX_DMABUF_UNSTABLE_V1_CLIENT_PROTOCOL_H -+ -+#include <stdint.h> -+#include <stddef.h> -+#include "wayland-client.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/** -+ * @page page_linux_dmabuf_unstable_v1 The linux_dmabuf_unstable_v1 protocol -+ * @section page_ifaces_linux_dmabuf_unstable_v1 Interfaces -+ * - @subpage page_iface_zwp_linux_dmabuf_v1 - factory for creating dmabuf-based -+ * wl_buffers -+ * - @subpage page_iface_zwp_linux_buffer_params_v1 - parameters for creating a -+ * dmabuf-based wl_buffer -+ * @section page_copyright_linux_dmabuf_unstable_v1 Copyright -+ * <pre> -+ * -+ * Copyright © 2014, 2015 Collabora, Ltd. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ * </pre> -+ */ -+struct wl_buffer; -+struct zwp_linux_buffer_params_v1; -+struct zwp_linux_dmabuf_v1; -+ -+/** -+ * @page page_iface_zwp_linux_dmabuf_v1 zwp_linux_dmabuf_v1 -+ * @section page_iface_zwp_linux_dmabuf_v1_desc Description -+ * -+ * Following the interfaces from: -+ * https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt -+ * and the Linux DRM sub-system's AddFb2 ioctl. -+ * -+ * This interface offers ways to create generic dmabuf-based -+ * wl_buffers. Immediately after a client binds to this interface, -+ * the set of supported formats and format modifiers is sent with -+ * 'format' and 'modifier' events. -+ * -+ * The following are required from clients: -+ * -+ * - Clients must ensure that either all data in the dma-buf is -+ * coherent for all subsequent read access or that coherency is -+ * correctly handled by the underlying kernel-side dma-buf -+ * implementation. -+ * -+ * - Don't make any more attachments after sending the buffer to the -+ * compositor. Making more attachments later increases the risk of -+ * the compositor not being able to use (re-import) an existing -+ * dmabuf-based wl_buffer. -+ * -+ * The underlying graphics stack must ensure the following: -+ * -+ * - The dmabuf file descriptors relayed to the server will stay valid -+ * for the whole lifetime of the wl_buffer. This means the server may -+ * at any time use those fds to import the dmabuf into any kernel -+ * sub-system that might accept it. -+ * -+ * To create a wl_buffer from one or more dmabufs, a client creates a -+ * zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params -+ * request. All planes required by the intended format are added with -+ * the 'add' request. Finally, a 'create' or 'create_immed' request is -+ * issued, which has the following outcome depending on the import success. -+ * -+ * The 'create' request, -+ * - on success, triggers a 'created' event which provides the final -+ * wl_buffer to the client. -+ * - on failure, triggers a 'failed' event to convey that the server -+ * cannot use the dmabufs received from the client. -+ * -+ * For the 'create_immed' request, -+ * - on success, the server immediately imports the added dmabufs to -+ * create a wl_buffer. No event is sent from the server in this case. -+ * - on failure, the server can choose to either: -+ * - terminate the client by raising a fatal error. -+ * - mark the wl_buffer as failed, and send a 'failed' event to the -+ * client. If the client uses a failed wl_buffer as an argument to any -+ * request, the behaviour is compositor implementation-defined. -+ * -+ * Warning! The protocol described in this file is experimental and -+ * backward incompatible changes may be made. Backward compatible changes -+ * may be added together with the corresponding interface version bump. -+ * Backward incompatible changes are done by bumping the version number in -+ * the protocol and interface names and resetting the interface version. -+ * Once the protocol is to be declared stable, the 'z' prefix and the -+ * version number in the protocol and interface names are removed and the -+ * interface version number is reset. -+ * @section page_iface_zwp_linux_dmabuf_v1_api API -+ * See @ref iface_zwp_linux_dmabuf_v1. -+ */ -+/** -+ * @defgroup iface_zwp_linux_dmabuf_v1 The zwp_linux_dmabuf_v1 interface -+ * -+ * Following the interfaces from: -+ * https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt -+ * and the Linux DRM sub-system's AddFb2 ioctl. -+ * -+ * This interface offers ways to create generic dmabuf-based -+ * wl_buffers. Immediately after a client binds to this interface, -+ * the set of supported formats and format modifiers is sent with -+ * 'format' and 'modifier' events. -+ * -+ * The following are required from clients: -+ * -+ * - Clients must ensure that either all data in the dma-buf is -+ * coherent for all subsequent read access or that coherency is -+ * correctly handled by the underlying kernel-side dma-buf -+ * implementation. -+ * -+ * - Don't make any more attachments after sending the buffer to the -+ * compositor. Making more attachments later increases the risk of -+ * the compositor not being able to use (re-import) an existing -+ * dmabuf-based wl_buffer. -+ * -+ * The underlying graphics stack must ensure the following: -+ * -+ * - The dmabuf file descriptors relayed to the server will stay valid -+ * for the whole lifetime of the wl_buffer. This means the server may -+ * at any time use those fds to import the dmabuf into any kernel -+ * sub-system that might accept it. -+ * -+ * To create a wl_buffer from one or more dmabufs, a client creates a -+ * zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params -+ * request. All planes required by the intended format are added with -+ * the 'add' request. Finally, a 'create' or 'create_immed' request is -+ * issued, which has the following outcome depending on the import success. -+ * -+ * The 'create' request, -+ * - on success, triggers a 'created' event which provides the final -+ * wl_buffer to the client. -+ * - on failure, triggers a 'failed' event to convey that the server -+ * cannot use the dmabufs received from the client. -+ * -+ * For the 'create_immed' request, -+ * - on success, the server immediately imports the added dmabufs to -+ * create a wl_buffer. No event is sent from the server in this case. -+ * - on failure, the server can choose to either: -+ * - terminate the client by raising a fatal error. -+ * - mark the wl_buffer as failed, and send a 'failed' event to the -+ * client. If the client uses a failed wl_buffer as an argument to any -+ * request, the behaviour is compositor implementation-defined. -+ * -+ * Warning! The protocol described in this file is experimental and -+ * backward incompatible changes may be made. Backward compatible changes -+ * may be added together with the corresponding interface version bump. -+ * Backward incompatible changes are done by bumping the version number in -+ * the protocol and interface names and resetting the interface version. -+ * Once the protocol is to be declared stable, the 'z' prefix and the -+ * version number in the protocol and interface names are removed and the -+ * interface version number is reset. -+ */ -+extern const struct wl_interface zwp_linux_dmabuf_v1_interface; -+/** -+ * @page page_iface_zwp_linux_buffer_params_v1 zwp_linux_buffer_params_v1 -+ * @section page_iface_zwp_linux_buffer_params_v1_desc Description -+ * -+ * This temporary object is a collection of dmabufs and other -+ * parameters that together form a single logical buffer. The temporary -+ * object may eventually create one wl_buffer unless cancelled by -+ * destroying it before requesting 'create'. -+ * -+ * Single-planar formats only require one dmabuf, however -+ * multi-planar formats may require more than one dmabuf. For all -+ * formats, an 'add' request must be called once per plane (even if the -+ * underlying dmabuf fd is identical). -+ * -+ * You must use consecutive plane indices ('plane_idx' argument for 'add') -+ * from zero to the number of planes used by the drm_fourcc format code. -+ * All planes required by the format must be given exactly once, but can -+ * be given in any order. Each plane index can be set only once. -+ * @section page_iface_zwp_linux_buffer_params_v1_api API -+ * See @ref iface_zwp_linux_buffer_params_v1. -+ */ -+/** -+ * @defgroup iface_zwp_linux_buffer_params_v1 The zwp_linux_buffer_params_v1 -+ * interface -+ * -+ * This temporary object is a collection of dmabufs and other -+ * parameters that together form a single logical buffer. The temporary -+ * object may eventually create one wl_buffer unless cancelled by -+ * destroying it before requesting 'create'. -+ * -+ * Single-planar formats only require one dmabuf, however -+ * multi-planar formats may require more than one dmabuf. For all -+ * formats, an 'add' request must be called once per plane (even if the -+ * underlying dmabuf fd is identical). -+ * -+ * You must use consecutive plane indices ('plane_idx' argument for 'add') -+ * from zero to the number of planes used by the drm_fourcc format code. -+ * All planes required by the format must be given exactly once, but can -+ * be given in any order. Each plane index can be set only once. -+ */ -+extern const struct wl_interface zwp_linux_buffer_params_v1_interface; -+ -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ * @struct zwp_linux_dmabuf_v1_listener -+ */ -+struct zwp_linux_dmabuf_v1_listener { -+ /** -+ * supported buffer format -+ * -+ * This event advertises one buffer format that the server -+ * supports. All the supported formats are advertised once when the -+ * client binds to this interface. A roundtrip after binding -+ * guarantees that the client has received all supported formats. -+ * -+ * For the definition of the format codes, see the -+ * zwp_linux_buffer_params_v1::create request. -+ * -+ * Warning: the 'format' event is likely to be deprecated and -+ * replaced with the 'modifier' event introduced in -+ * zwp_linux_dmabuf_v1 version 3, described below. Please refrain -+ * from using the information received from this event. -+ * @param format DRM_FORMAT code -+ */ -+ void (*format)(void* data, struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1, -+ uint32_t format); -+ /** -+ * supported buffer format modifier -+ * -+ * This event advertises the formats that the server supports, -+ * along with the modifiers supported for each format. All the -+ * supported modifiers for all the supported formats are advertised -+ * once when the client binds to this interface. A roundtrip after -+ * binding guarantees that the client has received all supported -+ * format-modifier pairs. -+ * -+ * For the definition of the format and modifier codes, see the -+ * zwp_linux_buffer_params_v1::create request. -+ * @param format DRM_FORMAT code -+ * @param modifier_hi high 32 bits of layout modifier -+ * @param modifier_lo low 32 bits of layout modifier -+ * @since 3 -+ */ -+ void (*modifier)(void* data, struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1, -+ uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo); -+}; -+ -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ */ -+static inline int zwp_linux_dmabuf_v1_add_listener( -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1, -+ const struct zwp_linux_dmabuf_v1_listener* listener, void* data) { -+ return wl_proxy_add_listener((struct wl_proxy*)zwp_linux_dmabuf_v1, -+ (void (**)(void))listener, data); -+} -+ -+#define ZWP_LINUX_DMABUF_V1_DESTROY 0 -+#define ZWP_LINUX_DMABUF_V1_CREATE_PARAMS 1 -+ -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ */ -+#define ZWP_LINUX_DMABUF_V1_FORMAT_SINCE_VERSION 1 -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ */ -+#define ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION 3 -+ -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ */ -+#define ZWP_LINUX_DMABUF_V1_DESTROY_SINCE_VERSION 1 -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ */ -+#define ZWP_LINUX_DMABUF_V1_CREATE_PARAMS_SINCE_VERSION 1 -+ -+/** @ingroup iface_zwp_linux_dmabuf_v1 */ -+static inline void zwp_linux_dmabuf_v1_set_user_data( -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1, void* user_data) { -+ wl_proxy_set_user_data((struct wl_proxy*)zwp_linux_dmabuf_v1, user_data); -+} -+ -+/** @ingroup iface_zwp_linux_dmabuf_v1 */ -+static inline void* zwp_linux_dmabuf_v1_get_user_data( -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1) { -+ return wl_proxy_get_user_data((struct wl_proxy*)zwp_linux_dmabuf_v1); -+} -+ -+static inline uint32_t zwp_linux_dmabuf_v1_get_version( -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1) { -+ return wl_proxy_get_version((struct wl_proxy*)zwp_linux_dmabuf_v1); -+} -+ -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ * -+ * Objects created through this interface, especially wl_buffers, will -+ * remain valid. -+ */ -+static inline void zwp_linux_dmabuf_v1_destroy( -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1) { -+ wl_proxy_marshal((struct wl_proxy*)zwp_linux_dmabuf_v1, -+ ZWP_LINUX_DMABUF_V1_DESTROY); -+ -+ wl_proxy_destroy((struct wl_proxy*)zwp_linux_dmabuf_v1); -+} -+ -+/** -+ * @ingroup iface_zwp_linux_dmabuf_v1 -+ * -+ * This temporary object is used to collect multiple dmabuf handles into -+ * a single batch to create a wl_buffer. It can only be used once and -+ * should be destroyed after a 'created' or 'failed' event has been -+ * received. -+ */ -+static inline struct zwp_linux_buffer_params_v1* -+zwp_linux_dmabuf_v1_create_params( -+ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf_v1) { -+ struct wl_proxy* params_id; -+ -+ params_id = wl_proxy_marshal_constructor( -+ (struct wl_proxy*)zwp_linux_dmabuf_v1, ZWP_LINUX_DMABUF_V1_CREATE_PARAMS, -+ &zwp_linux_buffer_params_v1_interface, NULL); -+ -+ return (struct zwp_linux_buffer_params_v1*)params_id; -+} -+ -+#ifndef ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ENUM -+# define ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ENUM -+enum zwp_linux_buffer_params_v1_error { -+ /** -+ * the dmabuf_batch object has already been used to create a wl_buffer -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED = 0, -+ /** -+ * plane index out of bounds -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX = 1, -+ /** -+ * the plane index was already set -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET = 2, -+ /** -+ * missing or too many planes to create a buffer -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE = 3, -+ /** -+ * format not supported -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT = 4, -+ /** -+ * invalid width or height -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS = 5, -+ /** -+ * offset + stride * height goes out of dmabuf bounds -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS = 6, -+ /** -+ * invalid wl_buffer resulted from importing dmabufs via the -+ * create_immed request on given buffer_params -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER = 7, -+}; -+#endif /* ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ENUM */ -+ -+#ifndef ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_ENUM -+# define ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_ENUM -+enum zwp_linux_buffer_params_v1_flags { -+ /** -+ * contents are y-inverted -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT = 1, -+ /** -+ * content is interlaced -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED = 2, -+ /** -+ * bottom field first -+ */ -+ ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST = 4, -+}; -+#endif /* ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_ENUM */ -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ * @struct zwp_linux_buffer_params_v1_listener -+ */ -+struct zwp_linux_buffer_params_v1_listener { -+ /** -+ * buffer creation succeeded -+ * -+ * This event indicates that the attempted buffer creation was -+ * successful. It provides the new wl_buffer referencing the -+ * dmabuf(s). -+ * -+ * Upon receiving this event, the client should destroy the -+ * zlinux_dmabuf_params object. -+ * @param buffer the newly created wl_buffer -+ */ -+ void (*created)(void* data, -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, -+ struct wl_buffer* buffer); -+ /** -+ * buffer creation failed -+ * -+ * This event indicates that the attempted buffer creation has -+ * failed. It usually means that one of the dmabuf constraints has -+ * not been fulfilled. -+ * -+ * Upon receiving this event, the client should destroy the -+ * zlinux_buffer_params object. -+ */ -+ void (*failed)(void* data, -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1); -+}; -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+static inline int zwp_linux_buffer_params_v1_add_listener( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, -+ const struct zwp_linux_buffer_params_v1_listener* listener, void* data) { -+ return wl_proxy_add_listener((struct wl_proxy*)zwp_linux_buffer_params_v1, -+ (void (**)(void))listener, data); -+} -+ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_DESTROY 0 -+#define ZWP_LINUX_BUFFER_PARAMS_V1_ADD 1 -+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE 2 -+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_IMMED 3 -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATED_SINCE_VERSION 1 -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_FAILED_SINCE_VERSION 1 -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_DESTROY_SINCE_VERSION 1 -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_ADD_SINCE_VERSION 1 -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_SINCE_VERSION 1 -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ */ -+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_IMMED_SINCE_VERSION 2 -+ -+/** @ingroup iface_zwp_linux_buffer_params_v1 */ -+static inline void zwp_linux_buffer_params_v1_set_user_data( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, -+ void* user_data) { -+ wl_proxy_set_user_data((struct wl_proxy*)zwp_linux_buffer_params_v1, -+ user_data); -+} -+ -+/** @ingroup iface_zwp_linux_buffer_params_v1 */ -+static inline void* zwp_linux_buffer_params_v1_get_user_data( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1) { -+ return wl_proxy_get_user_data((struct wl_proxy*)zwp_linux_buffer_params_v1); -+} -+ -+static inline uint32_t zwp_linux_buffer_params_v1_get_version( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1) { -+ return wl_proxy_get_version((struct wl_proxy*)zwp_linux_buffer_params_v1); -+} -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ * -+ * Cleans up the temporary data sent to the server for dmabuf-based -+ * wl_buffer creation. -+ */ -+static inline void zwp_linux_buffer_params_v1_destroy( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1) { -+ wl_proxy_marshal((struct wl_proxy*)zwp_linux_buffer_params_v1, -+ ZWP_LINUX_BUFFER_PARAMS_V1_DESTROY); -+ -+ wl_proxy_destroy((struct wl_proxy*)zwp_linux_buffer_params_v1); -+} -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ * -+ * This request adds one dmabuf to the set in this -+ * zwp_linux_buffer_params_v1. -+ * -+ * The 64-bit unsigned value combined from modifier_hi and modifier_lo -+ * is the dmabuf layout modifier. DRM AddFB2 ioctl calls this the -+ * fb modifier, which is defined in drm_mode.h of Linux UAPI. -+ * This is an opaque token. Drivers use this token to express tiling, -+ * compression, etc. driver-specific modifications to the base format -+ * defined by the DRM fourcc code. -+ * -+ * This request raises the PLANE_IDX error if plane_idx is too large. -+ * The error PLANE_SET is raised if attempting to set a plane that -+ * was already set. -+ */ -+static inline void zwp_linux_buffer_params_v1_add( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, int32_t fd, -+ uint32_t plane_idx, uint32_t offset, uint32_t stride, uint32_t modifier_hi, -+ uint32_t modifier_lo) { -+ wl_proxy_marshal((struct wl_proxy*)zwp_linux_buffer_params_v1, -+ ZWP_LINUX_BUFFER_PARAMS_V1_ADD, fd, plane_idx, offset, -+ stride, modifier_hi, modifier_lo); -+} -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ * -+ * This asks for creation of a wl_buffer from the added dmabuf -+ * buffers. The wl_buffer is not created immediately but returned via -+ * the 'created' event if the dmabuf sharing succeeds. The sharing -+ * may fail at runtime for reasons a client cannot predict, in -+ * which case the 'failed' event is triggered. -+ * -+ * The 'format' argument is a DRM_FORMAT code, as defined by the -+ * libdrm's drm_fourcc.h. The Linux kernel's DRM sub-system is the -+ * authoritative source on how the format codes should work. -+ * -+ * The 'flags' is a bitfield of the flags defined in enum "flags". -+ * 'y_invert' means the that the image needs to be y-flipped. -+ * -+ * Flag 'interlaced' means that the frame in the buffer is not -+ * progressive as usual, but interlaced. An interlaced buffer as -+ * supported here must always contain both top and bottom fields. -+ * The top field always begins on the first pixel row. The temporal -+ * ordering between the two fields is top field first, unless -+ * 'bottom_first' is specified. It is undefined whether 'bottom_first' -+ * is ignored if 'interlaced' is not set. -+ * -+ * This protocol does not convey any information about field rate, -+ * duration, or timing, other than the relative ordering between the -+ * two fields in one buffer. A compositor may have to estimate the -+ * intended field rate from the incoming buffer rate. It is undefined -+ * whether the time of receiving wl_surface.commit with a new buffer -+ * attached, applying the wl_surface state, wl_surface.frame callback -+ * trigger, presentation, or any other point in the compositor cycle -+ * is used to measure the frame or field times. There is no support -+ * for detecting missed or late frames/fields/buffers either, and -+ * there is no support whatsoever for cooperating with interlaced -+ * compositor output. -+ * -+ * The composited image quality resulting from the use of interlaced -+ * buffers is explicitly undefined. A compositor may use elaborate -+ * hardware features or software to deinterlace and create progressive -+ * output frames from a sequence of interlaced input buffers, or it -+ * may produce substandard image quality. However, compositors that -+ * cannot guarantee reasonable image quality in all cases are recommended -+ * to just reject all interlaced buffers. -+ * -+ * Any argument errors, including non-positive width or height, -+ * mismatch between the number of planes and the format, bad -+ * format, bad offset or stride, may be indicated by fatal protocol -+ * errors: INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, -+ * OUT_OF_BOUNDS. -+ * -+ * Dmabuf import errors in the server that are not obvious client -+ * bugs are returned via the 'failed' event as non-fatal. This -+ * allows attempting dmabuf sharing and falling back in the client -+ * if it fails. -+ * -+ * This request can be sent only once in the object's lifetime, after -+ * which the only legal request is destroy. This object should be -+ * destroyed after issuing a 'create' request. Attempting to use this -+ * object after issuing 'create' raises ALREADY_USED protocol error. -+ * -+ * It is not mandatory to issue 'create'. If a client wants to -+ * cancel the buffer creation, it can just destroy this object. -+ */ -+static inline void zwp_linux_buffer_params_v1_create( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, -+ int32_t width, int32_t height, uint32_t format, uint32_t flags) { -+ wl_proxy_marshal((struct wl_proxy*)zwp_linux_buffer_params_v1, -+ ZWP_LINUX_BUFFER_PARAMS_V1_CREATE, width, height, format, -+ flags); -+} -+ -+/** -+ * @ingroup iface_zwp_linux_buffer_params_v1 -+ * -+ * This asks for immediate creation of a wl_buffer by importing the -+ * added dmabufs. -+ * -+ * In case of import success, no event is sent from the server, and the -+ * wl_buffer is ready to be used by the client. -+ * -+ * Upon import failure, either of the following may happen, as seen fit -+ * by the implementation: -+ * - the client is terminated with one of the following fatal protocol -+ * errors: -+ * - INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS, -+ * in case of argument errors such as mismatch between the number -+ * of planes and the format, bad format, non-positive width or -+ * height, or bad offset or stride. -+ * - INVALID_WL_BUFFER, in case the cause for failure is unknown or -+ * plaform specific. -+ * - the server creates an invalid wl_buffer, marks it as failed and -+ * sends a 'failed' event to the client. The result of using this -+ * invalid wl_buffer as an argument in any request by the client is -+ * defined by the compositor implementation. -+ * -+ * This takes the same arguments as a 'create' request, and obeys the -+ * same restrictions. -+ */ -+static inline struct wl_buffer* zwp_linux_buffer_params_v1_create_immed( -+ struct zwp_linux_buffer_params_v1* zwp_linux_buffer_params_v1, -+ int32_t width, int32_t height, uint32_t format, uint32_t flags) { -+ struct wl_proxy* buffer_id; -+ -+ buffer_id = wl_proxy_marshal_constructor( -+ (struct wl_proxy*)zwp_linux_buffer_params_v1, -+ ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_IMMED, &wl_buffer_interface, NULL, -+ width, height, format, flags); -+ -+ return (struct wl_buffer*)buffer_id; -+} -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/widget/gtk/wayland/linux-dmabuf-unstable-v1-protocol.c b/widget/gtk/wayland/linux-dmabuf-unstable-v1-protocol.c -new file mode 100644 ---- /dev/null -+++ b/widget/gtk/wayland/linux-dmabuf-unstable-v1-protocol.c -@@ -0,0 +1,81 @@ -+/* Generated by wayland-scanner 1.17.0 */ -+ -+/* -+ * Copyright © 2014, 2015 Collabora, Ltd. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include <stdlib.h> -+#include <stdint.h> -+#include "wayland-util.h" -+ -+#pragma GCC visibility push(default) -+extern const struct wl_interface wl_buffer_interface; -+extern const struct wl_interface zwp_linux_buffer_params_v1_interface; -+#pragma GCC visibility pop -+ -+static const struct wl_interface* types[] = { -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ &zwp_linux_buffer_params_v1_interface, -+ &wl_buffer_interface, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ &wl_buffer_interface, -+}; -+ -+static const struct wl_message zwp_linux_dmabuf_v1_requests[] = { -+ {"destroy", "", types + 0}, -+ {"create_params", "n", types + 6}, -+}; -+ -+static const struct wl_message zwp_linux_dmabuf_v1_events[] = { -+ {"format", "u", types + 0}, -+ {"modifier", "3uuu", types + 0}, -+}; -+ -+const struct wl_interface zwp_linux_dmabuf_v1_interface = { -+ "zwp_linux_dmabuf_v1", 3, 2, -+ zwp_linux_dmabuf_v1_requests, 2, zwp_linux_dmabuf_v1_events, -+}; -+ -+static const struct wl_message zwp_linux_buffer_params_v1_requests[] = { -+ {"destroy", "", types + 0}, -+ {"add", "huuuuu", types + 0}, -+ {"create", "iiuu", types + 0}, -+ {"create_immed", "2niiuu", types + 7}, -+}; -+ -+static const struct wl_message zwp_linux_buffer_params_v1_events[] = { -+ {"created", "n", types + 12}, -+ {"failed", "", types + 0}, -+}; -+ -+const struct wl_interface zwp_linux_buffer_params_v1_interface = { -+ "zwp_linux_buffer_params_v1", 3, 4, -+ zwp_linux_buffer_params_v1_requests, 2, zwp_linux_buffer_params_v1_events, -+}; -diff --git a/widget/gtk/wayland/moz.build b/widget/gtk/wayland/moz.build ---- a/widget/gtk/wayland/moz.build -+++ b/widget/gtk/wayland/moz.build -@@ -4,16 +4,22 @@ - # 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/. - - with Files("**"): - BUG_COMPONENT = ("Core", "Widget: Gtk") - - SOURCES += [ - 'gtk-primary-selection-protocol.c', -+ 'linux-dmabuf-unstable-v1-protocol.c' -+] -+ -+EXPORTS.mozilla.widget += [ -+ 'gtk-primary-selection-client-protocol.h', -+ 'linux-dmabuf-unstable-v1-client-protocol.h', - ] - - include('/ipc/chromium/chromium-config.mozbuild') - - FINAL_LIBRARY = 'xul' - - CFLAGS += CONFIG['TK_CFLAGS'] - CXXFLAGS += CONFIG['TK_CFLAGS'] - @@ -1,3 +1,3 @@ SHA512 (cbindgen-vendor.tar.xz) = bdd1535c9923a082cdca263ff2c1765814b00b6a1c74be95bac4dbf7d0b7b29c1c27f0fed6feae99c88521c96e2865f0ea3cf784bd9a32a44cec6ee4df850662 -SHA512 (firefox-67.0.4.source.tar.xz) = 42abc837b5808a55e68273db6aa45fa73f8fe1df3c9072c94d8d049b6803ce8758745cc0a68af64c4ce9f86e5dd3b3619824ba67fabddce428204605894d9ee7 -SHA512 (firefox-langpacks-67.0.4-20190620.tar.xz) = 99a0528d7be28a26352dc43ef0090b38a83959af2b68d9b08015c83f523bbc9f364199a9016d13b5a039a2d8aaa164f8b4b0a210d0c62d209d5261dbfa9ada1f +SHA512 (firefox-68.0.source.tar.xz) = 3822d9e72edffd278b4a8e86998252e7e7134a1751d64c9913e5492971f41606187b67b3639dcfca6c97ae958547d6bc0426a5cb2c321e32fb96f33ed8760feb +SHA512 (firefox-langpacks-68.0-20190702.tar.xz) = 6b146f7ef5fd57c38d3074b5f7ee19ac90d11d3e742bedb843f47ed528c27df8aa3f38698e31dd0357cdfa13e37a08845c29e5b5ac0efe8c8291b2272acae1d7 |