Updated to 70.0 Build 2
This commit is contained in:
parent
be00a1517c
commit
302967b0a8
2
.gitignore
vendored
2
.gitignore
vendored
@ -366,3 +366,5 @@ firefox-3.6.4.source.tar.bz2
|
||||
/firefox-69.0.2.source.tar.xz
|
||||
/firefox-69.0.3.source.tar.xz
|
||||
/firefox-langpacks-69.0.3-20191010.tar.xz
|
||||
/firefox-70.0.source.tar.xz
|
||||
/firefox-langpacks-70.0-20191018.tar.xz
|
||||
|
44
firefox.spec
44
firefox.spec
@ -93,13 +93,13 @@ ExcludeArch: ppc64le
|
||||
|
||||
Summary: Mozilla Firefox Web browser
|
||||
Name: firefox
|
||||
Version: 69.0.3
|
||||
Release: 2%{?pre_tag}%{?dist}
|
||||
Version: 70.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}-20191010.tar.xz
|
||||
Source1: firefox-langpacks-%{version}%{?pre_version}-20191018.tar.xz
|
||||
%endif
|
||||
Source2: cbindgen-vendor.tar.xz
|
||||
Source10: firefox-mozconfig
|
||||
@ -146,31 +146,15 @@ Patch228: mozilla-1583466.patch
|
||||
# Upstream patches
|
||||
Patch402: mozilla-1196777.patch
|
||||
Patch412: mozilla-1337988.patch
|
||||
#Patch413: mozilla-1353817.patch
|
||||
Patch415: Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch
|
||||
Patch417: bug1375074-save-restore-x28.patch
|
||||
Patch418: mozilla-1512162.patch
|
||||
Patch419: mozilla-1568569.patch
|
||||
Patch420: mozilla-1566876-webrtc-ind.patch
|
||||
Patch421: mozilla-1579023.patch
|
||||
Patch422: mozilla-1580174-webrtc-popup.patch
|
||||
|
||||
# Wayland specific upstream patches
|
||||
Patch574: firefox-pipewire.patch
|
||||
Patch575: mozilla-1548475.patch
|
||||
Patch576: mozilla-1562827.patch
|
||||
Patch578: mozilla-1567434-1.patch
|
||||
Patch579: mozilla-1567434-2.patch
|
||||
Patch580: mozilla-1573813.patch
|
||||
Patch581: mozilla-1574036.patch
|
||||
Patch582: mozilla-1576268.patch
|
||||
Patch583: mozilla-1579794-1.patch
|
||||
Patch584: mozilla-1579794-2.patch
|
||||
Patch585: mozilla-1579849.patch
|
||||
Patch586: mozilla-1579823.patch
|
||||
Patch587: mozilla-1580152.patch
|
||||
Patch588: mozilla-1581748.patch
|
||||
Patch589: mozilla-1577024.patch
|
||||
Patch590: firefox-wayland-cache-missing.patch
|
||||
Patch591: mozilla-1587008.patch
|
||||
|
||||
@ -370,34 +354,15 @@ This package contains results of tests executed during build.
|
||||
%patch228 -p1 -b .mozilla-1583466
|
||||
|
||||
%patch402 -p1 -b .1196777
|
||||
#%patch413 -p1 -b .1353817
|
||||
%ifarch %{arm}
|
||||
%patch415 -p1 -b .1238661
|
||||
%endif
|
||||
%ifarch ppc64 ppc64le
|
||||
#%patch418 -p1 -b .1512162 FIXME no longer needed?
|
||||
%endif
|
||||
%patch419 -p1 -b .1568569
|
||||
%patch420 -p1 -b .1566876-webrtc-ind
|
||||
%patch421 -p1 -b .1579023
|
||||
|
||||
# Wayland specific upstream patches
|
||||
%patch574 -p1 -b .firefox-pipewire
|
||||
%patch575 -p1 -b .mozilla-1548475
|
||||
%patch576 -p1 -b .mozilla-1562827
|
||||
%patch578 -p1 -b .mozilla-1567434-1
|
||||
%patch579 -p1 -b .mozilla-1567434-2
|
||||
%patch580 -p1 -b .mozilla-1573813
|
||||
%patch581 -p1 -b .mozilla-1574036
|
||||
%patch582 -p1 -b .mozilla-1576268
|
||||
%patch583 -p1 -b .mozilla-1579794-1
|
||||
%patch584 -p1 -b .mozilla-1579794-2
|
||||
%patch585 -p1 -b .mozilla-1579849
|
||||
%patch422 -p1 -b .1580174-webrtc-popup
|
||||
%patch586 -p1 -b .mozilla-1579823
|
||||
%patch587 -p1 -b .mozilla-1580152
|
||||
%patch588 -p1 -b .mozilla-1581748
|
||||
%patch589 -p1 -b .mozilla-1577024
|
||||
%patch590 -p1 -b .cache-missing
|
||||
%patch591 -p1 -b .mozilla-1587008
|
||||
|
||||
@ -982,6 +947,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
%changelog
|
||||
* Tue Oct 15 2019 Martin Stransky <stransky@redhat.com> - 70.0-1
|
||||
- Updated to 70.0
|
||||
|
||||
* Mon Oct 14 2019 Martin Stransky <stransky@redhat.com> - 69.0.3-2
|
||||
- Build firefox-wayland again (rhbz#1761578).
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 1cc652f5525f458b0b4ceb12af24bf5a4367db32 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
|
||||
Date: Tue, 23 May 2017 13:09:48 -0400
|
||||
Subject: [PATCH] Bug 1353817: Include SkNx_neon.h for ARM64 too
|
||||
|
||||
This fixes build errors as arm_neon.h was missing along with some
|
||||
missing converters.
|
||||
---
|
||||
gfx/skia/skia/src/core/SkNx.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gfx/skia/skia/src/core/SkNx.h b/gfx/skia/skia/src/core/SkNx.h
|
||||
index 6bca856..b0427aa 100644
|
||||
--- a/gfx/skia/skia/src/core/SkNx.h
|
||||
+++ b/gfx/skia/skia/src/core/SkNx.h
|
||||
@@ -299,7 +299,7 @@ typedef SkNx<4, uint32_t> Sk4u;
|
||||
// Include platform specific specializations if available.
|
||||
#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||
#include "../opts/SkNx_sse.h"
|
||||
-#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON)
|
||||
+#elif !defined(SKNX_NO_SIMD) && (defined(SK_ARM_HAS_NEON) || defined(SK_CPU_ARM64))
|
||||
#include "../opts/SkNx_neon.h"
|
||||
#else
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
@ -1,43 +0,0 @@
|
||||
diff -up firefox-68.0.1/js/xpconnect/src/XPCWrappedNative.cpp.1512162 firefox-68.0.1/js/xpconnect/src/XPCWrappedNative.cpp
|
||||
--- firefox-68.0.1/js/xpconnect/src/XPCWrappedNative.cpp.1512162 2019-07-17 22:51:30.000000000 +0200
|
||||
+++ firefox-68.0.1/js/xpconnect/src/XPCWrappedNative.cpp 2019-07-25 08:08:18.512528313 +0200
|
||||
@@ -1092,7 +1092,7 @@ class MOZ_STACK_CLASS CallMethodHelper f
|
||||
MOZ_ALWAYS_INLINE bool GetOutParamSource(uint8_t paramIndex,
|
||||
MutableHandleValue srcp) const;
|
||||
|
||||
- MOZ_ALWAYS_INLINE bool GatherAndConvertResults();
|
||||
+ bool GatherAndConvertResults();
|
||||
|
||||
MOZ_ALWAYS_INLINE bool QueryInterfaceFastPath();
|
||||
|
||||
@@ -1139,7 +1139,7 @@ class MOZ_STACK_CLASS CallMethodHelper f
|
||||
|
||||
~CallMethodHelper();
|
||||
|
||||
- MOZ_ALWAYS_INLINE bool Call();
|
||||
+ bool Call();
|
||||
|
||||
// Trace implementation so we can put our CallMethodHelper in a Rooted<T>.
|
||||
void trace(JSTracer* aTrc);
|
||||
@@ -1157,6 +1157,10 @@ bool XPCWrappedNative::CallMethod(XPCCal
|
||||
return helper.get().Call();
|
||||
}
|
||||
|
||||
+#if (__GNUC__ && __linux__ && __PPC64__ && _LITTLE_ENDIAN)
|
||||
+// Work around a compiler bug on ppc64le (bug 1512162).
|
||||
+__attribute__ ((noinline,noclone))
|
||||
+#endif
|
||||
bool CallMethodHelper::Call() {
|
||||
mCallContext.SetRetVal(JS::UndefinedValue());
|
||||
|
||||
@@ -1315,6 +1319,10 @@ bool CallMethodHelper::GetOutParamSource
|
||||
return true;
|
||||
}
|
||||
|
||||
+#if (__GNUC__ && __linux__ && __PPC64__ && _LITTLE_ENDIAN)
|
||||
+// Work around a compiler bug on ppc64le (bug 1512162).
|
||||
+__attribute__ ((noinline,noclone))
|
||||
+#endif
|
||||
bool CallMethodHelper::GatherAndConvertResults() {
|
||||
// now we iterate through the native params to gather and convert results
|
||||
uint8_t paramCount = mMethodInfo->GetParamCount();
|
@ -1,7 +1,7 @@
|
||||
diff -up firefox-69.0/build/moz.configure/toolchain.configure.1516081 firefox-69.0/build/moz.configure/toolchain.configure
|
||||
--- firefox-69.0/build/moz.configure/toolchain.configure.1516081 2019-08-27 03:31:51.000000000 +0200
|
||||
+++ firefox-69.0/build/moz.configure/toolchain.configure 2019-08-29 10:42:45.872919255 +0200
|
||||
@@ -1411,7 +1411,7 @@ def pgo_flags(compiler, build_env, targe
|
||||
diff -up firefox-70.0/build/moz.configure/lto-pgo.configure.old firefox-70.0/build/moz.configure/lto-pgo.configure
|
||||
--- firefox-70.0/build/moz.configure/lto-pgo.configure.old 2019-10-18 20:33:54.240107068 +0200
|
||||
+++ firefox-70.0/build/moz.configure/lto-pgo.configure 2019-10-18 20:34:44.202009678 +0200
|
||||
@@ -16,7 +16,7 @@ def pgo_flags(compiler, build_env, targe
|
||||
|
||||
if compiler.type == 'gcc':
|
||||
return namespace(
|
||||
@ -10,29 +10,12 @@ diff -up firefox-69.0/build/moz.configure/toolchain.configure.1516081 firefox-69
|
||||
gen_ldflags=['-fprofile-generate'],
|
||||
use_cflags=['-fprofile-use', '-fprofile-correction',
|
||||
'-Wcoverage-mismatch'],
|
||||
@@ -1434,7 +1434,8 @@ def pgo_flags(compiler, build_env, targe
|
||||
@@ -38,7 +38,7 @@ def pgo_flags(compiler, build_env, targe
|
||||
gen_ldflags = ['-fprofile-generate']
|
||||
|
||||
if gen_ldflags:
|
||||
return namespace(
|
||||
- gen_cflags=[prefix + '-fprofile-generate'],
|
||||
+ gen_cflags=[prefix + '-fprofile-generate',
|
||||
+ '-DMOZ_PROFILE_INSTRUMENTATION'],
|
||||
+ gen_cflags=[prefix + '-fprofile-generate', '-DMOZ_PROFILE_INSTRUMENTATION'],
|
||||
gen_ldflags=gen_ldflags,
|
||||
use_cflags=[prefix + '-fprofile-use=%s' % profdata,
|
||||
# Some error messages about mismatched profile data
|
||||
diff -up firefox-69.0/toolkit/components/terminator/nsTerminator.cpp.1516081 firefox-69.0/toolkit/components/terminator/nsTerminator.cpp
|
||||
--- firefox-69.0/toolkit/components/terminator/nsTerminator.cpp.1516081 2019-08-27 03:32:05.000000000 +0200
|
||||
+++ firefox-69.0/toolkit/components/terminator/nsTerminator.cpp 2019-08-29 09:51:08.513440687 +0200
|
||||
@@ -419,6 +419,12 @@ void nsTerminator::StartWatchdog() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+ // Disable watchdog for PGO train builds - writting profile information at
|
||||
+ // exit may take time and it is better to make build hang rather than
|
||||
+ // silently produce poorly performing binary.
|
||||
+#ifdef MOZ_PROFILE_INSTRUMENTATION
|
||||
+ crashAfterMS = INT32_MAX;
|
||||
+#endif
|
||||
|
||||
UniquePtr<Options> options(new Options());
|
||||
const PRIntervalTime ticksDuration = PR_MillisecondsToInterval(1000);
|
||||
|
@ -1,141 +0,0 @@
|
||||
diff -up firefox-69.0/widget/gtk/nsWindow.cpp.mozilla-1562827 firefox-69.0/widget/gtk/nsWindow.cpp
|
||||
--- firefox-69.0/widget/gtk/nsWindow.cpp.mozilla-1562827 2019-09-02 15:16:15.031528276 +0200
|
||||
+++ firefox-69.0/widget/gtk/nsWindow.cpp 2019-09-02 15:16:15.037528254 +0200
|
||||
@@ -818,7 +818,6 @@ void nsWindow::SetParent(nsIWidget* aNew
|
||||
if (mParent) {
|
||||
mParent->RemoveChild(this);
|
||||
}
|
||||
-
|
||||
mParent = aNewParent;
|
||||
|
||||
GtkWidget* oldContainer = GetMozContainerWidget();
|
||||
@@ -830,88 +829,73 @@ void nsWindow::SetParent(nsIWidget* aNew
|
||||
return;
|
||||
}
|
||||
|
||||
+ nsWindow* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
+ GdkWindow* newParentWindow = nullptr;
|
||||
+ GtkWidget* newContainer = nullptr;
|
||||
if (aNewParent) {
|
||||
aNewParent->AddChild(this);
|
||||
- ReparentNativeWidget(aNewParent);
|
||||
+ newParentWindow = newParent->mGdkWindow;
|
||||
+ newContainer = newParent->GetMozContainerWidget();
|
||||
} else {
|
||||
// aNewParent is nullptr, but reparent to a hidden window to avoid
|
||||
// destroying the GdkWindow and its descendants.
|
||||
// An invisible container widget is needed to hold descendant
|
||||
// GtkWidgets.
|
||||
- GtkWidget* newContainer = EnsureInvisibleContainer();
|
||||
- GdkWindow* newParentWindow = gtk_widget_get_window(newContainer);
|
||||
- ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
|
||||
- oldContainer);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-bool nsWindow::WidgetTypeSupportsAcceleration() { return !IsSmallPopup(); }
|
||||
-
|
||||
-void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) {
|
||||
- MOZ_ASSERT(aNewParent, "null widget");
|
||||
- NS_ASSERTION(!mIsDestroyed, "");
|
||||
- NS_ASSERTION(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
|
||||
-
|
||||
- GtkWidget* oldContainer = GetMozContainerWidget();
|
||||
- if (!oldContainer) {
|
||||
- // The GdkWindows have been destroyed so there is nothing else to
|
||||
- // reparent.
|
||||
- MOZ_ASSERT(gdk_window_is_destroyed(mGdkWindow),
|
||||
- "live GdkWindow with no widget");
|
||||
- return;
|
||||
+ newContainer = EnsureInvisibleContainer();
|
||||
+ newParentWindow = gtk_widget_get_window(newContainer);
|
||||
}
|
||||
- MOZ_ASSERT(!gdk_window_is_destroyed(mGdkWindow),
|
||||
- "destroyed GdkWindow with widget");
|
||||
|
||||
- auto* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
- GdkWindow* newParentWindow = newParent->mGdkWindow;
|
||||
- GtkWidget* newContainer = newParent->GetMozContainerWidget();
|
||||
- GtkWindow* shell = GTK_WINDOW(mShell);
|
||||
-
|
||||
- if (shell && gtk_window_get_transient_for(shell)) {
|
||||
- GtkWindow* topLevelParent =
|
||||
- GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
|
||||
- gtk_window_set_transient_for(shell, topLevelParent);
|
||||
- }
|
||||
-
|
||||
- ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
|
||||
- oldContainer);
|
||||
-}
|
||||
-
|
||||
-void nsWindow::ReparentNativeWidgetInternal(nsIWidget* aNewParent,
|
||||
- GtkWidget* aNewContainer,
|
||||
- GdkWindow* aNewParentWindow,
|
||||
- GtkWidget* aOldContainer) {
|
||||
- if (!aNewContainer) {
|
||||
+ if (!newContainer) {
|
||||
// The new parent GdkWindow has been destroyed.
|
||||
- MOZ_ASSERT(!aNewParentWindow || gdk_window_is_destroyed(aNewParentWindow),
|
||||
+ MOZ_ASSERT(!newParentWindow || gdk_window_is_destroyed(newParentWindow),
|
||||
"live GdkWindow with no widget");
|
||||
Destroy();
|
||||
} else {
|
||||
- if (aNewContainer != aOldContainer) {
|
||||
- MOZ_ASSERT(!gdk_window_is_destroyed(aNewParentWindow),
|
||||
+ if (newContainer != oldContainer) {
|
||||
+ MOZ_ASSERT(!gdk_window_is_destroyed(newParentWindow),
|
||||
"destroyed GdkWindow with widget");
|
||||
- SetWidgetForHierarchy(mGdkWindow, aOldContainer, aNewContainer);
|
||||
+ SetWidgetForHierarchy(mGdkWindow, oldContainer, newContainer);
|
||||
|
||||
- if (aOldContainer == gInvisibleContainer) {
|
||||
+ if (oldContainer == gInvisibleContainer) {
|
||||
CheckDestroyInvisibleContainer();
|
||||
}
|
||||
}
|
||||
|
||||
- if (!mIsTopLevel) {
|
||||
- gdk_window_reparent(mGdkWindow, aNewParentWindow,
|
||||
- DevicePixelsToGdkCoordRoundDown(mBounds.x),
|
||||
- DevicePixelsToGdkCoordRoundDown(mBounds.y));
|
||||
- }
|
||||
+ gdk_window_reparent(mGdkWindow, newParentWindow,
|
||||
+ DevicePixelsToGdkCoordRoundDown(mBounds.x),
|
||||
+ DevicePixelsToGdkCoordRoundDown(mBounds.y));
|
||||
+ mToplevelParentWindow = GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
|
||||
}
|
||||
|
||||
- auto* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
bool parentHasMappedToplevel = newParent && newParent->mHasMappedToplevel;
|
||||
if (mHasMappedToplevel != parentHasMappedToplevel) {
|
||||
SetHasMappedToplevel(parentHasMappedToplevel);
|
||||
}
|
||||
}
|
||||
|
||||
+bool nsWindow::WidgetTypeSupportsAcceleration() { return !IsSmallPopup(); }
|
||||
+
|
||||
+void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) {
|
||||
+ MOZ_ASSERT(aNewParent, "null widget");
|
||||
+ MOZ_ASSERT(!mIsDestroyed, "");
|
||||
+ MOZ_ASSERT(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
|
||||
+ MOZ_ASSERT(!gdk_window_is_destroyed(mGdkWindow),
|
||||
+ "destroyed GdkWindow with widget");
|
||||
+
|
||||
+ MOZ_ASSERT(
|
||||
+ !mParent,
|
||||
+ "nsWindow::ReparentNativeWidget() works on toplevel windows only.");
|
||||
+
|
||||
+ auto* newParent = static_cast<nsWindow*>(aNewParent);
|
||||
+ GtkWindow* newParentWidget = GTK_WINDOW(newParent->GetGtkWidget());
|
||||
+ GtkWindow* shell = GTK_WINDOW(mShell);
|
||||
+
|
||||
+ if (shell && gtk_window_get_transient_for(shell)) {
|
||||
+ gtk_window_set_transient_for(shell, newParentWidget);
|
||||
+ mToplevelParentWindow = newParentWidget;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void nsWindow::SetModal(bool aModal) {
|
||||
LOG(("nsWindow::SetModal [%p] %d\n", (void*)this, aModal));
|
||||
if (mIsDestroyed) return;
|
||||
diff -up firefox-69.0/widget/gtk/nsWindow.h.mozilla-1562827 firefox-69.0/widget/gtk/nsWindow.h
|
@ -1,36 +0,0 @@
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -3504,12 +3504,6 @@
|
||||
mBounds = aRect;
|
||||
ConstrainSize(&mBounds.width, &mBounds.height);
|
||||
|
||||
- // eWindowType_child is not supported on Wayland. Just switch to toplevel
|
||||
- // as a workaround.
|
||||
- if (!mIsX11Display && mWindowType == eWindowType_child) {
|
||||
- mWindowType = eWindowType_toplevel;
|
||||
- }
|
||||
-
|
||||
// figure out our parent window
|
||||
GtkWidget* parentMozContainer = nullptr;
|
||||
GtkContainer* parentGtkContainer = nullptr;
|
||||
@@ -3543,6 +3537,18 @@
|
||||
topLevelParent = GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
|
||||
}
|
||||
|
||||
+ if (!mIsX11Display) {
|
||||
+ if (mWindowType == eWindowType_child) {
|
||||
+ // eWindowType_child is not supported on Wayland. Just switch to toplevel
|
||||
+ // as a workaround.
|
||||
+ mWindowType = eWindowType_toplevel;
|
||||
+ } else if (mWindowType == eWindowType_popup && !topLevelParent) {
|
||||
+ // Workaround for Wayland where the popup windows always need to have
|
||||
+ // parent window. For example webrtc ui is a popup window without parent.
|
||||
+ mWindowType = eWindowType_toplevel;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// ok, create our windows
|
||||
switch (mWindowType) {
|
||||
case eWindowType_dialog:
|
||||
|
@ -1,226 +0,0 @@
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- a/widget/gtk/WindowSurfaceWayland.cpp
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
@@ -616,8 +616,6 @@
|
||||
}
|
||||
|
||||
if (!aFullScreenUpdate) {
|
||||
- NS_WARNING(
|
||||
- "We can't create a new Wayland buffer for non-fullscreen updates!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -674,8 +672,6 @@
|
||||
(void*)buffer));
|
||||
|
||||
if (!buffer) {
|
||||
- NS_WARNING(
|
||||
- "WindowSurfaceWayland::LockWaylandBuffer(): No buffer available");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
|
||||
--- a/widget/gtk/nsWindow.h
|
||||
+++ b/widget/gtk/nsWindow.h
|
||||
@@ -487,6 +487,7 @@
|
||||
GtkWidget* mShell;
|
||||
MozContainer* mContainer;
|
||||
GdkWindow* mGdkWindow;
|
||||
+ GtkWindow* mToplevelParentWindow;
|
||||
bool mWindowShouldStartDragging = false;
|
||||
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
|
||||
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -401,6 +401,7 @@
|
||||
mContainer = nullptr;
|
||||
mGdkWindow = nullptr;
|
||||
mShell = nullptr;
|
||||
+ mToplevelParentWindow = nullptr;
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
mHasMappedToplevel = false;
|
||||
mIsFullyObscured = false;
|
||||
@@ -1144,6 +1145,8 @@
|
||||
nsWindow* window =
|
||||
static_cast<nsWindow*>(gVisibleWaylandPopupWindows->data);
|
||||
if (window->mPopupType != ePopupTypeTooltip) break;
|
||||
+ LOG(("nsWindow::HideWaylandTooltips [%p] hidding tooltip [%p].\n",
|
||||
+ (void*)this, window));
|
||||
window->HideWaylandWindow();
|
||||
gVisibleWaylandPopupWindows = g_list_delete_link(
|
||||
gVisibleWaylandPopupWindows, gVisibleWaylandPopupWindows);
|
||||
@@ -1172,9 +1175,12 @@
|
||||
// before we open another one on that level. It means that every open
|
||||
// popup needs to have an unique parent.
|
||||
GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
||||
+ LOG(("nsWindow::ConfigureWaylandPopupWindows [%p]\n", (void*)this));
|
||||
+
|
||||
// Check if we're already configured.
|
||||
if (gVisibleWaylandPopupWindows &&
|
||||
g_list_find(gVisibleWaylandPopupWindows, this)) {
|
||||
+ LOG(("...[%p] is already configured.\n", (void*)this));
|
||||
return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell)));
|
||||
}
|
||||
|
||||
@@ -1182,9 +1188,15 @@
|
||||
// as it's short lived temporary window.
|
||||
HideWaylandTooltips();
|
||||
|
||||
- GtkWindow* parentWidget = nullptr;
|
||||
+ GtkWindow* parentWidget = mToplevelParentWindow;
|
||||
if (gVisibleWaylandPopupWindows) {
|
||||
+ LOG(("... there's visible active popup [%p]\n",
|
||||
+ gVisibleWaylandPopupWindows->data));
|
||||
+
|
||||
if (mPopupType == ePopupTypeTooltip) {
|
||||
+ LOG(("...[%p] is tooltip, parent [%p]\n", (void*)this,
|
||||
+ gVisibleWaylandPopupWindows->data));
|
||||
+
|
||||
// Attach tooltip window to the latest popup window
|
||||
// to have both visible.
|
||||
nsWindow* window =
|
||||
@@ -1200,12 +1212,19 @@
|
||||
// nsWindow::Create()) or we're toplevel popup without parent.
|
||||
// In both cases just use parent which was passed to nsWindow::Create().
|
||||
if (!menuPopupFrame) {
|
||||
- return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell)));
|
||||
+ LOG(("...[%p] menuPopupFrame = null, using given parent widget [%p]\n",
|
||||
+ (void*)this, parentWidget));
|
||||
+ return GTK_WIDGET(parentWidget);
|
||||
}
|
||||
|
||||
nsWindow* parentWindow =
|
||||
static_cast<nsWindow*>(menuPopupFrame->GetParentMenuWidget());
|
||||
+ LOG(("...[%p] GetParentMenuWidget() = %p\n", (void*)this, parentWindow));
|
||||
+
|
||||
if (!parentWindow) {
|
||||
+ LOG(("...[%p] using active/visible popups as a parent [%p]\n",
|
||||
+ (void*)this, gVisibleWaylandPopupWindows->data));
|
||||
+
|
||||
// We're toplevel popup menu attached to another menu. Just use our
|
||||
// latest popup as a parent.
|
||||
parentWindow =
|
||||
@@ -1234,10 +1253,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ MOZ_ASSERT(parentWidget, "Missing parent widget for wayland popup!");
|
||||
if (parentWidget) {
|
||||
+ LOG(("...[%p] set parent widget [%p]\n", (void*)this, parentWidget));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(mShell), parentWidget);
|
||||
- } else {
|
||||
- parentWidget = gtk_window_get_transient_for(GTK_WINDOW(mShell));
|
||||
}
|
||||
gVisibleWaylandPopupWindows =
|
||||
g_list_prepend(gVisibleWaylandPopupWindows, this);
|
||||
@@ -1248,9 +1267,11 @@
|
||||
static void NativeMoveResizeWaylandPopupCallback(
|
||||
GdkWindow* window, const GdkRectangle* flipped_rect,
|
||||
const GdkRectangle* final_rect, gboolean flipped_x, gboolean flipped_y,
|
||||
- void* unused) {
|
||||
- LOG(("%s flipped %d %d\n", __FUNCTION__, flipped_rect->x, flipped_rect->y));
|
||||
- LOG(("%s final %d %d\n", __FUNCTION__, final_rect->x, final_rect->y));
|
||||
+ void* aWindow) {
|
||||
+ LOG(("%s [%p] flipped %d %d\n", __FUNCTION__, aWindow, flipped_rect->x,
|
||||
+ flipped_rect->y));
|
||||
+ LOG(("%s [%p] final %d %d\n", __FUNCTION__, aWindow, final_rect->x,
|
||||
+ final_rect->y));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1264,6 +1285,8 @@
|
||||
// Compositor may be confused by windows with width/height = 0
|
||||
// and positioning such windows leads to Bug 1555866.
|
||||
if (!AreBoundsSane()) {
|
||||
+ LOG(("nsWindow::NativeMoveResizeWaylandPopup [%p] Bounds are not sane\n",
|
||||
+ (void*)this));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1277,6 +1300,8 @@
|
||||
// - gdk_window_move_to_rect() is not available
|
||||
// - the widget doesn't have a valid GdkWindow
|
||||
if (!sGdkWindowMoveToRect || !gdkWindow) {
|
||||
+ LOG(("nsWindow::NativeMoveResizeWaylandPopup [%p] use gtk_window_move()\n",
|
||||
+ (void*)this));
|
||||
gtk_window_move(GTK_WINDOW(mShell), aPosition->x, aPosition->y);
|
||||
return;
|
||||
}
|
||||
@@ -1302,8 +1327,12 @@
|
||||
}
|
||||
LOG((" request result %d %d\n", rect.x, rect.y));
|
||||
#ifdef DEBUG
|
||||
- g_signal_connect(gdkWindow, "moved-to-rect",
|
||||
- G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this);
|
||||
+ if (!g_signal_handler_find(
|
||||
+ gdkWindow, G_SIGNAL_MATCH_FUNC, 0, 0, nullptr,
|
||||
+ FuncToGpointer(NativeMoveResizeWaylandPopupCallback), this)) {
|
||||
+ g_signal_connect(gdkWindow, "moved-to-rect",
|
||||
+ G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this);
|
||||
+ }
|
||||
#endif
|
||||
|
||||
GdkGravity rectAnchor = GDK_GRAVITY_NORTH_WEST;
|
||||
@@ -3508,7 +3537,6 @@
|
||||
GtkWidget* parentMozContainer = nullptr;
|
||||
GtkContainer* parentGtkContainer = nullptr;
|
||||
GdkWindow* parentGdkWindow = nullptr;
|
||||
- GtkWindow* topLevelParent = nullptr;
|
||||
nsWindow* parentnsWindow = nullptr;
|
||||
GtkWidget* eventWidget = nullptr;
|
||||
bool drawToContainer = false;
|
||||
@@ -3534,7 +3562,8 @@
|
||||
|
||||
// get the toplevel window just in case someone needs to use it
|
||||
// for setting transients or whatever.
|
||||
- topLevelParent = GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
|
||||
+ mToplevelParentWindow =
|
||||
+ GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
|
||||
}
|
||||
|
||||
if (!mIsX11Display) {
|
||||
@@ -3542,7 +3571,7 @@
|
||||
// eWindowType_child is not supported on Wayland. Just switch to toplevel
|
||||
// as a workaround.
|
||||
mWindowType = eWindowType_toplevel;
|
||||
- } else if (mWindowType == eWindowType_popup && !topLevelParent) {
|
||||
+ } else if (mWindowType == eWindowType_popup && !mToplevelParentWindow) {
|
||||
// Workaround for Wayland where the popup windows always need to have
|
||||
// parent window. For example webrtc ui is a popup window without parent.
|
||||
mWindowType = eWindowType_toplevel;
|
||||
@@ -3677,7 +3706,7 @@
|
||||
gdk_get_program_class());
|
||||
gtk_window_set_type_hint(GTK_WINDOW(mShell),
|
||||
GDK_WINDOW_TYPE_HINT_DIALOG);
|
||||
- gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
|
||||
+ gtk_window_set_transient_for(GTK_WINDOW(mShell), mToplevelParentWindow);
|
||||
} else if (mWindowType == eWindowType_popup) {
|
||||
gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup",
|
||||
gdk_get_program_class());
|
||||
@@ -3730,10 +3759,11 @@
|
||||
}
|
||||
gtk_window_set_type_hint(GTK_WINDOW(mShell), gtkTypeHint);
|
||||
|
||||
- if (topLevelParent) {
|
||||
+ if (mToplevelParentWindow) {
|
||||
LOG(("nsWindow::Create [%p] Set popup parent %p\n", (void*)this,
|
||||
- topLevelParent));
|
||||
- gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
|
||||
+ mToplevelParentWindow));
|
||||
+ gtk_window_set_transient_for(GTK_WINDOW(mShell),
|
||||
+ mToplevelParentWindow);
|
||||
}
|
||||
|
||||
// We need realized mShell at NativeMove().
|
||||
@@ -4011,7 +4041,8 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
- LOG(("nsWindow [%p]\n", (void*)this));
|
||||
+ LOG(("nsWindow [%p] %s\n", (void*)this,
|
||||
+ mWindowType == eWindowType_toplevel ? "Toplevel" : "Popup"));
|
||||
if (mShell) {
|
||||
LOG(("\tmShell %p mContainer %p mGdkWindow %p 0x%lx\n", mShell, mContainer,
|
||||
mGdkWindow, mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0));
|
||||
|
@ -1,35 +0,0 @@
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -1208,6 +1208,7 @@
|
||||
if (frame) {
|
||||
menuPopupFrame = do_QueryFrame(frame);
|
||||
}
|
||||
+
|
||||
// The popup is not fully created yet (we're called from
|
||||
// nsWindow::Create()) or we're toplevel popup without parent.
|
||||
// In both cases just use parent which was passed to nsWindow::Create().
|
||||
@@ -1217,10 +1218,22 @@
|
||||
return GTK_WIDGET(parentWidget);
|
||||
}
|
||||
|
||||
+ LOG(("...[%p] is %s\n", (void*)this,
|
||||
+ menuPopupFrame->IsContextMenu() ? "context menu" : "popup"));
|
||||
+
|
||||
nsWindow* parentWindow =
|
||||
static_cast<nsWindow*>(menuPopupFrame->GetParentMenuWidget());
|
||||
LOG(("...[%p] GetParentMenuWidget() = %p\n", (void*)this, parentWindow));
|
||||
|
||||
+ // If the popup is a regular menu but GetParentMenuWidget() returns
|
||||
+ // nullptr which means it's connected non-menu parent
|
||||
+ // (bookmark toolbar for instance).
|
||||
+ // In this case use a parent given at nsWindow::Create().
|
||||
+ if (!parentWindow && !menuPopupFrame->IsContextMenu()) {
|
||||
+ parentWindow =
|
||||
+ get_window_for_gtk_widget(GTK_WIDGET(mToplevelParentWindow));
|
||||
+ }
|
||||
+
|
||||
if (!parentWindow) {
|
||||
LOG(("...[%p] using active/visible popups as a parent [%p]\n",
|
||||
(void*)this, gVisibleWaylandPopupWindows->data));
|
||||
|
@ -1,29 +0,0 @@
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -6577,11 +6577,22 @@
|
||||
}
|
||||
|
||||
gint nsWindow::GdkScaleFactor() {
|
||||
+ // For popup windows with parent window we need to get scale factor of the
|
||||
+ // parent window. Otherwise the scale factor of the popup is not updated
|
||||
+ // during it's hidden.
|
||||
+ GdkWindow* scaledGdkWindow = mGdkWindow;
|
||||
+ if (mToplevelParentWindow) {
|
||||
+ scaledGdkWindow = gtk_widget_get_window(GTK_WIDGET(mToplevelParentWindow));
|
||||
+ // Fallback for windows which parent has been unrealized.
|
||||
+ if (!scaledGdkWindow) {
|
||||
+ scaledGdkWindow = mGdkWindow;
|
||||
+ }
|
||||
+ }
|
||||
// Available as of GTK 3.10+
|
||||
static auto sGdkWindowGetScaleFactorPtr =
|
||||
(gint(*)(GdkWindow*))dlsym(RTLD_DEFAULT, "gdk_window_get_scale_factor");
|
||||
- if (sGdkWindowGetScaleFactorPtr && mGdkWindow)
|
||||
- return (*sGdkWindowGetScaleFactorPtr)(mGdkWindow);
|
||||
+ if (sGdkWindowGetScaleFactorPtr && scaledGdkWindow)
|
||||
+ return (*sGdkWindowGetScaleFactorPtr)(scaledGdkWindow);
|
||||
return ScreenHelperGTK::GetGTKMonitorScaleFactor();
|
||||
}
|
||||
|
||||
|
@ -1,425 +0,0 @@
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h
|
||||
--- a/widget/gtk/WindowSurfaceWayland.h
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.h
|
||||
@@ -177,12 +177,9 @@
|
||||
|
||||
private:
|
||||
WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight);
|
||||
- WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight,
|
||||
- bool aFullScreenUpdate);
|
||||
+ WindowBackBuffer* GetWaylandBufferToDraw(bool aCanSwitchBuffer);
|
||||
|
||||
- already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(int aWidth, int aHeight,
|
||||
- bool aClearBuffer,
|
||||
- bool aFullScreenUpdate);
|
||||
+ already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(bool aCanSwitchBuffer);
|
||||
void UnlockWaylandBuffer();
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> LockImageSurface(
|
||||
@@ -198,7 +195,10 @@
|
||||
|
||||
// TODO: Do we need to hold a reference to nsWindow object?
|
||||
nsWindow* mWindow;
|
||||
- LayoutDeviceIntRect mLastScreenRect;
|
||||
+ // Buffer screen rects helps us understand if we operate on
|
||||
+ // the same window size as we're called on WindowSurfaceWayland::Lock().
|
||||
+ // mBufferScreenRect is window size when our wayland buffer was allocated.
|
||||
+ LayoutDeviceIntRect mBufferScreenRect;
|
||||
nsWaylandDisplay* mWaylandDisplay;
|
||||
WindowBackBuffer* mWaylandBuffer;
|
||||
LayoutDeviceIntRegion mWaylandBufferDamage;
|
||||
@@ -211,7 +211,8 @@
|
||||
AutoTArray<WindowImageSurface, 30> mDelayedImageCommits;
|
||||
bool mDrawToWaylandBufferDirectly;
|
||||
bool mPendingCommit;
|
||||
- bool mWaylandBufferFullScreenDamage;
|
||||
+ bool mWholeWindowBufferDamage;
|
||||
+ bool mBufferNeedsClear;
|
||||
bool mIsMainThread;
|
||||
bool mNeedScaleFactorUpdate;
|
||||
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- a/widget/gtk/WindowSurfaceWayland.cpp
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
@@ -499,7 +499,8 @@
|
||||
mDelayedCommitHandle(nullptr),
|
||||
mDrawToWaylandBufferDirectly(true),
|
||||
mPendingCommit(false),
|
||||
- mWaylandBufferFullScreenDamage(false),
|
||||
+ mWholeWindowBufferDamage(false),
|
||||
+ mBufferNeedsClear(false),
|
||||
mIsMainThread(NS_IsMainThread()),
|
||||
mNeedScaleFactorUpdate(true) {
|
||||
for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
|
||||
@@ -565,18 +566,20 @@
|
||||
}
|
||||
|
||||
WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(
|
||||
- int aWidth, int aHeight, bool aFullScreenUpdate) {
|
||||
+ bool aCanSwitchBuffer) {
|
||||
LOGWAYLAND(("%s [%p] Requested buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, aWidth, aHeight));
|
||||
+ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
|
||||
// There's no buffer created yet, create a new one.
|
||||
if (!mWaylandBuffer) {
|
||||
- MOZ_ASSERT(aFullScreenUpdate, "Created new buffer for partial drawing!");
|
||||
+ MOZ_ASSERT(aCanSwitchBuffer && mWholeWindowBufferDamage,
|
||||
+ "Created new buffer for partial drawing!");
|
||||
LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, aWidth, aHeight));
|
||||
+ (void*)this, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
|
||||
- mWaylandBuffer = CreateWaylandBuffer(aWidth, aHeight);
|
||||
- mWaylandBufferFullScreenDamage = true;
|
||||
+ mWaylandBuffer =
|
||||
+ CreateWaylandBuffer(mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
mNeedScaleFactorUpdate = true;
|
||||
return mWaylandBuffer;
|
||||
}
|
||||
@@ -593,29 +596,31 @@
|
||||
LOGWAYLAND(
|
||||
("%s [%p] Use recent buffer.\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
|
||||
- if (mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) {
|
||||
+ if (mWaylandBuffer->IsMatchingSize(mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height)) {
|
||||
LOGWAYLAND(("%s [%p] Size is ok, use the buffer [%d x %d]\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight));
|
||||
+ __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
return mWaylandBuffer;
|
||||
}
|
||||
|
||||
- if (!aFullScreenUpdate) {
|
||||
+ if (!aCanSwitchBuffer) {
|
||||
NS_WARNING("We can't resize Wayland buffer for non-fullscreen updates!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOGWAYLAND(("%s [%p] Reuse buffer with resize [%d x %d]\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight));
|
||||
+ __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
|
||||
- mWaylandBuffer->Resize(aWidth, aHeight);
|
||||
+ mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
// There's a chance that scale factor has been changed
|
||||
// when buffer size changed
|
||||
- mWaylandBufferFullScreenDamage = true;
|
||||
mNeedScaleFactorUpdate = true;
|
||||
return mWaylandBuffer;
|
||||
}
|
||||
|
||||
- if (!aFullScreenUpdate) {
|
||||
+ if (!aCanSwitchBuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -625,8 +630,10 @@
|
||||
availableBuffer++) {
|
||||
if (!mBackupBuffer[availableBuffer]) {
|
||||
LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, aWidth, aHeight));
|
||||
- mBackupBuffer[availableBuffer] = CreateWaylandBuffer(aWidth, aHeight);
|
||||
+ (void*)this, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
+ mBackupBuffer[availableBuffer] = CreateWaylandBuffer(
|
||||
+ mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -650,23 +657,23 @@
|
||||
__PRETTY_FUNCTION__, (void*)this, (void*)lastWaylandBuffer,
|
||||
(void*)mWaylandBuffer));
|
||||
|
||||
- mWaylandBufferFullScreenDamage = true;
|
||||
mNeedScaleFactorUpdate = true;
|
||||
|
||||
- bool bufferNeedsResize = !mWaylandBuffer->IsMatchingSize(aWidth, aHeight);
|
||||
+ bool bufferNeedsResize = !mWaylandBuffer->IsMatchingSize(
|
||||
+ mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
if (bufferNeedsResize) {
|
||||
LOGWAYLAND(("%s [%p] Resize buffer to [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, aWidth, aHeight));
|
||||
- mWaylandBuffer->Resize(aWidth, aHeight);
|
||||
+ (void*)this, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
+ mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
}
|
||||
|
||||
return mWaylandBuffer;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer(
|
||||
- int aWidth, int aHeight, bool aClearBuffer, bool aFullScreenUpdate) {
|
||||
- WindowBackBuffer* buffer =
|
||||
- GetWaylandBufferToDraw(aWidth, aHeight, aFullScreenUpdate);
|
||||
+ bool aCanSwitchBuffer) {
|
||||
+ WindowBackBuffer* buffer = GetWaylandBufferToDraw(aCanSwitchBuffer);
|
||||
|
||||
LOGWAYLAND(("%s [%p] Got buffer %p\n", __PRETTY_FUNCTION__, (void*)this,
|
||||
(void*)buffer));
|
||||
@@ -675,8 +682,9 @@
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- if (aClearBuffer) {
|
||||
+ if (mBufferNeedsClear && mWholeWindowBufferDamage) {
|
||||
buffer->Clear();
|
||||
+ mBufferNeedsClear = false;
|
||||
}
|
||||
|
||||
return buffer->Lock();
|
||||
@@ -744,7 +752,7 @@
|
||||
const LayoutDeviceIntRegion& aRegion) {
|
||||
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
|
||||
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
|
||||
+ LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
|
||||
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
|
||||
|
||||
@@ -753,54 +761,77 @@
|
||||
mWindow->IsWaylandPopup() &&
|
||||
(eTransparencyTransparent == mWindow->GetTransparencyMode());
|
||||
|
||||
- mDrawToWaylandBufferDirectly =
|
||||
- isTransparentPopup ? IsPopupFullScreenUpdate(screenRect, aRegion)
|
||||
- : IsWindowFullScreenUpdate(screenRect, aRegion);
|
||||
+ // We have request to lock whole buffer/window.
|
||||
+ mWholeWindowBufferDamage =
|
||||
+ isTransparentPopup ? IsPopupFullScreenUpdate(lockedScreenRect, aRegion)
|
||||
+ : IsWindowFullScreenUpdate(lockedScreenRect, aRegion);
|
||||
|
||||
- bool needsClear = mWindow->WaylandSurfaceNeedsClear() ||
|
||||
- (isTransparentPopup && mDrawToWaylandBufferDirectly);
|
||||
+ // Clear buffer when we (re)draw new transparent popup window,
|
||||
+ // otherwise leave it as-is, mBufferNeedsClear can be set from previous
|
||||
+ // (already pending) commits which are cached now.
|
||||
+ if (mWholeWindowBufferDamage) {
|
||||
+ mBufferNeedsClear =
|
||||
+ mWindow->WaylandSurfaceNeedsClear() || isTransparentPopup;
|
||||
+ }
|
||||
|
||||
LOGWAYLAND(("%s [%p] lockSize [%d x %d] windowSize [%d x %d]\n",
|
||||
__PRETTY_FUNCTION__, (void*)this, lockSize.width, lockSize.height,
|
||||
- screenRect.width, screenRect.height));
|
||||
+ lockedScreenRect.width, lockedScreenRect.height));
|
||||
LOGWAYLAND((" nsWindow = %p\n", mWindow));
|
||||
LOGWAYLAND((" isPopup = %d\n", mWindow->IsWaylandPopup()));
|
||||
LOGWAYLAND((" isTransparentPopup = %d\n", isTransparentPopup));
|
||||
LOGWAYLAND((" IsPopupFullScreenUpdate = %d\n",
|
||||
- IsPopupFullScreenUpdate(screenRect, aRegion)));
|
||||
+ IsPopupFullScreenUpdate(lockedScreenRect, aRegion)));
|
||||
LOGWAYLAND((" IsWindowFullScreenUpdate = %d\n",
|
||||
- IsWindowFullScreenUpdate(screenRect, aRegion)));
|
||||
- LOGWAYLAND((" needsClear = %d\n", needsClear));
|
||||
- LOGWAYLAND(
|
||||
- (" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
|
||||
+ IsWindowFullScreenUpdate(lockedScreenRect, aRegion)));
|
||||
+ LOGWAYLAND((" mBufferNeedsClear = %d\n", mBufferNeedsClear));
|
||||
+ LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
+
|
||||
+#if DEBUG
|
||||
+ if (!(mBufferScreenRect == lockedScreenRect)) {
|
||||
+ LOGWAYLAND((" screen size changed\n"));
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
- // Allow full screen allocation and clear
|
||||
- // when window size changed.
|
||||
- bool bufferRedraw = !(screenRect == mLastScreenRect);
|
||||
- if (bufferRedraw) {
|
||||
- mDrawToWaylandBufferDirectly = true;
|
||||
- needsClear = true;
|
||||
+ if (!(mBufferScreenRect == lockedScreenRect)) {
|
||||
+ // Screen (window) size changed and we still have some painting pending
|
||||
+ // for the last window size. That can happen when window is resized.
|
||||
+ // We can't commit them any more as they're for former window size, so
|
||||
+ // scratch them.
|
||||
+ mDelayedImageCommits.Clear();
|
||||
+
|
||||
+ if (!mWholeWindowBufferDamage) {
|
||||
+ NS_WARNING("Partial screen update when window is resized!");
|
||||
+ // This should not happen. Screen size changed but we got only
|
||||
+ // partal screen update instead of whole screen. Discard this painting
|
||||
+ // as it produces artifacts.
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ mBufferScreenRect = lockedScreenRect;
|
||||
}
|
||||
|
||||
- if (mDrawToWaylandBufferDirectly) {
|
||||
+ if (mWholeWindowBufferDamage) {
|
||||
+ // We can lock/commit entire buffer direcly.
|
||||
+ mDrawToWaylandBufferDirectly = true;
|
||||
+
|
||||
// If there's any pending image commit scratch them as we're going
|
||||
// to redraw the whole sceen anyway.
|
||||
mDelayedImageCommits.Clear();
|
||||
|
||||
- RefPtr<gfx::DrawTarget> dt =
|
||||
- LockWaylandBuffer(screenRect.width, screenRect.height, needsClear,
|
||||
- /* aFullScreenUpdate */ true);
|
||||
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
+ /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
if (dt) {
|
||||
- if (bufferRedraw) {
|
||||
- mLastScreenRect = screenRect;
|
||||
- }
|
||||
return dt.forget();
|
||||
}
|
||||
+ }
|
||||
|
||||
- // We don't have any front buffer available. Try indirect drawing
|
||||
- // to mImageSurface which is mirrored to front buffer at commit.
|
||||
- mDrawToWaylandBufferDirectly = false;
|
||||
- }
|
||||
+ // We do indirect drawing due to:
|
||||
+ //
|
||||
+ // 1) We don't have any front buffer available. Try indirect drawing
|
||||
+ // to mImageSurface which is mirrored to front buffer at commit.
|
||||
+ // 2) Only part of the screen is locked. We can't lock entire screen for
|
||||
+ // such drawing as it produces visible artifacts.
|
||||
+ mDrawToWaylandBufferDirectly = false;
|
||||
|
||||
LOGWAYLAND((" Indirect drawing.\n"));
|
||||
return LockImageSurface(lockSize);
|
||||
@@ -851,16 +882,14 @@
|
||||
LayoutDeviceIntRegion& aWaylandBufferDamage) {
|
||||
MOZ_ASSERT(!mDrawToWaylandBufferDirectly);
|
||||
|
||||
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
|
||||
+#ifdef DEBUG
|
||||
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
-
|
||||
gfx::Rect rect(bounds);
|
||||
- if (rect.IsEmpty()) {
|
||||
- return false;
|
||||
- }
|
||||
+ MOZ_ASSERT(!rect.IsEmpty(), "Empty drawing?");
|
||||
+#endif
|
||||
|
||||
LOGWAYLAND(("%s [%p] screenSize [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, screenRect.width, screenRect.height));
|
||||
+ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
|
||||
RefPtr<gfx::SourceSurface> surf =
|
||||
gfx::Factory::CreateSourceSurfaceForCairoSurface(
|
||||
@@ -871,13 +900,8 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
- // Allow full screen allocation and clear
|
||||
- // when window size changed.
|
||||
- bool bufferRedraw = !(screenRect == mLastScreenRect);
|
||||
- RefPtr<gfx::DrawTarget> dt =
|
||||
- LockWaylandBuffer(screenRect.width, screenRect.height,
|
||||
- /* needs clear*/ bufferRedraw,
|
||||
- /* aFullScreenUpdate */ bufferRedraw);
|
||||
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
+ /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
if (dt) {
|
||||
LOGWAYLAND(
|
||||
(" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
|
||||
@@ -885,14 +909,11 @@
|
||||
|
||||
// Draw any delayed image commits first
|
||||
DrawDelayedImageCommits(dt, aWaylandBufferDamage);
|
||||
+ // Draw image from recent WindowSurfaceWayland::Lock().
|
||||
WindowImageSurface::Draw(surf, dt, aRegion);
|
||||
// Submit all drawing to final Wayland buffer upload
|
||||
aWaylandBufferDamage.OrWith(aRegion);
|
||||
UnlockWaylandBuffer();
|
||||
-
|
||||
- if (bufferRedraw) {
|
||||
- mLastScreenRect = screenRect;
|
||||
- }
|
||||
} else {
|
||||
mDelayedImageCommits.AppendElement(WindowImageSurface(surf, aRegion));
|
||||
LOGWAYLAND((" Added WindowImageSurfaces, cached surfaces %ld\n",
|
||||
@@ -930,29 +951,25 @@
|
||||
LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
LOGWAYLAND(
|
||||
(" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
|
||||
- LOGWAYLAND((" mWaylandBufferFullScreenDamage = %d\n",
|
||||
- mWaylandBufferFullScreenDamage));
|
||||
+ LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle));
|
||||
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
|
||||
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
|
||||
|
||||
if (!mDrawToWaylandBufferDirectly) {
|
||||
+ MOZ_ASSERT(mDelayedImageCommits.Length(),
|
||||
+ "Indirect drawing without any image?");
|
||||
+
|
||||
// There's some cached drawings - try to flush them now.
|
||||
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
|
||||
- bool bufferRedraw = !(screenRect == mLastScreenRect);
|
||||
- RefPtr<gfx::DrawTarget> dt =
|
||||
- LockWaylandBuffer(screenRect.width, screenRect.height,
|
||||
- /* needsClear */ bufferRedraw,
|
||||
- /* full screen update */ bufferRedraw);
|
||||
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
+ /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
+
|
||||
if (dt) {
|
||||
LOGWAYLAND(("%s [%p] flushed indirect drawing\n", __PRETTY_FUNCTION__,
|
||||
(void*)this));
|
||||
DrawDelayedImageCommits(dt, mWaylandBufferDamage);
|
||||
UnlockWaylandBuffer();
|
||||
mDrawToWaylandBufferDirectly = true;
|
||||
- if (bufferRedraw) {
|
||||
- mLastScreenRect = screenRect;
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1000,10 +1017,10 @@
|
||||
mLastCommittedSurface = nullptr;
|
||||
}
|
||||
|
||||
- if (mWaylandBufferFullScreenDamage) {
|
||||
- LayoutDeviceIntRect rect = mWindow->GetBounds();
|
||||
- wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height);
|
||||
- mWaylandBufferFullScreenDamage = false;
|
||||
+ if (mWholeWindowBufferDamage) {
|
||||
+ wl_surface_damage(waylandSurface, 0, 0, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height);
|
||||
+ mWholeWindowBufferDamage = false;
|
||||
mNeedScaleFactorUpdate = true;
|
||||
} else {
|
||||
gint scaleFactor = mWindow->GdkScaleFactor();
|
||||
@@ -1043,24 +1060,24 @@
|
||||
|
||||
#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, screenRect.height));
|
||||
+ lockSize.height, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n",
|
||||
mDrawToWaylandBufferDirectly));
|
||||
- LOGWAYLAND((" mWaylandBufferFullScreenDamage = %d\n",
|
||||
- mWaylandBufferFullScreenDamage));
|
||||
+ LOGWAYLAND(
|
||||
+ (" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mDrawToWaylandBufferDirectly) {
|
||||
MOZ_ASSERT(mWaylandBuffer->IsLocked());
|
||||
// If we're not at fullscreen damage add drawing area from aInvalidRegion
|
||||
- if (!mWaylandBufferFullScreenDamage) {
|
||||
+ if (!mWholeWindowBufferDamage) {
|
||||
mWaylandBufferDamage.OrWith(aInvalidRegion);
|
||||
}
|
||||
UnlockWaylandBuffer();
|
||||
|
@ -1,17 +0,0 @@
|
||||
diff --git a/widget/gtk/nsClipboardWayland.cpp b/widget/gtk/nsClipboardWayland.cpp
|
||||
--- a/widget/gtk/nsClipboardWayland.cpp
|
||||
+++ b/widget/gtk/nsClipboardWayland.cpp
|
||||
@@ -195,6 +195,12 @@
|
||||
uint32_t all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
|
||||
+ /* Default to move D&D action (Bug 1576268).
|
||||
+ */
|
||||
+ if (dnd_actions == 0) {
|
||||
+ all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
+ }
|
||||
+
|
||||
wl_data_offer_set_actions(mWaylandDataOffer, all_actions, dnd_actions);
|
||||
|
||||
/* Workaround Wayland D&D architecture here. To get the data_device_drop()
|
||||
|
@ -1,90 +0,0 @@
|
||||
diff -up firefox-69.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1577024 firefox-69.0/widget/gtk/nsWaylandDisplay.cpp
|
||||
--- firefox-69.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1577024 2019-09-17 21:09:15.817764591 +0200
|
||||
+++ firefox-69.0/widget/gtk/nsWaylandDisplay.cpp 2019-09-17 21:09:15.822764568 +0200
|
||||
@@ -13,10 +13,15 @@ namespace widget {
|
||||
#define GBMLIB_NAME "libgbm.so.1"
|
||||
#define DRMLIB_NAME "libdrm.so.2"
|
||||
|
||||
+#define DMABUF_PREF "widget.wayland_dmabuf_backend.enabled"
|
||||
+// See WindowSurfaceWayland::RenderingCacheMode for details.
|
||||
+#define CACHE_MODE_PREF "widget.wayland_cache_mode"
|
||||
+
|
||||
bool nsWaylandDisplay::mIsDMABufEnabled = false;
|
||||
// -1 mean the pref was not loaded yet
|
||||
int nsWaylandDisplay::mIsDMABufPrefState = -1;
|
||||
bool nsWaylandDisplay::mIsDMABufConfigured = false;
|
||||
+int nsWaylandDisplay::mRenderingCacheModePref = -1;
|
||||
|
||||
wl_display* WaylandDisplayGetWLDisplay(GdkDisplay* aGdkDisplay) {
|
||||
if (!aGdkDisplay) {
|
||||
@@ -373,14 +378,15 @@ nsWaylandDisplay::nsWaylandDisplay(wl_di
|
||||
wl_registry_add_listener(mRegistry, ®istry_listener, this);
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
- // We can't load the preference from compositor/render thread,
|
||||
- // only from main one. So we can't call it directly from
|
||||
- // nsWaylandDisplay::IsDMABufEnabled() as it can be called from various
|
||||
- // threads.
|
||||
+ // We can't load the preference from compositor/render thread
|
||||
+ // so load all Wayland prefs here.
|
||||
if (mIsDMABufPrefState == -1) {
|
||||
- mIsDMABufPrefState =
|
||||
- Preferences::GetBool("widget.wayland_dmabuf_backend.enabled", false);
|
||||
+ mIsDMABufPrefState = Preferences::GetBool(DMABUF_PREF, false);
|
||||
+ }
|
||||
+ if (mRenderingCacheModePref == -1) {
|
||||
+ mRenderingCacheModePref = Preferences::GetInt(CACHE_MODE_PREF, 0);
|
||||
}
|
||||
+
|
||||
// Use default event queue in main thread operated by Gtk+.
|
||||
mEventQueue = nullptr;
|
||||
wl_display_roundtrip(mDisplay);
|
||||
diff -up firefox-69.0/widget/gtk/nsWaylandDisplay.h.mozilla-1577024 firefox-69.0/widget/gtk/nsWaylandDisplay.h
|
||||
--- firefox-69.0/widget/gtk/nsWaylandDisplay.h.mozilla-1577024 2019-09-17 21:09:15.818764586 +0200
|
||||
+++ firefox-69.0/widget/gtk/nsWaylandDisplay.h 2019-09-17 21:09:15.822764568 +0200
|
||||
@@ -83,6 +83,9 @@ class nsWaylandDisplay {
|
||||
uint32_t mModifierLo);
|
||||
static bool IsDMABufEnabled();
|
||||
|
||||
+ // See WindowSurfaceWayland::CacheMode for details.
|
||||
+ int GetRenderingCacheModePref() { return mRenderingCacheModePref; };
|
||||
+
|
||||
private:
|
||||
bool ConfigureGbm();
|
||||
|
||||
@@ -108,6 +111,7 @@ class nsWaylandDisplay {
|
||||
static bool mIsDMABufEnabled;
|
||||
static int mIsDMABufPrefState;
|
||||
static bool mIsDMABufConfigured;
|
||||
+ static int mRenderingCacheModePref;
|
||||
};
|
||||
|
||||
void WaylandDispatchDisplays();
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1577024 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1577024 2019-09-17 21:09:15.820764577 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-18 08:34:50.568111279 +0200
|
||||
@@ -192,7 +192,7 @@ It owns wl_buffer object, owns WaylandDM
|
||||
(which provides the DMA Buffer) and ties them together.
|
||||
|
||||
WindowBackBufferDMABuf backend is used only when WaylandDMABufSurface is
|
||||
-available and gfx.wayland_dmabuf_backend.enabled preference is set.
|
||||
+available and widget.wayland_dmabuf_backend.enabled preference is set.
|
||||
|
||||
*/
|
||||
|
||||
@@ -519,9 +519,11 @@ WindowSurfaceWayland::WindowSurfaceWayla
|
||||
mBufferNeedsClear(false),
|
||||
mIsMainThread(NS_IsMainThread()),
|
||||
mNeedScaleFactorUpdate(true) {
|
||||
- for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
|
||||
- mRenderingCacheMode = CACHE_ALL;
|
||||
-
|
||||
+ for (int i = 0; i < BACK_BUFFER_NUM; i++) {
|
||||
+ mBackupBuffer[i] = nullptr;
|
||||
+ }
|
||||
+ mRenderingCacheMode = static_cast<RenderingCacheMode>(
|
||||
+ mWaylandDisplay->GetRenderingCacheModePref());
|
||||
}
|
||||
|
||||
WindowSurfaceWayland::~WindowSurfaceWayland() {
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1577024 firefox-69.0/widget/gtk/WindowSurfaceWayland.h
|
@ -1,134 +0,0 @@
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h
|
||||
--- a/widget/gtk/WindowSurfaceWayland.h
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.h
|
||||
@@ -154,11 +154,12 @@
|
||||
void Draw(gfx::DrawTarget* aDest,
|
||||
LayoutDeviceIntRegion& aWaylandBufferDamage);
|
||||
|
||||
- WindowImageSurface(gfx::SourceSurface* aSurface,
|
||||
+ WindowImageSurface(gfxImageSurface* aImageSurface,
|
||||
const LayoutDeviceIntRegion& aUpdateRegion);
|
||||
|
||||
private:
|
||||
RefPtr<gfx::SourceSurface> mSurface;
|
||||
+ RefPtr<gfxImageSurface> mImageSurface;
|
||||
const LayoutDeviceIntRegion mUpdateRegion;
|
||||
};
|
||||
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- a/widget/gtk/WindowSurfaceWayland.cpp
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
@@ -890,8 +890,12 @@
|
||||
}
|
||||
|
||||
WindowImageSurface::WindowImageSurface(
|
||||
- gfx::SourceSurface* aSurface, const LayoutDeviceIntRegion& aUpdateRegion)
|
||||
- : mSurface(aSurface), mUpdateRegion(aUpdateRegion){};
|
||||
+ gfxImageSurface* aImageSurface, const LayoutDeviceIntRegion& aUpdateRegion)
|
||||
+ : mImageSurface(aImageSurface), mUpdateRegion(aUpdateRegion) {
|
||||
+ mSurface = gfx::Factory::CreateSourceSurfaceForCairoSurface(
|
||||
+ mImageSurface->CairoSurface(), mImageSurface->GetSize(),
|
||||
+ mImageSurface->Format());
|
||||
+}
|
||||
|
||||
void WindowSurfaceWayland::DrawDelayedImageCommits(
|
||||
gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) {
|
||||
@@ -915,36 +919,24 @@
|
||||
LOGWAYLAND(("%s [%p] screenSize [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
(void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
|
||||
- RefPtr<gfx::SourceSurface> surf =
|
||||
- gfx::Factory::CreateSourceSurfaceForCairoSurface(
|
||||
- mImageSurface->CairoSurface(), mImageSurface->GetSize(),
|
||||
- mImageSurface->Format());
|
||||
- if (!surf) {
|
||||
- NS_WARNING("Failed to create source cairo surface!");
|
||||
- return false;
|
||||
- }
|
||||
+ mDelayedImageCommits.AppendElement(
|
||||
+ WindowImageSurface(mImageSurface, aRegion));
|
||||
+ // mImageSurface is owned by mDelayedImageCommits
|
||||
+ mImageSurface = nullptr;
|
||||
|
||||
RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
/* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
- if (dt) {
|
||||
- LOGWAYLAND(
|
||||
- (" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
|
||||
- long(mDelayedImageCommits.Length() + 1)));
|
||||
-
|
||||
- // Draw any delayed image commits first
|
||||
- DrawDelayedImageCommits(dt, aWaylandBufferDamage);
|
||||
- // Draw image from recent WindowSurfaceWayland::Lock().
|
||||
- WindowImageSurface::Draw(surf, dt, aRegion);
|
||||
- // Submit all drawing to final Wayland buffer upload
|
||||
- aWaylandBufferDamage.OrWith(aRegion);
|
||||
- UnlockWaylandBuffer();
|
||||
- } else {
|
||||
- mDelayedImageCommits.AppendElement(WindowImageSurface(surf, aRegion));
|
||||
- LOGWAYLAND((" Added WindowImageSurfaces, cached surfaces %ld\n",
|
||||
- long(mDelayedImageCommits.Length())));
|
||||
+ if (!dt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ LOGWAYLAND((" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
|
||||
+ long(mDelayedImageCommits.Length() + 1)));
|
||||
+
|
||||
+ // Draw any delayed image commits first
|
||||
+ DrawDelayedImageCommits(dt, aWaylandBufferDamage);
|
||||
+ UnlockWaylandBuffer();
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -980,23 +972,6 @@
|
||||
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
|
||||
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
|
||||
|
||||
- if (!mDrawToWaylandBufferDirectly) {
|
||||
- MOZ_ASSERT(mDelayedImageCommits.Length(),
|
||||
- "Indirect drawing without any image?");
|
||||
-
|
||||
- // There's some cached drawings - try to flush them now.
|
||||
- RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
- /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
-
|
||||
- if (dt) {
|
||||
- LOGWAYLAND(("%s [%p] flushed indirect drawing\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this));
|
||||
- DrawDelayedImageCommits(dt, mWaylandBufferDamage);
|
||||
- UnlockWaylandBuffer();
|
||||
- mDrawToWaylandBufferDirectly = true;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
wl_surface* waylandSurface = mWindow->GetWaylandSurface();
|
||||
if (!waylandSurface) {
|
||||
LOGWAYLAND(("%s [%p] mWindow->GetWaylandSurface() failed, delay commit.\n",
|
||||
@@ -1105,6 +1080,7 @@
|
||||
mWaylandBufferDamage.OrWith(aInvalidRegion);
|
||||
}
|
||||
UnlockWaylandBuffer();
|
||||
+ mPendingCommit = true;
|
||||
} else {
|
||||
MOZ_ASSERT(!mWaylandBuffer->IsLocked(),
|
||||
"Drawing to already locked buffer?");
|
||||
@@ -1112,12 +1088,13 @@
|
||||
mWaylandBufferDamage)) {
|
||||
// Our cached drawing is flushed, we can draw fullscreen again.
|
||||
mDrawToWaylandBufferDirectly = true;
|
||||
+ mPendingCommit = true;
|
||||
}
|
||||
}
|
||||
|
||||
- // We're ready to commit.
|
||||
- mPendingCommit = true;
|
||||
- CommitWaylandBuffer();
|
||||
+ if (mPendingCommit) {
|
||||
+ CommitWaylandBuffer();
|
||||
+ }
|
||||
}
|
||||
|
||||
void WindowSurfaceWayland::FrameCallbackHandler() {
|
||||
|
@ -1,166 +0,0 @@
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h
|
||||
--- a/widget/gtk/WindowSurfaceWayland.h
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.h
|
||||
@@ -204,7 +204,6 @@
|
||||
const LayoutDeviceIntRegion& aRegion,
|
||||
LayoutDeviceIntRegion& aWaylandBufferDamage);
|
||||
void CommitWaylandBuffer();
|
||||
- void CalcRectScale(LayoutDeviceIntRect& aRect, int scale);
|
||||
|
||||
void DrawDelayedImageCommits(gfx::DrawTarget* aDrawTarget,
|
||||
LayoutDeviceIntRegion& aWaylandBufferDamage);
|
||||
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- a/widget/gtk/WindowSurfaceWayland.cpp
|
||||
+++ b/widget/gtk/WindowSurfaceWayland.cpp
|
||||
@@ -951,16 +951,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
-void WindowSurfaceWayland::CalcRectScale(LayoutDeviceIntRect& aRect,
|
||||
- int aScale) {
|
||||
- aRect.x = aRect.x / aScale;
|
||||
- aRect.y = aRect.y / aScale;
|
||||
-
|
||||
- // We don't need exact damage size - just safely cover the round errors.
|
||||
- aRect.width = (aRect.width / aScale) + 2;
|
||||
- aRect.height = (aRect.height / aScale) + 2;
|
||||
-}
|
||||
-
|
||||
void WindowSurfaceWayland::CommitWaylandBuffer() {
|
||||
MOZ_ASSERT(mPendingCommit, "Committing empty surface!");
|
||||
|
||||
@@ -1022,16 +1012,10 @@
|
||||
mWholeWindowBufferDamage = false;
|
||||
mNeedScaleFactorUpdate = true;
|
||||
} else {
|
||||
- gint scaleFactor = mWindow->GdkScaleFactor();
|
||||
for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done();
|
||||
iter.Next()) {
|
||||
mozilla::LayoutDeviceIntRect r = iter.Get();
|
||||
- // We need to remove the scale factor because the wl_surface_damage
|
||||
- // also multiplies by current scale factor.
|
||||
- if (scaleFactor > 1) {
|
||||
- CalcRectScale(r, scaleFactor);
|
||||
- }
|
||||
- wl_surface_damage(waylandSurface, r.x, r.y, r.width, r.height);
|
||||
+ wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/widget/gtk/mozcontainer.cpp b/widget/gtk/mozcontainer.cpp
|
||||
--- a/widget/gtk/mozcontainer.cpp
|
||||
+++ b/widget/gtk/mozcontainer.cpp
|
||||
@@ -578,16 +578,12 @@
|
||||
return nullptr;
|
||||
}
|
||||
GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
+ nsWaylandDisplay* waylandDisplay = WaylandDisplayGet(display);
|
||||
|
||||
// Available as of GTK 3.8+
|
||||
- static auto sGdkWaylandDisplayGetWlCompositor =
|
||||
- (wl_compositor * (*)(GdkDisplay*))
|
||||
- dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_compositor");
|
||||
- struct wl_compositor* compositor =
|
||||
- sGdkWaylandDisplayGetWlCompositor(display);
|
||||
+ struct wl_compositor* compositor = waylandDisplay->GetCompositor();
|
||||
container->surface = wl_compositor_create_surface(compositor);
|
||||
|
||||
- nsWaylandDisplay* waylandDisplay = WaylandDisplayGet(display);
|
||||
container->subsurface = wl_subcompositor_get_subsurface(
|
||||
waylandDisplay->GetSubcompositor(), container->surface,
|
||||
moz_container_get_gtk_container_surface(container));
|
||||
diff --git a/widget/gtk/mozwayland/mozwayland.h b/widget/gtk/mozwayland/mozwayland.h
|
||||
--- a/widget/gtk/mozwayland/mozwayland.h
|
||||
+++ b/widget/gtk/mozwayland/mozwayland.h
|
||||
@@ -108,6 +108,17 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifndef WL_SURFACE_DAMAGE_BUFFER
|
||||
+# define WL_SURFACE_DAMAGE_BUFFER 9
|
||||
+
|
||||
+static inline void wl_surface_damage_buffer(struct wl_surface* wl_surface,
|
||||
+ int32_t x, int32_t y, int32_t width,
|
||||
+ int32_t height) {
|
||||
+ wl_proxy_marshal((struct wl_proxy*)wl_surface, WL_SURFACE_DAMAGE_BUFFER, x, y,
|
||||
+ width, height);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/widget/gtk/mozwayland/mozwayland.c b/widget/gtk/mozwayland/mozwayland.c
|
||||
--- a/widget/gtk/mozwayland/mozwayland.c
|
||||
+++ b/widget/gtk/mozwayland/mozwayland.c
|
||||
@@ -30,6 +30,7 @@
|
||||
const struct wl_interface wl_seat_interface;
|
||||
const struct wl_interface wl_surface_interface;
|
||||
const struct wl_interface wl_subsurface_interface;
|
||||
+const struct wl_interface wl_compositor_interface;
|
||||
const struct wl_interface wl_subcompositor_interface;
|
||||
#pragma GCC visibility pop
|
||||
|
||||
diff --git a/widget/gtk/nsWaylandDisplay.h b/widget/gtk/nsWaylandDisplay.h
|
||||
--- a/widget/gtk/nsWaylandDisplay.h
|
||||
+++ b/widget/gtk/nsWaylandDisplay.h
|
||||
@@ -45,6 +45,7 @@
|
||||
MessageLoop* GetDispatcherThreadLoop() { return mDispatcherThreadLoop; }
|
||||
wl_display* GetDisplay() { return mDisplay; };
|
||||
wl_event_queue* GetEventQueue() { return mEventQueue; };
|
||||
+ wl_compositor* GetCompositor(void) { return mCompositor; };
|
||||
wl_subcompositor* GetSubcompositor(void) { return mSubcompositor; };
|
||||
wl_data_device_manager* GetDataDeviceManager(void) {
|
||||
return mDataDeviceManager;
|
||||
@@ -56,6 +57,7 @@
|
||||
};
|
||||
|
||||
void SetShm(wl_shm* aShm);
|
||||
+ void SetCompositor(wl_compositor* aCompositor);
|
||||
void SetSubcompositor(wl_subcompositor* aSubcompositor);
|
||||
void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager);
|
||||
void SetSeat(wl_seat* aSeat);
|
||||
@@ -88,6 +90,7 @@
|
||||
wl_display* mDisplay;
|
||||
wl_event_queue* mEventQueue;
|
||||
wl_data_device_manager* mDataDeviceManager;
|
||||
+ wl_compositor* mCompositor;
|
||||
wl_subcompositor* mSubcompositor;
|
||||
wl_seat* mSeat;
|
||||
wl_shm* mShm;
|
||||
diff --git a/widget/gtk/nsWaylandDisplay.cpp b/widget/gtk/nsWaylandDisplay.cpp
|
||||
--- a/widget/gtk/nsWaylandDisplay.cpp
|
||||
+++ b/widget/gtk/nsWaylandDisplay.cpp
|
||||
@@ -116,6 +116,10 @@
|
||||
|
||||
void nsWaylandDisplay::SetShm(wl_shm* aShm) { mShm = aShm; }
|
||||
|
||||
+void nsWaylandDisplay::SetCompositor(wl_compositor* aCompositor) {
|
||||
+ mCompositor = aCompositor;
|
||||
+}
|
||||
+
|
||||
void nsWaylandDisplay::SetSubcompositor(wl_subcompositor* aSubcompositor) {
|
||||
mSubcompositor = aSubcompositor;
|
||||
}
|
||||
@@ -223,6 +227,12 @@
|
||||
wl_proxy_set_queue((struct wl_proxy*)primary_selection_device_manager,
|
||||
display->GetEventQueue());
|
||||
display->SetPrimarySelectionDeviceManager(primary_selection_device_manager);
|
||||
+ } else if (strcmp(interface, "wl_compositor") == 0) {
|
||||
+ // Requested wl_compositor version 4 as we need wl_surface_damage_buffer().
|
||||
+ auto compositor = static_cast<wl_compositor*>(
|
||||
+ wl_registry_bind(registry, id, &wl_compositor_interface, 4));
|
||||
+ wl_proxy_set_queue((struct wl_proxy*)compositor, display->GetEventQueue());
|
||||
+ display->SetCompositor(compositor);
|
||||
} else if (strcmp(interface, "wl_subcompositor") == 0) {
|
||||
auto subcompositor = static_cast<wl_subcompositor*>(
|
||||
wl_registry_bind(registry, id, &wl_subcompositor_interface, 1));
|
||||
@@ -306,6 +316,7 @@
|
||||
mDisplay(aDisplay),
|
||||
mEventQueue(nullptr),
|
||||
mDataDeviceManager(nullptr),
|
||||
+ mCompositor(nullptr),
|
||||
mSubcompositor(nullptr),
|
||||
mSeat(nullptr),
|
||||
mShm(nullptr),
|
||||
|
@ -1,306 +0,0 @@
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1579823 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1579823 2019-09-12 07:53:06.119602913 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-12 07:54:47.410105270 +0200
|
||||
@@ -326,13 +326,13 @@ void WindowBackBufferShm::Create(int aWi
|
||||
mHeight = aHeight;
|
||||
|
||||
LOGWAYLAND((
|
||||
- "%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this,
|
||||
+ "WindowBackBufferShm::Create [%p] wl_buffer %p ID %d\n", (void*)this,
|
||||
(void*)mWaylandBuffer,
|
||||
mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1));
|
||||
}
|
||||
|
||||
void WindowBackBufferShm::Release() {
|
||||
- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND(("WindowBackBufferShm::Release [%p]\n", (void*)this));
|
||||
|
||||
wl_buffer_destroy(mWaylandBuffer);
|
||||
mWidth = mHeight = 0;
|
||||
@@ -358,8 +358,8 @@ WindowBackBufferShm::~WindowBackBufferSh
|
||||
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));
|
||||
+ LOGWAYLAND(("WindowBackBufferShm::Resize [%p] %d %d\n", (void*)this, aWidth,
|
||||
+ aHeight));
|
||||
|
||||
Release();
|
||||
Create(aWidth, aHeight);
|
||||
@@ -369,7 +369,7 @@ bool WindowBackBufferShm::Resize(int aWi
|
||||
|
||||
void WindowBackBuffer::Attach(wl_surface* aSurface) {
|
||||
LOGWAYLAND(
|
||||
- ("%s [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", __PRETTY_FUNCTION__,
|
||||
+ ("WindowBackBuffer::Attach [%p] wl_surface %p ID %d wl_buffer %p ID %d\n",
|
||||
(void*)this, (void*)aSurface,
|
||||
aSurface ? wl_proxy_get_id((struct wl_proxy*)aSurface) : -1,
|
||||
(void*)GetWlBuffer(),
|
||||
@@ -382,8 +382,8 @@ void WindowBackBuffer::Attach(wl_surface
|
||||
}
|
||||
|
||||
void WindowBackBufferShm::Detach(wl_buffer* aBuffer) {
|
||||
- LOGWAYLAND(("%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this,
|
||||
- (void*)aBuffer,
|
||||
+ LOGWAYLAND(("WindowBackBufferShm::Detach [%p] wl_buffer %p ID %d\n",
|
||||
+ (void*)this, (void*)aBuffer,
|
||||
aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1));
|
||||
|
||||
mAttached = false;
|
||||
@@ -404,7 +404,7 @@ bool WindowBackBufferShm::SetImageDataFr
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> WindowBackBufferShm::Lock() {
|
||||
LOGWAYLAND((
|
||||
- "%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__,
|
||||
+ "WindowBackBufferShm::Lock [%p] [%d x %d] wl_buffer %p ID %d\n",
|
||||
(void*)this, mWidth, mHeight, (void*)mWaylandBuffer,
|
||||
mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1));
|
||||
|
||||
@@ -419,16 +419,17 @@ WindowBackBufferDMABuf::WindowBackBuffer
|
||||
nsWaylandDisplay* aWaylandDisplay, int aWidth, int aHeight)
|
||||
: WindowBackBuffer(aWaylandDisplay) {
|
||||
mDMAbufSurface.Create(aWidth, aHeight);
|
||||
-
|
||||
- LOGWAYLAND(("%s [%p] Created DMABuf buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, aWidth, aHeight));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowBackBufferDMABuf::WindowBackBufferDMABuf [%p] Created DMABuf "
|
||||
+ "buffer [%d x %d]\n",
|
||||
+ (void*)this, 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__,
|
||||
+ ("WindowBackBufferDMABuf::Lock [%p] [%d x %d] wl_buffer %p ID %d\n",
|
||||
(void*)this, GetWidth(), GetHeight(), (void*)GetWlBuffer(),
|
||||
GetWlBuffer() ? wl_proxy_get_id((struct wl_proxy*)GetWlBuffer()) : -1));
|
||||
|
||||
@@ -534,7 +535,8 @@ WindowSurfaceWayland::~WindowSurfaceWayl
|
||||
bool WindowSurfaceWayland::UseDMABufBackend() {
|
||||
if (!mUseDMABufInitialized) {
|
||||
mUseDMABuf = nsWaylandDisplay::IsDMABufEnabled();
|
||||
- LOGWAYLAND(("%s DMABuf state %d\n", __PRETTY_FUNCTION__, mUseDMABuf));
|
||||
+ LOGWAYLAND(("WindowSurfaceWayland::UseDMABufBackend DMABuf state %d\n",
|
||||
+ mUseDMABuf));
|
||||
mUseDMABufInitialized = true;
|
||||
}
|
||||
return mUseDMABuf;
|
||||
@@ -567,15 +569,16 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
|
||||
WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(
|
||||
bool aCanSwitchBuffer) {
|
||||
- LOGWAYLAND(("%s [%p] Requested buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::GetWaylandBufferToDraw [%p] Requested buffer [%d "
|
||||
+ "x %d]\n",
|
||||
+ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
|
||||
// There's no buffer created yet, create a new one.
|
||||
if (!mWaylandBuffer) {
|
||||
MOZ_ASSERT(aCanSwitchBuffer && mWholeWindowBufferDamage,
|
||||
"Created new buffer for partial drawing!");
|
||||
- LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, mBufferScreenRect.width,
|
||||
+ LOGWAYLAND((" Created new buffer [%d x %d]\n", mBufferScreenRect.width,
|
||||
mBufferScreenRect.height));
|
||||
|
||||
mWaylandBuffer =
|
||||
@@ -586,21 +589,19 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mWaylandBuffer->IsAttached()) {
|
||||
- LOGWAYLAND(("%s [%p] Buffer %p is attached, need to find a new one.\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, mWaylandBuffer));
|
||||
+ LOGWAYLAND((" Buffer %p is attached, need to find a new one.\n",
|
||||
+ mWaylandBuffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reuse existing buffer
|
||||
if (!mWaylandBuffer->IsAttached()) {
|
||||
- LOGWAYLAND(
|
||||
- ("%s [%p] Use recent buffer.\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND((" Use recent buffer.\n"));
|
||||
|
||||
if (mWaylandBuffer->IsMatchingSize(mBufferScreenRect.width,
|
||||
mBufferScreenRect.height)) {
|
||||
- LOGWAYLAND(("%s [%p] Size is ok, use the buffer [%d x %d]\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width,
|
||||
- mBufferScreenRect.height));
|
||||
+ LOGWAYLAND((" Size is ok, use the buffer [%d x %d]\n",
|
||||
+ mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
return mWaylandBuffer;
|
||||
}
|
||||
|
||||
@@ -609,9 +610,8 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- LOGWAYLAND(("%s [%p] Reuse buffer with resize [%d x %d]\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width,
|
||||
- mBufferScreenRect.height));
|
||||
+ LOGWAYLAND((" Reuse buffer with resize [%d x %d]\n",
|
||||
+ mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
|
||||
mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
// There's a chance that scale factor has been changed
|
||||
@@ -629,8 +629,7 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
for (availableBuffer = 0; availableBuffer < BACK_BUFFER_NUM;
|
||||
availableBuffer++) {
|
||||
if (!mBackupBuffer[availableBuffer]) {
|
||||
- LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, mBufferScreenRect.width,
|
||||
+ LOGWAYLAND((" Created new buffer [%d x %d]\n", mBufferScreenRect.width,
|
||||
mBufferScreenRect.height));
|
||||
mBackupBuffer[availableBuffer] = CreateWaylandBuffer(
|
||||
mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
@@ -643,8 +642,7 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) {
|
||||
- LOGWAYLAND(("%s [%p] No drawing buffer available!\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this));
|
||||
+ LOGWAYLAND((" No drawing buffer available!\n"));
|
||||
NS_WARNING("No drawing buffer available");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -653,17 +651,15 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
mWaylandBuffer = mBackupBuffer[availableBuffer];
|
||||
mBackupBuffer[availableBuffer] = lastWaylandBuffer;
|
||||
|
||||
- LOGWAYLAND(("%s [%p] Buffer flip new back %p new front %p \n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, (void*)lastWaylandBuffer,
|
||||
- (void*)mWaylandBuffer));
|
||||
+ LOGWAYLAND((" Buffer flip new back %p new front %p \n",
|
||||
+ (void*)lastWaylandBuffer, (void*)mWaylandBuffer));
|
||||
|
||||
mNeedScaleFactorUpdate = true;
|
||||
|
||||
bool bufferNeedsResize = !mWaylandBuffer->IsMatchingSize(
|
||||
mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
if (bufferNeedsResize) {
|
||||
- LOGWAYLAND(("%s [%p] Resize buffer to [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, mBufferScreenRect.width,
|
||||
+ LOGWAYLAND((" Resize buffer to [%d x %d]\n", mBufferScreenRect.width,
|
||||
mBufferScreenRect.height));
|
||||
mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height);
|
||||
}
|
||||
@@ -675,8 +671,8 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
bool aCanSwitchBuffer) {
|
||||
WindowBackBuffer* buffer = GetWaylandBufferToDraw(aCanSwitchBuffer);
|
||||
|
||||
- LOGWAYLAND(("%s [%p] Got buffer %p\n", __PRETTY_FUNCTION__, (void*)this,
|
||||
- (void*)buffer));
|
||||
+ LOGWAYLAND(("WindowSurfaceWayland::LockWaylandBuffer [%p] Got buffer %p\n",
|
||||
+ (void*)this, (void*)buffer));
|
||||
|
||||
if (!buffer) {
|
||||
return nullptr;
|
||||
@@ -691,7 +687,7 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
}
|
||||
|
||||
void WindowSurfaceWayland::UnlockWaylandBuffer() {
|
||||
- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND(("WindowSurfaceWayland::UnlockWaylandBuffer [%p]\n", (void*)this));
|
||||
mWaylandBuffer->Unlock();
|
||||
}
|
||||
|
||||
@@ -774,9 +770,11 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
mWindow->WaylandSurfaceNeedsClear() || isTransparentPopup;
|
||||
}
|
||||
|
||||
- LOGWAYLAND(("%s [%p] lockSize [%d x %d] windowSize [%d x %d]\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this, lockSize.width, lockSize.height,
|
||||
- lockedScreenRect.width, lockedScreenRect.height));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::Lock [%p] lockSize [%d x %d] windowSize [%d x "
|
||||
+ "%d]\n",
|
||||
+ (void*)this, lockSize.width, lockSize.height, lockedScreenRect.width,
|
||||
+ lockedScreenRect.height));
|
||||
LOGWAYLAND((" nsWindow = %p\n", mWindow));
|
||||
LOGWAYLAND((" isPopup = %d\n", mWindow->IsWaylandPopup()));
|
||||
LOGWAYLAND((" isTransparentPopup = %d\n", isTransparentPopup));
|
||||
@@ -892,8 +890,10 @@ bool WindowSurfaceWayland::CommitImageSu
|
||||
MOZ_ASSERT(!rect.IsEmpty(), "Empty drawing?");
|
||||
#endif
|
||||
|
||||
- LOGWAYLAND(("%s [%p] screenSize [%d x %d]\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer [%p] "
|
||||
+ "screenSize [%d x %d]\n",
|
||||
+ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
|
||||
mDelayedImageCommits.AppendElement(
|
||||
WindowImageSurface(mImageSurface, aRegion));
|
||||
@@ -930,7 +930,7 @@ static void WaylandBufferDelayCommitHand
|
||||
void WindowSurfaceWayland::CommitWaylandBuffer() {
|
||||
MOZ_ASSERT(mPendingCommit, "Committing empty surface!");
|
||||
|
||||
- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this));
|
||||
LOGWAYLAND(
|
||||
(" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
|
||||
LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
@@ -940,8 +940,8 @@ void WindowSurfaceWayland::CommitWayland
|
||||
|
||||
wl_surface* waylandSurface = mWindow->GetWaylandSurface();
|
||||
if (!waylandSurface) {
|
||||
- LOGWAYLAND(("%s [%p] mWindow->GetWaylandSurface() failed, delay commit.\n",
|
||||
- __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND((" [%p] mWindow->GetWaylandSurface() failed, delay commit.\n",
|
||||
+ (void*)this));
|
||||
|
||||
// Target window is not created yet - delay the commit. This can happen only
|
||||
// when the window is newly created and there's no active
|
||||
@@ -969,8 +969,7 @@ void WindowSurfaceWayland::CommitWayland
|
||||
// We have an active frame callback request so handle it.
|
||||
if (mFrameCallback) {
|
||||
if (waylandSurface == mLastCommittedSurface) {
|
||||
- LOGWAYLAND(("%s [%p] wait for frame callback.\n", __PRETTY_FUNCTION__,
|
||||
- (void*)this));
|
||||
+ LOGWAYLAND((" [%p] wait for frame callback.\n", (void*)this));
|
||||
// We have an active frame callback pending from our recent surface.
|
||||
// It means we should defer the commit to FrameCallbackHandler().
|
||||
return;
|
||||
@@ -1022,10 +1021,11 @@ void WindowSurfaceWayland::Commit(const
|
||||
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, mBufferScreenRect.width,
|
||||
- mBufferScreenRect.height));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::Commit [%p] lockSize [%d x %d] screenSize [%d "
|
||||
+ "x %d]\n",
|
||||
+ (void*)this, lockSize.width, lockSize.height, mBufferScreenRect.width,
|
||||
+ mBufferScreenRect.height));
|
||||
LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n",
|
||||
mDrawToWaylandBufferDirectly));
|
||||
LOGWAYLAND(
|
||||
@@ -1064,7 +1064,8 @@ void WindowSurfaceWayland::FrameCallback
|
||||
MOZ_ASSERT(mLastCommittedSurface != nullptr,
|
||||
"FrameCallbackHandler() called without valid wl_surface!");
|
||||
|
||||
- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::FrameCallbackHandler [%p]\n", (void*)this));
|
||||
|
||||
wl_callback_destroy(mFrameCallback);
|
||||
mFrameCallback = nullptr;
|
||||
@@ -1077,7 +1078,8 @@ void WindowSurfaceWayland::FrameCallback
|
||||
void WindowSurfaceWayland::DelayedCommitHandler() {
|
||||
MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!");
|
||||
|
||||
- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::DelayedCommitHandler [%p]\n", (void*)this));
|
||||
|
||||
*mDelayedCommitHandle = nullptr;
|
||||
free(mDelayedCommitHandle);
|
@ -1,14 +0,0 @@
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.old firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.old 2019-09-11 14:34:36.687382704 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-11 14:39:02.000391578 +0200
|
||||
@@ -751,6 +751,10 @@ static bool IsPopupFullScreenUpdate(Layo
|
||||
already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock(
|
||||
const LayoutDeviceIntRegion& aRegion) {
|
||||
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
+
|
||||
+ // Disable all commits from frame callback handler and delayed comit handler
|
||||
+ // as we're updated by gecko compositor.
|
||||
+ mPendingCommit = false;
|
||||
|
||||
LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
|
||||
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
@ -1,618 +0,0 @@
|
||||
diff -up firefox-69.0/widget/gtk/mozwayland/mozwayland.h.mozilla-1580152 firefox-69.0/widget/gtk/mozwayland/mozwayland.h
|
||||
--- firefox-69.0/widget/gtk/mozwayland/mozwayland.h.mozilla-1580152 2019-09-16 11:11:30.081299217 +0200
|
||||
+++ firefox-69.0/widget/gtk/mozwayland/mozwayland.h 2019-09-16 11:11:30.089299191 +0200
|
||||
@@ -27,6 +27,9 @@ MOZ_EXPORT struct wl_proxy* wl_proxy_mar
|
||||
struct wl_proxy* proxy, uint32_t opcode,
|
||||
const struct wl_interface* interface, ...);
|
||||
|
||||
+MOZ_EXPORT void* wl_proxy_create_wrapper(void* proxy);
|
||||
+MOZ_EXPORT void wl_proxy_wrapper_destroy(void* proxy_wrapper);
|
||||
+
|
||||
/* We need implement some missing functions from wayland-client-protocol.h
|
||||
*/
|
||||
#ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM
|
||||
diff -up firefox-69.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1580152 firefox-69.0/widget/gtk/nsWaylandDisplay.cpp
|
||||
--- firefox-69.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1580152 2019-09-16 11:11:30.081299217 +0200
|
||||
+++ firefox-69.0/widget/gtk/nsWaylandDisplay.cpp 2019-09-16 11:11:30.089299191 +0200
|
||||
@@ -243,6 +243,61 @@ bool nsWaylandDisplay::DispatchEventQueu
|
||||
return true;
|
||||
}
|
||||
|
||||
+void nsWaylandDisplay::SyncEnd() {
|
||||
+ wl_callback_destroy(mSyncCallback);
|
||||
+ mSyncCallback = NULL;
|
||||
+}
|
||||
+
|
||||
+static void wayland_sync_callback(void* data, struct wl_callback* callback,
|
||||
+ uint32_t time) {
|
||||
+ auto display = static_cast<nsWaylandDisplay*>(data);
|
||||
+ display->SyncEnd();
|
||||
+}
|
||||
+
|
||||
+static const struct wl_callback_listener sync_callback_listener = {
|
||||
+ .done = wayland_sync_callback};
|
||||
+
|
||||
+void nsWaylandDisplay::SyncBegin() {
|
||||
+ WaitForSyncEnd();
|
||||
+
|
||||
+ // Use wl_display_sync() to synchronize wayland events.
|
||||
+ // See dri2_wl_swap_buffers_with_damage() from MESA
|
||||
+ // or wl_display_roundtrip_queue() from wayland-client.
|
||||
+ struct wl_display* displayWrapper =
|
||||
+ static_cast<wl_display*>(wl_proxy_create_wrapper((void*)mDisplay));
|
||||
+ if (!displayWrapper) {
|
||||
+ NS_WARNING("Failed to create wl_proxy wrapper!");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wl_proxy_set_queue((struct wl_proxy*)displayWrapper, mEventQueue);
|
||||
+ mSyncCallback = wl_display_sync(displayWrapper);
|
||||
+ wl_proxy_wrapper_destroy((void*)displayWrapper);
|
||||
+
|
||||
+ if (!mSyncCallback) {
|
||||
+ NS_WARNING("Failed to create wl_display_sync callback!");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wl_callback_add_listener(mSyncCallback, &sync_callback_listener, this);
|
||||
+ wl_display_flush(mDisplay);
|
||||
+}
|
||||
+
|
||||
+void nsWaylandDisplay::WaitForSyncEnd() {
|
||||
+ // We're done here
|
||||
+ if (!mSyncCallback) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (mSyncCallback != NULL) {
|
||||
+ if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1) {
|
||||
+ NS_WARNING("wl_display_dispatch_queue failed!");
|
||||
+ SyncEnd();
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
bool nsWaylandDisplay::Matches(wl_display* aDisplay) {
|
||||
return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay;
|
||||
}
|
||||
@@ -305,6 +360,7 @@ nsWaylandDisplay::nsWaylandDisplay(wl_di
|
||||
mSubcompositor(nullptr),
|
||||
mSeat(nullptr),
|
||||
mShm(nullptr),
|
||||
+ mSyncCallback(nullptr),
|
||||
mPrimarySelectionDeviceManager(nullptr),
|
||||
mRegistry(nullptr),
|
||||
mGbmDevice(nullptr),
|
||||
diff -up firefox-69.0/widget/gtk/nsWaylandDisplay.h.mozilla-1580152 firefox-69.0/widget/gtk/nsWaylandDisplay.h
|
||||
--- firefox-69.0/widget/gtk/nsWaylandDisplay.h.mozilla-1580152 2019-09-16 11:11:30.081299217 +0200
|
||||
+++ firefox-69.0/widget/gtk/nsWaylandDisplay.h 2019-09-16 11:11:30.089299191 +0200
|
||||
@@ -41,6 +41,11 @@ class nsWaylandDisplay {
|
||||
virtual ~nsWaylandDisplay();
|
||||
|
||||
bool DispatchEventQueue();
|
||||
+
|
||||
+ void SyncBegin();
|
||||
+ void SyncEnd();
|
||||
+ void WaitForSyncEnd();
|
||||
+
|
||||
bool Matches(wl_display* aDisplay);
|
||||
|
||||
MessageLoop* GetDispatcherThreadLoop() { return mDispatcherThreadLoop; }
|
||||
@@ -90,6 +95,7 @@ class nsWaylandDisplay {
|
||||
wl_subcompositor* mSubcompositor;
|
||||
wl_seat* mSeat;
|
||||
wl_shm* mShm;
|
||||
+ wl_callback* mSyncCallback;
|
||||
gtk_primary_selection_device_manager* mPrimarySelectionDeviceManager;
|
||||
wl_registry* mRegistry;
|
||||
zwp_linux_dmabuf_v1* mDmabuf;
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1580152 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1580152 2019-09-16 11:11:30.086299200 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-16 11:57:35.462193492 +0200
|
||||
@@ -32,6 +32,9 @@ extern mozilla::LazyLogModule gWidgetWay
|
||||
# define LOGWAYLAND(args)
|
||||
#endif /* MOZ_LOGGING */
|
||||
|
||||
+// Maximal compositin timeout it miliseconds
|
||||
+#define COMPOSITING_TIMEOUT 200
|
||||
+
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
@@ -198,6 +201,10 @@ available and gfx.wayland_dmabuf_backend
|
||||
#define BUFFER_BPP 4
|
||||
gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8;
|
||||
|
||||
+nsWaylandDisplay* WindowBackBuffer::GetWaylandDisplay() {
|
||||
+ return mWindowSurfaceWayland->GetWaylandDisplay();
|
||||
+}
|
||||
+
|
||||
int WaylandShmPool::CreateTemporaryFile(int aSize) {
|
||||
const char* tmppath = getenv("XDG_RUNTIME_DIR");
|
||||
MOZ_RELEASE_ASSERT(tmppath, "Missing XDG_RUNTIME_DIR env variable.");
|
||||
@@ -342,10 +349,11 @@ void WindowBackBufferShm::Clear() {
|
||||
memset(mShmPool.GetImageData(), 0, mHeight * mWidth * BUFFER_BPP);
|
||||
}
|
||||
|
||||
-WindowBackBufferShm::WindowBackBufferShm(nsWaylandDisplay* aWaylandDisplay,
|
||||
- int aWidth, int aHeight)
|
||||
- : WindowBackBuffer(aWaylandDisplay),
|
||||
- mShmPool(aWaylandDisplay, aWidth * aHeight * BUFFER_BPP),
|
||||
+WindowBackBufferShm::WindowBackBufferShm(
|
||||
+ WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, int aHeight)
|
||||
+ : WindowBackBuffer(aWindowSurfaceWayland),
|
||||
+ mShmPool(aWindowSurfaceWayland->GetWaylandDisplay(),
|
||||
+ aWidth * aHeight * BUFFER_BPP),
|
||||
mWaylandBuffer(nullptr),
|
||||
mWidth(aWidth),
|
||||
mHeight(aHeight),
|
||||
@@ -387,6 +395,9 @@ void WindowBackBufferShm::Detach(wl_buff
|
||||
aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1));
|
||||
|
||||
mAttached = false;
|
||||
+
|
||||
+ // Commit any potential cached drawings from latest Lock()/Commit() cycle.
|
||||
+ mWindowSurfaceWayland->CommitWaylandBuffer();
|
||||
}
|
||||
|
||||
bool WindowBackBufferShm::SetImageDataFromBuffer(
|
||||
@@ -416,8 +427,8 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
}
|
||||
|
||||
WindowBackBufferDMABuf::WindowBackBufferDMABuf(
|
||||
- nsWaylandDisplay* aWaylandDisplay, int aWidth, int aHeight)
|
||||
- : WindowBackBuffer(aWaylandDisplay) {
|
||||
+ WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, int aHeight)
|
||||
+ : WindowBackBuffer(aWindowSurfaceWayland) {
|
||||
mDMAbufSurface.Create(aWidth, aHeight);
|
||||
LOGWAYLAND(
|
||||
("WindowBackBufferDMABuf::WindowBackBufferDMABuf [%p] Created DMABuf "
|
||||
@@ -475,6 +486,9 @@ bool WindowBackBufferDMABuf::SetImageDat
|
||||
|
||||
void WindowBackBufferDMABuf::Detach(wl_buffer* aBuffer) {
|
||||
mDMAbufSurface.WLBufferDetach();
|
||||
+
|
||||
+ // Commit any potential cached drawings from latest Lock()/Commit() cycle.
|
||||
+ mWindowSurfaceWayland->CommitWaylandBuffer();
|
||||
}
|
||||
|
||||
void WindowBackBufferDMABuf::Clear() { mDMAbufSurface.Clear(); }
|
||||
@@ -496,10 +510,11 @@ WindowSurfaceWayland::WindowSurfaceWayla
|
||||
mWaylandBuffer(nullptr),
|
||||
mFrameCallback(nullptr),
|
||||
mLastCommittedSurface(nullptr),
|
||||
- mDisplayThreadMessageLoop(MessageLoop::current()),
|
||||
mDelayedCommitHandle(nullptr),
|
||||
+ mLastCommitTime(0),
|
||||
mDrawToWaylandBufferDirectly(true),
|
||||
- mPendingCommit(false),
|
||||
+ mBufferPendingCommit(false),
|
||||
+ mBufferCommitAllowed(false),
|
||||
mWholeWindowBufferDamage(false),
|
||||
mBufferNeedsClear(false),
|
||||
mIsMainThread(NS_IsMainThread()),
|
||||
@@ -508,7 +523,7 @@ WindowSurfaceWayland::WindowSurfaceWayla
|
||||
}
|
||||
|
||||
WindowSurfaceWayland::~WindowSurfaceWayland() {
|
||||
- if (mPendingCommit) {
|
||||
+ if (mBufferPendingCommit) {
|
||||
NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!");
|
||||
}
|
||||
|
||||
@@ -547,7 +562,7 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
if (UseDMABufBackend()) {
|
||||
static bool sDMABufBufferCreated = false;
|
||||
WindowBackBuffer* buffer =
|
||||
- new WindowBackBufferDMABuf(mWaylandDisplay, aWidth, aHeight);
|
||||
+ new WindowBackBufferDMABuf(this, aWidth, aHeight);
|
||||
if (buffer) {
|
||||
sDMABufBufferCreated = true;
|
||||
return buffer;
|
||||
@@ -564,7 +579,7 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
}
|
||||
}
|
||||
|
||||
- return new WindowBackBufferShm(mWaylandDisplay, aWidth, aHeight);
|
||||
+ return new WindowBackBufferShm(this, aWidth, aHeight);
|
||||
}
|
||||
|
||||
WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(
|
||||
@@ -675,6 +690,11 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
(void*)this, (void*)buffer));
|
||||
|
||||
if (!buffer) {
|
||||
+ if (mLastCommitTime && (g_get_monotonic_time() / 1000) - mLastCommitTime >
|
||||
+ COMPOSITING_TIMEOUT) {
|
||||
+ NS_WARNING(
|
||||
+ "Slow response from Wayland compositor, visual glitches ahead.");
|
||||
+ }
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -724,10 +744,9 @@ static bool IsPopupFullScreenUpdate(Layo
|
||||
// box is equal to window borders.
|
||||
if (aRegion.GetNumRects() > 2) return false;
|
||||
|
||||
- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
|
||||
-
|
||||
- return (screenRect.width == lockSize.width &&
|
||||
+ IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
|
||||
+ return (lockSize.x == 0 && lockSize.y == 0 &&
|
||||
+ screenRect.width == lockSize.width &&
|
||||
screenRect.height == lockSize.height);
|
||||
}
|
||||
|
||||
@@ -738,8 +757,7 @@ static bool IsPopupFullScreenUpdate(Layo
|
||||
to clip/buffer the drawing and we can return wl_buffer directly
|
||||
for drawing.
|
||||
- mWaylandBuffer is available - that's an ideal situation.
|
||||
- - mWaylandBuffer is locked by compositor - flip buffers and draw.
|
||||
- - if we can't flip buffers - go B)
|
||||
+ - mWaylandBuffer is locked by compositor - go B)
|
||||
|
||||
B) Lock() is requested for part(s) of screen. We need to provide temporary
|
||||
surface to draw into and copy result (clipped) to target wl_surface.
|
||||
@@ -747,14 +765,17 @@ static bool IsPopupFullScreenUpdate(Layo
|
||||
already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock(
|
||||
const LayoutDeviceIntRegion& aRegion) {
|
||||
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
-
|
||||
- // Disable all commits from frame callback handler and delayed comit handler
|
||||
- // as we're updated by gecko compositor.
|
||||
- mPendingCommit = false;
|
||||
+
|
||||
+ // Wait until all pending events are processed. There may be queued
|
||||
+ // wl_buffer release event which releases our wl_buffer for further rendering.
|
||||
+ mWaylandDisplay->WaitForSyncEnd();
|
||||
+
|
||||
+ // Disable all commits (from potential frame callback/delayed handlers)
|
||||
+ // until next WindowSurfaceWayland::Commit() call.
|
||||
+ mBufferCommitAllowed = false;
|
||||
|
||||
LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
|
||||
- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
|
||||
+ gfx::IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
|
||||
|
||||
// Are we asked for entire nsWindow to draw?
|
||||
bool isTransparentPopup =
|
||||
@@ -775,10 +796,10 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
}
|
||||
|
||||
LOGWAYLAND(
|
||||
- ("WindowSurfaceWayland::Lock [%p] lockSize [%d x %d] windowSize [%d x "
|
||||
- "%d]\n",
|
||||
- (void*)this, lockSize.width, lockSize.height, lockedScreenRect.width,
|
||||
- lockedScreenRect.height));
|
||||
+ ("WindowSurfaceWayland::Lock [%p] [%d,%d] -> [%d x %d] rects %d "
|
||||
+ "windowSize [%d x %d]\n",
|
||||
+ (void*)this, lockSize.x, lockSize.y, lockSize.width, lockSize.height,
|
||||
+ aRegion.GetNumRects(), lockedScreenRect.width, lockedScreenRect.height));
|
||||
LOGWAYLAND((" nsWindow = %p\n", mWindow));
|
||||
LOGWAYLAND((" isPopup = %d\n", mWindow->IsWaylandPopup()));
|
||||
LOGWAYLAND((" isTransparentPopup = %d\n", isTransparentPopup));
|
||||
@@ -789,7 +810,7 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
LOGWAYLAND((" mBufferNeedsClear = %d\n", mBufferNeedsClear));
|
||||
LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
|
||||
-#if DEBUG
|
||||
+#if MOZ_LOGGING
|
||||
if (!(mBufferScreenRect == lockedScreenRect)) {
|
||||
LOGWAYLAND((" screen size changed\n"));
|
||||
}
|
||||
@@ -836,7 +857,7 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
mDrawToWaylandBufferDirectly = false;
|
||||
|
||||
LOGWAYLAND((" Indirect drawing.\n"));
|
||||
- return LockImageSurface(lockSize);
|
||||
+ return LockImageSurface(gfx::IntSize(lockSize.XMost(), lockSize.YMost()));
|
||||
}
|
||||
|
||||
void WindowImageSurface::Draw(gfx::SourceSurface* aSurface,
|
||||
@@ -875,34 +896,42 @@ WindowImageSurface::WindowImageSurface(
|
||||
mImageSurface->Format());
|
||||
}
|
||||
|
||||
+void WindowSurfaceWayland::CacheImageSurface(
|
||||
+ const LayoutDeviceIntRegion& aRegion) {
|
||||
+#ifdef MOZ_LOGGING
|
||||
+ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
+ LOGWAYLAND(("WindowSurfaceWayland::CacheImageSurface [%p]\n", (void*)this));
|
||||
+ LOGWAYLAND((" rects num %d\n", aRegion.GetNumRects()));
|
||||
+ LOGWAYLAND((" bounds [ %d, %d] -> [%d x %d]\n", bounds.x, bounds.y,
|
||||
+ bounds.width, bounds.height));
|
||||
+#endif
|
||||
+
|
||||
+ mDelayedImageCommits.AppendElement(
|
||||
+ WindowImageSurface(mImageSurface, aRegion));
|
||||
+ // mImageSurface is owned by mDelayedImageCommits
|
||||
+ mImageSurface = nullptr;
|
||||
+
|
||||
+ LOGWAYLAND(
|
||||
+ (" There's %d cached images\n", int(mDelayedImageCommits.Length())));
|
||||
+}
|
||||
+
|
||||
void WindowSurfaceWayland::DrawDelayedImageCommits(
|
||||
gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) {
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::DrawDelayedImageCommits [%p]\n", (void*)this));
|
||||
+
|
||||
for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) {
|
||||
mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage);
|
||||
}
|
||||
mDelayedImageCommits.Clear();
|
||||
}
|
||||
|
||||
-bool WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer(
|
||||
- const LayoutDeviceIntRegion& aRegion,
|
||||
- LayoutDeviceIntRegion& aWaylandBufferDamage) {
|
||||
- MOZ_ASSERT(!mDrawToWaylandBufferDirectly);
|
||||
-
|
||||
-#ifdef DEBUG
|
||||
- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
- gfx::Rect rect(bounds);
|
||||
- MOZ_ASSERT(!rect.IsEmpty(), "Empty drawing?");
|
||||
-#endif
|
||||
-
|
||||
- LOGWAYLAND(
|
||||
- ("WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer [%p] "
|
||||
- "screenSize [%d x %d]\n",
|
||||
- (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
+bool WindowSurfaceWayland::CommitImageCacheToWaylandBuffer() {
|
||||
+ if (!mDelayedImageCommits.Length()) {
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
- mDelayedImageCommits.AppendElement(
|
||||
- WindowImageSurface(mImageSurface, aRegion));
|
||||
- // mImageSurface is owned by mDelayedImageCommits
|
||||
- mImageSurface = nullptr;
|
||||
+ MOZ_ASSERT(!mDrawToWaylandBufferDirectly);
|
||||
|
||||
RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
/* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
@@ -911,10 +940,10 @@ bool WindowSurfaceWayland::CommitImageSu
|
||||
}
|
||||
|
||||
LOGWAYLAND((" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
|
||||
- long(mDelayedImageCommits.Length() + 1)));
|
||||
+ long(mDelayedImageCommits.Length())));
|
||||
|
||||
// Draw any delayed image commits first
|
||||
- DrawDelayedImageCommits(dt, aWaylandBufferDamage);
|
||||
+ DrawDelayedImageCommits(dt, mWaylandBufferDamage);
|
||||
UnlockWaylandBuffer();
|
||||
|
||||
return true;
|
||||
@@ -932,7 +961,8 @@ static void WaylandBufferDelayCommitHand
|
||||
}
|
||||
|
||||
void WindowSurfaceWayland::CommitWaylandBuffer() {
|
||||
- MOZ_ASSERT(mPendingCommit, "Committing empty surface!");
|
||||
+ MOZ_ASSERT(!mWaylandBuffer->IsAttached(),
|
||||
+ "We can't draw to attached wayland buffer!");
|
||||
|
||||
LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this));
|
||||
LOGWAYLAND(
|
||||
@@ -941,6 +971,21 @@ void WindowSurfaceWayland::CommitWayland
|
||||
LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle));
|
||||
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
|
||||
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
|
||||
+ LOGWAYLAND((" mBufferPendingCommit = %d\n", mBufferPendingCommit));
|
||||
+ LOGWAYLAND((" mBufferCommitAllowed = %d\n", mBufferCommitAllowed));
|
||||
+
|
||||
+ if (!mBufferCommitAllowed) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (CommitImageCacheToWaylandBuffer()) {
|
||||
+ mBufferPendingCommit = true;
|
||||
+ }
|
||||
+
|
||||
+ // There's nothing to do here
|
||||
+ if (!mBufferPendingCommit) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
wl_surface* waylandSurface = mWindow->GetWaylandSurface();
|
||||
if (!waylandSurface) {
|
||||
@@ -986,6 +1031,7 @@ void WindowSurfaceWayland::CommitWayland
|
||||
}
|
||||
|
||||
if (mWholeWindowBufferDamage) {
|
||||
+ LOGWAYLAND((" send whole screen damage\n"));
|
||||
wl_surface_damage(waylandSurface, 0, 0, mBufferScreenRect.width,
|
||||
mBufferScreenRect.height);
|
||||
mWholeWindowBufferDamage = false;
|
||||
@@ -994,6 +1040,8 @@ void WindowSurfaceWayland::CommitWayland
|
||||
for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done();
|
||||
iter.Next()) {
|
||||
mozilla::LayoutDeviceIntRect r = iter.Get();
|
||||
+ LOGWAYLAND((" wl_surface_damage_buffer [%d, %d] -> [%d, %d]\n", r.x,
|
||||
+ r.y, r.width, r.height));
|
||||
wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
}
|
||||
@@ -1012,24 +1060,31 @@ void WindowSurfaceWayland::CommitWayland
|
||||
|
||||
mWaylandBuffer->Attach(waylandSurface);
|
||||
mLastCommittedSurface = waylandSurface;
|
||||
+ mLastCommitTime = g_get_monotonic_time() / 1000;
|
||||
+
|
||||
+ // Ask wl_display to start events synchronization. We're going wait
|
||||
+ // until all events are processed before next WindowSurfaceWayland::Lock()
|
||||
+ // as we need freed wl_buffer there.
|
||||
+ mWaylandDisplay->SyncBegin();
|
||||
|
||||
// There's no pending commit, all changes are sent to compositor.
|
||||
- mPendingCommit = false;
|
||||
+ mBufferPendingCommit = false;
|
||||
}
|
||||
|
||||
void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) {
|
||||
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
|
||||
-#ifdef DEBUG
|
||||
- {
|
||||
- gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
|
||||
- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
|
||||
+ // Flush all waiting events explicitly as we need
|
||||
+ // mWaylandDisplay->FlushEventQueue();
|
||||
|
||||
+#ifdef MOZ_LOGGING
|
||||
+ {
|
||||
+ gfx::IntRect lockSize = aInvalidRegion.GetBounds().ToUnknownRect();
|
||||
LOGWAYLAND(
|
||||
- ("WindowSurfaceWayland::Commit [%p] lockSize [%d x %d] screenSize [%d "
|
||||
- "x %d]\n",
|
||||
- (void*)this, lockSize.width, lockSize.height, mBufferScreenRect.width,
|
||||
- mBufferScreenRect.height));
|
||||
+ ("WindowSurfaceWayland::Commit [%p] damage size [%d, %d] -> [%d x %d]"
|
||||
+ "screenSize [%d x %d]\n",
|
||||
+ (void*)this, lockSize.x, lockSize.y, lockSize.width, lockSize.height,
|
||||
+ mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n",
|
||||
mDrawToWaylandBufferDirectly));
|
||||
LOGWAYLAND(
|
||||
@@ -1044,21 +1099,15 @@ void WindowSurfaceWayland::Commit(const
|
||||
mWaylandBufferDamage.OrWith(aInvalidRegion);
|
||||
}
|
||||
UnlockWaylandBuffer();
|
||||
- mPendingCommit = true;
|
||||
+ mBufferPendingCommit = true;
|
||||
} 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;
|
||||
- mPendingCommit = true;
|
||||
- }
|
||||
+ CacheImageSurface(aInvalidRegion);
|
||||
}
|
||||
|
||||
- if (mPendingCommit) {
|
||||
- CommitWaylandBuffer();
|
||||
- }
|
||||
+ mBufferCommitAllowed = true;
|
||||
+ CommitWaylandBuffer();
|
||||
}
|
||||
|
||||
void WindowSurfaceWayland::FrameCallbackHandler() {
|
||||
@@ -1074,9 +1123,7 @@ void WindowSurfaceWayland::FrameCallback
|
||||
wl_callback_destroy(mFrameCallback);
|
||||
mFrameCallback = nullptr;
|
||||
|
||||
- if (mPendingCommit) {
|
||||
- CommitWaylandBuffer();
|
||||
- }
|
||||
+ CommitWaylandBuffer();
|
||||
}
|
||||
|
||||
void WindowSurfaceWayland::DelayedCommitHandler() {
|
||||
@@ -1089,9 +1136,7 @@ void WindowSurfaceWayland::DelayedCommit
|
||||
free(mDelayedCommitHandle);
|
||||
mDelayedCommitHandle = nullptr;
|
||||
|
||||
- if (mPendingCommit) {
|
||||
- CommitWaylandBuffer();
|
||||
- }
|
||||
+ CommitWaylandBuffer();
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1580152 firefox-69.0/widget/gtk/WindowSurfaceWayland.h
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1580152 2019-09-16 11:11:30.080299221 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.h 2019-09-16 11:11:30.090299187 +0200
|
||||
@@ -17,6 +17,8 @@
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
+class WindowSurfaceWayland;
|
||||
+
|
||||
// Allocates and owns shared memory for Wayland drawing surface
|
||||
class WaylandShmPool {
|
||||
public:
|
||||
@@ -69,20 +71,22 @@ class WindowBackBuffer {
|
||||
|
||||
static gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; }
|
||||
|
||||
- nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; };
|
||||
+ nsWaylandDisplay* GetWaylandDisplay();
|
||||
|
||||
- WindowBackBuffer(nsWaylandDisplay* aWaylandDisplay)
|
||||
- : mWaylandDisplay(aWaylandDisplay){};
|
||||
+ WindowBackBuffer(WindowSurfaceWayland* aWindowSurfaceWayland)
|
||||
+ : mWindowSurfaceWayland(aWindowSurfaceWayland){};
|
||||
virtual ~WindowBackBuffer(){};
|
||||
|
||||
+ protected:
|
||||
+ WindowSurfaceWayland* mWindowSurfaceWayland;
|
||||
+
|
||||
private:
|
||||
static gfx::SurfaceFormat mFormat;
|
||||
- nsWaylandDisplay* mWaylandDisplay;
|
||||
};
|
||||
|
||||
class WindowBackBufferShm : public WindowBackBuffer {
|
||||
public:
|
||||
- WindowBackBufferShm(nsWaylandDisplay* aWaylandDisplay, int aWidth,
|
||||
+ WindowBackBufferShm(WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth,
|
||||
int aHeight);
|
||||
~WindowBackBufferShm();
|
||||
|
||||
@@ -121,8 +125,8 @@ class WindowBackBufferShm : public Windo
|
||||
|
||||
class WindowBackBufferDMABuf : public WindowBackBuffer {
|
||||
public:
|
||||
- WindowBackBufferDMABuf(nsWaylandDisplay* aWaylandDisplay, int aWidth,
|
||||
- int aHeight);
|
||||
+ WindowBackBufferDMABuf(WindowSurfaceWayland* aWindowSurfaceWayland,
|
||||
+ int aWidth, int aHeight);
|
||||
~WindowBackBufferDMABuf();
|
||||
|
||||
bool IsAttached();
|
||||
@@ -175,6 +179,9 @@ class WindowSurfaceWayland : public Wind
|
||||
void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
|
||||
void FrameCallbackHandler();
|
||||
void DelayedCommitHandler();
|
||||
+ void CommitWaylandBuffer();
|
||||
+
|
||||
+ nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; };
|
||||
|
||||
private:
|
||||
WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight);
|
||||
@@ -185,10 +192,9 @@ class WindowSurfaceWayland : public Wind
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> LockImageSurface(
|
||||
const gfx::IntSize& aLockSize);
|
||||
- bool CommitImageSurfaceToWaylandBuffer(
|
||||
- const LayoutDeviceIntRegion& aRegion,
|
||||
- LayoutDeviceIntRegion& aWaylandBufferDamage);
|
||||
- void CommitWaylandBuffer();
|
||||
+
|
||||
+ void CacheImageSurface(const LayoutDeviceIntRegion& aRegion);
|
||||
+ bool CommitImageCacheToWaylandBuffer();
|
||||
|
||||
void DrawDelayedImageCommits(gfx::DrawTarget* aDrawTarget,
|
||||
LayoutDeviceIntRegion& aWaylandBufferDamage);
|
||||
@@ -205,12 +211,13 @@ class WindowSurfaceWayland : public Wind
|
||||
WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM];
|
||||
wl_callback* mFrameCallback;
|
||||
wl_surface* mLastCommittedSurface;
|
||||
- MessageLoop* mDisplayThreadMessageLoop;
|
||||
WindowSurfaceWayland** mDelayedCommitHandle;
|
||||
RefPtr<gfxImageSurface> mImageSurface;
|
||||
AutoTArray<WindowImageSurface, 30> mDelayedImageCommits;
|
||||
+ int64_t mLastCommitTime;
|
||||
bool mDrawToWaylandBufferDirectly;
|
||||
- bool mPendingCommit;
|
||||
+ bool mBufferPendingCommit;
|
||||
+ bool mBufferCommitAllowed;
|
||||
bool mWholeWindowBufferDamage;
|
||||
bool mBufferNeedsClear;
|
||||
bool mIsMainThread;
|
@ -1,574 +0,0 @@
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1581748 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1581748 2019-09-17 13:19:47.190908284 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-17 13:19:47.196908262 +0200
|
||||
@@ -32,7 +32,7 @@ extern mozilla::LazyLogModule gWidgetWay
|
||||
# define LOGWAYLAND(args)
|
||||
#endif /* MOZ_LOGGING */
|
||||
|
||||
-// Maximal compositin timeout it miliseconds
|
||||
+// Maximal compositing timeout it miliseconds
|
||||
#define COMPOSITING_TIMEOUT 200
|
||||
|
||||
namespace mozilla {
|
||||
@@ -513,13 +513,15 @@ WindowSurfaceWayland::WindowSurfaceWayla
|
||||
mDelayedCommitHandle(nullptr),
|
||||
mLastCommitTime(0),
|
||||
mDrawToWaylandBufferDirectly(true),
|
||||
+ mCanSwitchWaylandBuffer(true),
|
||||
mBufferPendingCommit(false),
|
||||
mBufferCommitAllowed(false),
|
||||
- mWholeWindowBufferDamage(false),
|
||||
mBufferNeedsClear(false),
|
||||
mIsMainThread(NS_IsMainThread()),
|
||||
mNeedScaleFactorUpdate(true) {
|
||||
for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
|
||||
+ mRenderingCacheMode = CACHE_ALL;
|
||||
+
|
||||
}
|
||||
|
||||
WindowSurfaceWayland::~WindowSurfaceWayland() {
|
||||
@@ -591,8 +593,6 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
|
||||
// There's no buffer created yet, create a new one.
|
||||
if (!mWaylandBuffer) {
|
||||
- MOZ_ASSERT(aCanSwitchBuffer && mWholeWindowBufferDamage,
|
||||
- "Created new buffer for partial drawing!");
|
||||
LOGWAYLAND((" Created new buffer [%d x %d]\n", mBufferScreenRect.width,
|
||||
mBufferScreenRect.height));
|
||||
|
||||
@@ -682,9 +682,8 @@ WindowBackBuffer* WindowSurfaceWayland::
|
||||
return mWaylandBuffer;
|
||||
}
|
||||
|
||||
-already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer(
|
||||
- bool aCanSwitchBuffer) {
|
||||
- WindowBackBuffer* buffer = GetWaylandBufferToDraw(aCanSwitchBuffer);
|
||||
+already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer() {
|
||||
+ WindowBackBuffer* buffer = GetWaylandBufferToDraw(mCanSwitchWaylandBuffer);
|
||||
|
||||
LOGWAYLAND(("WindowSurfaceWayland::LockWaylandBuffer [%p] Got buffer %p\n",
|
||||
(void*)this, (void*)buffer));
|
||||
@@ -698,7 +697,9 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- if (mBufferNeedsClear && mWholeWindowBufferDamage) {
|
||||
+ mCanSwitchWaylandBuffer = false;
|
||||
+
|
||||
+ if (mBufferNeedsClear) {
|
||||
buffer->Clear();
|
||||
mBufferNeedsClear = false;
|
||||
}
|
||||
@@ -728,40 +729,30 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
WindowBackBuffer::GetSurfaceFormat());
|
||||
}
|
||||
|
||||
-static bool IsWindowFullScreenUpdate(LayoutDeviceIntRect& screenRect,
|
||||
- const LayoutDeviceIntRegion& aRegion) {
|
||||
- if (aRegion.GetNumRects() > 1) return false;
|
||||
-
|
||||
- IntRect rect = aRegion.RectIter().Get().ToUnknownRect();
|
||||
- return (rect.x == 0 && rect.y == 0 && screenRect.width == rect.width &&
|
||||
- screenRect.height == rect.height);
|
||||
+static bool IsWindowFullScreenUpdate(
|
||||
+ LayoutDeviceIntRect& aScreenRect,
|
||||
+ const LayoutDeviceIntRegion& aUpdatedRegion) {
|
||||
+ if (aUpdatedRegion.GetNumRects() > 1) return false;
|
||||
+
|
||||
+ IntRect rect = aUpdatedRegion.RectIter().Get().ToUnknownRect();
|
||||
+ return (rect.x == 0 && rect.y == 0 && aScreenRect.width == rect.width &&
|
||||
+ aScreenRect.height == rect.height);
|
||||
}
|
||||
|
||||
-static bool IsPopupFullScreenUpdate(LayoutDeviceIntRect& screenRect,
|
||||
- const LayoutDeviceIntRegion& aRegion) {
|
||||
+static bool IsPopupFullScreenUpdate(
|
||||
+ LayoutDeviceIntRect& aScreenRect,
|
||||
+ const LayoutDeviceIntRegion& aUpdatedRegion) {
|
||||
// We know that popups can be drawn from two parts; a panel and an arrow.
|
||||
// Assume we redraw whole popups when we have two rects and bounding
|
||||
// box is equal to window borders.
|
||||
- if (aRegion.GetNumRects() > 2) return false;
|
||||
+ if (aUpdatedRegion.GetNumRects() > 2) return false;
|
||||
|
||||
- IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
|
||||
+ gfx::IntRect lockSize = aUpdatedRegion.GetBounds().ToUnknownRect();
|
||||
return (lockSize.x == 0 && lockSize.y == 0 &&
|
||||
- screenRect.width == lockSize.width &&
|
||||
- screenRect.height == lockSize.height);
|
||||
+ aScreenRect.width == lockSize.width &&
|
||||
+ aScreenRect.height == lockSize.height);
|
||||
}
|
||||
|
||||
-/*
|
||||
- There are some situations which can happen here:
|
||||
-
|
||||
- A) Lock() is called to whole surface. In that case we don't need
|
||||
- to clip/buffer the drawing and we can return wl_buffer directly
|
||||
- for drawing.
|
||||
- - mWaylandBuffer is available - that's an ideal situation.
|
||||
- - mWaylandBuffer is locked by compositor - go B)
|
||||
-
|
||||
- B) Lock() is requested for part(s) of screen. We need to provide temporary
|
||||
- surface to draw into and copy result (clipped) to target wl_surface.
|
||||
- */
|
||||
already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock(
|
||||
const LayoutDeviceIntRegion& aRegion) {
|
||||
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
@@ -777,22 +768,31 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
|
||||
gfx::IntRect lockSize = aRegion.GetBounds().ToUnknownRect();
|
||||
|
||||
- // Are we asked for entire nsWindow to draw?
|
||||
bool isTransparentPopup =
|
||||
mWindow->IsWaylandPopup() &&
|
||||
(eTransparencyTransparent == mWindow->GetTransparencyMode());
|
||||
|
||||
- // We have request to lock whole buffer/window.
|
||||
- mWholeWindowBufferDamage =
|
||||
- isTransparentPopup ? IsPopupFullScreenUpdate(lockedScreenRect, aRegion)
|
||||
- : IsWindowFullScreenUpdate(lockedScreenRect, aRegion);
|
||||
-
|
||||
- // Clear buffer when we (re)draw new transparent popup window,
|
||||
- // otherwise leave it as-is, mBufferNeedsClear can be set from previous
|
||||
- // (already pending) commits which are cached now.
|
||||
- if (mWholeWindowBufferDamage) {
|
||||
+ bool windowRedraw = isTransparentPopup
|
||||
+ ? IsPopupFullScreenUpdate(lockedScreenRect, aRegion)
|
||||
+ : IsWindowFullScreenUpdate(lockedScreenRect, aRegion);
|
||||
+ if (windowRedraw) {
|
||||
+ // Clear buffer when we (re)draw new transparent popup window,
|
||||
+ // otherwise leave it as-is, mBufferNeedsClear can be set from previous
|
||||
+ // (already pending) commits which are cached now.
|
||||
mBufferNeedsClear =
|
||||
mWindow->WaylandSurfaceNeedsClear() || isTransparentPopup;
|
||||
+
|
||||
+ // Store info that we can switch WaylandBuffer when we flush
|
||||
+ // mImageSurface / mDelayedImageCommits. Don't clear it - it's cleared
|
||||
+ // at LockWaylandBuffer() when we actualy switch the buffer.
|
||||
+ mCanSwitchWaylandBuffer = windowRedraw;
|
||||
+
|
||||
+ // We do full buffer repaint so clear our cached drawings.
|
||||
+ mDelayedImageCommits.Clear();
|
||||
+ mWaylandBufferDamage.SetEmpty();
|
||||
+
|
||||
+ // Also do scale factor update for whole window updates just to be sure.
|
||||
+ mNeedScaleFactorUpdate = true;
|
||||
}
|
||||
|
||||
LOGWAYLAND(
|
||||
@@ -808,7 +808,7 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
LOGWAYLAND((" IsWindowFullScreenUpdate = %d\n",
|
||||
IsWindowFullScreenUpdate(lockedScreenRect, aRegion)));
|
||||
LOGWAYLAND((" mBufferNeedsClear = %d\n", mBufferNeedsClear));
|
||||
- LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
+ LOGWAYLAND((" windowRedraw = %d\n", windowRedraw));
|
||||
|
||||
#if MOZ_LOGGING
|
||||
if (!(mBufferScreenRect == lockedScreenRect)) {
|
||||
@@ -822,8 +822,9 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
// We can't commit them any more as they're for former window size, so
|
||||
// scratch them.
|
||||
mDelayedImageCommits.Clear();
|
||||
+ mWaylandBufferDamage.SetEmpty();
|
||||
|
||||
- if (!mWholeWindowBufferDamage) {
|
||||
+ if (!windowRedraw) {
|
||||
NS_WARNING("Partial screen update when window is resized!");
|
||||
// This should not happen. Screen size changed but we got only
|
||||
// partal screen update instead of whole screen. Discard this painting
|
||||
@@ -833,52 +834,56 @@ already_AddRefed<gfx::DrawTarget> Window
|
||||
mBufferScreenRect = lockedScreenRect;
|
||||
}
|
||||
|
||||
- if (mWholeWindowBufferDamage) {
|
||||
- // We can lock/commit entire buffer direcly.
|
||||
- mDrawToWaylandBufferDirectly = true;
|
||||
-
|
||||
- // If there's any pending image commit scratch them as we're going
|
||||
- // to redraw the whole sceen anyway.
|
||||
- mDelayedImageCommits.Clear();
|
||||
+ mDrawToWaylandBufferDirectly =
|
||||
+ (windowRedraw || mRenderingCacheMode != CACHE_ALL);
|
||||
|
||||
- RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
- /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
+ if (mDrawToWaylandBufferDirectly) {
|
||||
+ LOGWAYLAND((" Direct drawing\n"));
|
||||
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer();
|
||||
if (dt) {
|
||||
+ if (!windowRedraw) {
|
||||
+ DrawDelayedImageCommits(dt, mWaylandBufferDamage);
|
||||
+ }
|
||||
return dt.forget();
|
||||
}
|
||||
}
|
||||
|
||||
- // We do indirect drawing due to:
|
||||
- //
|
||||
- // 1) We don't have any front buffer available. Try indirect drawing
|
||||
- // to mImageSurface which is mirrored to front buffer at commit.
|
||||
- // 2) Only part of the screen is locked. We can't lock entire screen for
|
||||
- // such drawing as it produces visible artifacts.
|
||||
+ // Any caching is disabled and we don't have any back buffer available.
|
||||
+ if (mRenderingCacheMode == CACHE_NONE) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ // We do indirect drawing because there isn't any front buffer available.
|
||||
+ // Do indirect drawing to mImageSurface which is commited to wayland
|
||||
+ // wl_buffer by DrawDelayedImageCommits() later.
|
||||
mDrawToWaylandBufferDirectly = false;
|
||||
|
||||
LOGWAYLAND((" Indirect drawing.\n"));
|
||||
return LockImageSurface(gfx::IntSize(lockSize.XMost(), lockSize.YMost()));
|
||||
}
|
||||
|
||||
+bool WindowImageSurface::OverlapsSurface(
|
||||
+ class WindowImageSurface& aBottomSurface) {
|
||||
+ return mUpdateRegion.Contains(aBottomSurface.mUpdateRegion);
|
||||
+}
|
||||
+
|
||||
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());
|
||||
- }
|
||||
-
|
||||
+#ifdef MOZ_LOGGING
|
||||
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||
- gfx::Rect rect(bounds);
|
||||
- aDest->DrawSurface(aSurface, rect, rect);
|
||||
+ LOGWAYLAND(("WindowImageSurface::Draw\n"));
|
||||
+ LOGWAYLAND((" rects num %d\n", aRegion.GetNumRects()));
|
||||
+ LOGWAYLAND((" bounds [ %d, %d] -> [%d x %d]\n", bounds.x, bounds.y,
|
||||
+ bounds.width, bounds.height));
|
||||
+#endif
|
||||
|
||||
- if (numRects != 1) {
|
||||
- aDest->PopClip();
|
||||
+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
+ mozilla::LayoutDeviceIntRect r = iter.Get();
|
||||
+ gfx::Rect rect(r.ToUnknownRect());
|
||||
+ LOGWAYLAND((" draw rect [%f,%f] -> [%f x %f]\n", rect.x, rect.y,
|
||||
+ rect.width, rect.height));
|
||||
+ aDest->DrawSurface(aSurface, rect, rect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,6 +901,18 @@ WindowImageSurface::WindowImageSurface(
|
||||
mImageSurface->Format());
|
||||
}
|
||||
|
||||
+void WindowSurfaceWayland::DrawDelayedImageCommits(
|
||||
+ gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) {
|
||||
+ LOGWAYLAND(
|
||||
+ ("WindowSurfaceWayland::DrawDelayedImageCommits [%p]\n", (void*)this));
|
||||
+ MOZ_ASSERT(mDelayedImageCommits.Length() > 0, "Nothing to draw?");
|
||||
+
|
||||
+ for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) {
|
||||
+ mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage);
|
||||
+ }
|
||||
+ mDelayedImageCommits.Clear();
|
||||
+}
|
||||
+
|
||||
void WindowSurfaceWayland::CacheImageSurface(
|
||||
const LayoutDeviceIntRegion& aRegion) {
|
||||
#ifdef MOZ_LOGGING
|
||||
@@ -906,8 +923,26 @@ void WindowSurfaceWayland::CacheImageSur
|
||||
bounds.width, bounds.height));
|
||||
#endif
|
||||
|
||||
- mDelayedImageCommits.AppendElement(
|
||||
- WindowImageSurface(mImageSurface, aRegion));
|
||||
+ WindowImageSurface surf = WindowImageSurface(mImageSurface, aRegion);
|
||||
+
|
||||
+ if (mDelayedImageCommits.Length()) {
|
||||
+ int lastSurf = mDelayedImageCommits.Length() - 1;
|
||||
+ if (surf.OverlapsSurface(mDelayedImageCommits[lastSurf])) {
|
||||
+#ifdef MOZ_LOGGING
|
||||
+ {
|
||||
+ gfx::IntRect size = mDelayedImageCommits[lastSurf]
|
||||
+ .GetUpdateRegion()
|
||||
+ ->GetBounds()
|
||||
+ .ToUnknownRect();
|
||||
+ LOGWAYLAND((" removing [ %d, %d] -> [%d x %d]\n", size.x, size.y,
|
||||
+ size.width, size.height));
|
||||
+ }
|
||||
+#endif
|
||||
+ mDelayedImageCommits.RemoveElementAt(lastSurf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mDelayedImageCommits.AppendElement(surf);
|
||||
// mImageSurface is owned by mDelayedImageCommits
|
||||
mImageSurface = nullptr;
|
||||
|
||||
@@ -915,17 +950,6 @@ void WindowSurfaceWayland::CacheImageSur
|
||||
(" There's %d cached images\n", int(mDelayedImageCommits.Length())));
|
||||
}
|
||||
|
||||
-void WindowSurfaceWayland::DrawDelayedImageCommits(
|
||||
- gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) {
|
||||
- LOGWAYLAND(
|
||||
- ("WindowSurfaceWayland::DrawDelayedImageCommits [%p]\n", (void*)this));
|
||||
-
|
||||
- for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) {
|
||||
- mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage);
|
||||
- }
|
||||
- mDelayedImageCommits.Clear();
|
||||
-}
|
||||
-
|
||||
bool WindowSurfaceWayland::CommitImageCacheToWaylandBuffer() {
|
||||
if (!mDelayedImageCommits.Length()) {
|
||||
return false;
|
||||
@@ -933,8 +957,7 @@ bool WindowSurfaceWayland::CommitImageCa
|
||||
|
||||
MOZ_ASSERT(!mDrawToWaylandBufferDirectly);
|
||||
|
||||
- RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
|
||||
- /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
|
||||
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer();
|
||||
if (!dt) {
|
||||
return false;
|
||||
}
|
||||
@@ -942,7 +965,6 @@ bool WindowSurfaceWayland::CommitImageCa
|
||||
LOGWAYLAND((" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
|
||||
long(mDelayedImageCommits.Length())));
|
||||
|
||||
- // Draw any delayed image commits first
|
||||
DrawDelayedImageCommits(dt, mWaylandBufferDamage);
|
||||
UnlockWaylandBuffer();
|
||||
|
||||
@@ -967,7 +989,7 @@ void WindowSurfaceWayland::CommitWayland
|
||||
LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this));
|
||||
LOGWAYLAND(
|
||||
(" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
|
||||
- LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
+ LOGWAYLAND((" mCanSwitchWaylandBuffer = %d\n", mCanSwitchWaylandBuffer));
|
||||
LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle));
|
||||
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
|
||||
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
|
||||
@@ -1030,20 +1052,11 @@ void WindowSurfaceWayland::CommitWayland
|
||||
mLastCommittedSurface = nullptr;
|
||||
}
|
||||
|
||||
- if (mWholeWindowBufferDamage) {
|
||||
- LOGWAYLAND((" send whole screen damage\n"));
|
||||
- wl_surface_damage(waylandSurface, 0, 0, mBufferScreenRect.width,
|
||||
- mBufferScreenRect.height);
|
||||
- mWholeWindowBufferDamage = false;
|
||||
- mNeedScaleFactorUpdate = true;
|
||||
- } else {
|
||||
- for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done();
|
||||
- iter.Next()) {
|
||||
- mozilla::LayoutDeviceIntRect r = iter.Get();
|
||||
- LOGWAYLAND((" wl_surface_damage_buffer [%d, %d] -> [%d, %d]\n", r.x,
|
||||
- r.y, r.width, r.height));
|
||||
- wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
|
||||
- }
|
||||
+ for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); iter.Next()) {
|
||||
+ mozilla::LayoutDeviceIntRect r = iter.Get();
|
||||
+ LOGWAYLAND((" wl_surface_damage_buffer [%d, %d] -> [%d, %d]\n", r.x, r.y,
|
||||
+ r.width, r.height));
|
||||
+ wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
// Clear all back buffer damage as we're committing
|
||||
@@ -1062,9 +1075,9 @@ void WindowSurfaceWayland::CommitWayland
|
||||
mLastCommittedSurface = waylandSurface;
|
||||
mLastCommitTime = g_get_monotonic_time() / 1000;
|
||||
|
||||
- // Ask wl_display to start events synchronization. We're going wait
|
||||
+ // Ask wl_display to start events synchronization. We're going to wait
|
||||
// until all events are processed before next WindowSurfaceWayland::Lock()
|
||||
- // as we need freed wl_buffer there.
|
||||
+ // as we hope for free wl_buffer there.
|
||||
mWaylandDisplay->SyncBegin();
|
||||
|
||||
// There's no pending commit, all changes are sent to compositor.
|
||||
@@ -1074,9 +1087,6 @@ void WindowSurfaceWayland::CommitWayland
|
||||
void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) {
|
||||
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
|
||||
- // Flush all waiting events explicitly as we need
|
||||
- // mWaylandDisplay->FlushEventQueue();
|
||||
-
|
||||
#ifdef MOZ_LOGGING
|
||||
{
|
||||
gfx::IntRect lockSize = aInvalidRegion.GetBounds().ToUnknownRect();
|
||||
@@ -1087,17 +1097,12 @@ void WindowSurfaceWayland::Commit(const
|
||||
mBufferScreenRect.width, mBufferScreenRect.height));
|
||||
LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n",
|
||||
mDrawToWaylandBufferDirectly));
|
||||
- LOGWAYLAND(
|
||||
- (" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mDrawToWaylandBufferDirectly) {
|
||||
MOZ_ASSERT(mWaylandBuffer->IsLocked());
|
||||
- // If we're not at fullscreen damage add drawing area from aInvalidRegion
|
||||
- if (!mWholeWindowBufferDamage) {
|
||||
- mWaylandBufferDamage.OrWith(aInvalidRegion);
|
||||
- }
|
||||
+ mWaylandBufferDamage.OrWith(aInvalidRegion);
|
||||
UnlockWaylandBuffer();
|
||||
mBufferPendingCommit = true;
|
||||
} else {
|
||||
diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1581748 firefox-69.0/widget/gtk/WindowSurfaceWayland.h
|
||||
--- firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1581748 2019-09-17 13:19:47.191908280 +0200
|
||||
+++ firefox-69.0/widget/gtk/WindowSurfaceWayland.h 2019-09-17 13:19:47.197908258 +0200
|
||||
@@ -161,6 +161,10 @@ class WindowImageSurface {
|
||||
WindowImageSurface(gfxImageSurface* aImageSurface,
|
||||
const LayoutDeviceIntRegion& aUpdateRegion);
|
||||
|
||||
+ bool OverlapsSurface(class WindowImageSurface& aBottomSurface);
|
||||
+
|
||||
+ const LayoutDeviceIntRegion* GetUpdateRegion() { return &mUpdateRegion; };
|
||||
+
|
||||
private:
|
||||
RefPtr<gfx::SourceSurface> mSurface;
|
||||
RefPtr<gfxImageSurface> mImageSurface;
|
||||
@@ -174,20 +178,59 @@ class WindowSurfaceWayland : public Wind
|
||||
explicit WindowSurfaceWayland(nsWindow* aWindow);
|
||||
~WindowSurfaceWayland();
|
||||
|
||||
+ // Lock() / Commit() are called by gecko when Firefox
|
||||
+ // wants to display something. Lock() returns a DrawTarget
|
||||
+ // where gecko paints. When gecko is done it calls Commit()
|
||||
+ // and we try to send the DrawTarget (backed by wl_buffer)
|
||||
+ // to wayland compositor.
|
||||
+ //
|
||||
+ // If we fail (wayland compositor is busy,
|
||||
+ // wl_surface is not created yet) we queue the painting
|
||||
+ // and we send it to wayland compositor in FrameCallbackHandler()/
|
||||
+ // DelayedCommitHandler/CommitWaylandBuffer().
|
||||
already_AddRefed<gfx::DrawTarget> Lock(
|
||||
const LayoutDeviceIntRegion& aRegion) override;
|
||||
void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
|
||||
+
|
||||
+ // It's called from wayland compositor when there's the right
|
||||
+ // time to send wl_buffer to display. It's no-op if there's no
|
||||
+ // queued commits.
|
||||
void FrameCallbackHandler();
|
||||
+
|
||||
+ // When a new window is created we may not have a valid wl_surface
|
||||
+ // for drawing (Gtk haven't created it yet). All commits are queued
|
||||
+ // and DelayedCommitHandler() is called by timer when wl_surface is ready
|
||||
+ // for drawing.
|
||||
void DelayedCommitHandler();
|
||||
+
|
||||
+ // Try to commit all queued drawings to Wayland compositor. This is usually
|
||||
+ // called from other routines but can be used to explicitly flush
|
||||
+ // all drawings as we do when wl_buffer is released
|
||||
+ // (see WindowBackBufferShm::Detach() for instance).
|
||||
void CommitWaylandBuffer();
|
||||
|
||||
nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; };
|
||||
|
||||
+ // Image cache mode can be set by widget.wayland_cache_mode
|
||||
+ typedef enum {
|
||||
+ // Cache and clip all drawings, default. It's slowest
|
||||
+ // but also without any rendered artifacts.
|
||||
+ CACHE_ALL = 0,
|
||||
+ // Cache drawing only when back buffer is missing. May produce
|
||||
+ // some rendering artifacts and flickering when partial screen update
|
||||
+ // is rendered.
|
||||
+ CACHE_MISSING = 1,
|
||||
+ // Don't cache anything, draw only when back buffer is available.
|
||||
+ // Suitable for fullscreen content only like fullscreen video playback and
|
||||
+ // may work well with dmabuf backend.
|
||||
+ CACHE_NONE = 2
|
||||
+ } RenderingCacheMode;
|
||||
+
|
||||
private:
|
||||
WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight);
|
||||
WindowBackBuffer* GetWaylandBufferToDraw(bool aCanSwitchBuffer);
|
||||
|
||||
- already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(bool aCanSwitchBuffer);
|
||||
+ already_AddRefed<gfx::DrawTarget> LockWaylandBuffer();
|
||||
void UnlockWaylandBuffer();
|
||||
|
||||
already_AddRefed<gfx::DrawTarget> LockImageSurface(
|
||||
@@ -206,23 +249,71 @@ class WindowSurfaceWayland : public Wind
|
||||
// mBufferScreenRect is window size when our wayland buffer was allocated.
|
||||
LayoutDeviceIntRect mBufferScreenRect;
|
||||
nsWaylandDisplay* mWaylandDisplay;
|
||||
+
|
||||
+ // Actual buffer (backed by wl_buffer) where all drawings go into.
|
||||
+ // Drawn areas are stored at mWaylandBufferDamage and if there's
|
||||
+ // any uncommited drawings which needs to be send to wayland compositor
|
||||
+ // the mBufferPendingCommit is set.
|
||||
WindowBackBuffer* mWaylandBuffer;
|
||||
- LayoutDeviceIntRegion mWaylandBufferDamage;
|
||||
WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM];
|
||||
+ LayoutDeviceIntRegion mWaylandBufferDamage;
|
||||
+
|
||||
+ // After every commit to wayland compositor a frame callback is requested.
|
||||
+ // Any next commit to wayland compositor will happen when frame callback
|
||||
+ // comes from wayland compositor back as it's the best time to do the commit.
|
||||
wl_callback* mFrameCallback;
|
||||
wl_surface* mLastCommittedSurface;
|
||||
+
|
||||
+ // Registered reference to pending DelayedCommitHandler() call.
|
||||
WindowSurfaceWayland** mDelayedCommitHandle;
|
||||
+
|
||||
+ // Cached drawings. If we can't get WaylandBuffer (wl_buffer) at
|
||||
+ // WindowSurfaceWayland::Lock() we direct gecko rendering to
|
||||
+ // mImageSurface.
|
||||
+ // If we can't get WaylandBuffer at WindowSurfaceWayland::Commit()
|
||||
+ // time, mImageSurface is moved to mDelayedImageCommits which
|
||||
+ // holds all cached drawings.
|
||||
+ // mDelayedImageCommits can be drawn by FrameCallbackHandler(),
|
||||
+ // DelayedCommitHandler() or when WaylandBuffer is detached.
|
||||
RefPtr<gfxImageSurface> mImageSurface;
|
||||
AutoTArray<WindowImageSurface, 30> mDelayedImageCommits;
|
||||
+
|
||||
int64_t mLastCommitTime;
|
||||
+
|
||||
+ // Indicates that we don't have any cached drawings at mDelayedImageCommits
|
||||
+ // and WindowSurfaceWayland::Lock() returned WaylandBuffer to gecko
|
||||
+ // to draw into.
|
||||
bool mDrawToWaylandBufferDirectly;
|
||||
+
|
||||
+ // Set when our cached drawings (mDelayedImageCommits) contains
|
||||
+ // full screen damage. That means we can safely switch WaylandBuffer
|
||||
+ // at LockWaylandBuffer().
|
||||
+ bool mCanSwitchWaylandBuffer;
|
||||
+
|
||||
+ // Set when actual WaylandBuffer contains drawings which are not send to
|
||||
+ // wayland compositor yet.
|
||||
bool mBufferPendingCommit;
|
||||
+
|
||||
+ // We can't send WaylandBuffer (wl_buffer) to compositor when gecko
|
||||
+ // is rendering into it (i.e. between WindowSurfaceWayland::Lock() /
|
||||
+ // WindowSurfaceWayland::Commit()).
|
||||
+ // Thus we use mBufferCommitAllowed to disable commit by callbacks
|
||||
+ // (FrameCallbackHandler(), DelayedCommitHandler())
|
||||
bool mBufferCommitAllowed;
|
||||
- bool mWholeWindowBufferDamage;
|
||||
+
|
||||
+ // We need to clear WaylandBuffer when entire transparent window is repainted.
|
||||
+ // This typically apply to popup windows.
|
||||
bool mBufferNeedsClear;
|
||||
+
|
||||
bool mIsMainThread;
|
||||
+
|
||||
+ // When new WaylandBuffer (wl_buffer) is send to wayland compositor
|
||||
+ // (buffer switch or resize) we also need to set its scale factor.
|
||||
bool mNeedScaleFactorUpdate;
|
||||
|
||||
+ // Image caching strategy, see RenderingCacheMode for details.
|
||||
+ RenderingCacheMode mRenderingCacheMode;
|
||||
+
|
||||
static bool UseDMABufBackend();
|
||||
static bool mUseDMABufInitialized;
|
||||
static bool mUseDMABuf;
|
21
pgo.patch
21
pgo.patch
@ -1,9 +1,10 @@
|
||||
diff -up firefox-64.0/build/unix/mozconfig.unix.pgo firefox-64.0/build/unix/mozconfig.unix
|
||||
--- firefox-64.0/build/unix/mozconfig.unix.pgo 2019-01-03 15:23:16.792980384 +0100
|
||||
+++ firefox-64.0/build/unix/mozconfig.unix 2019-01-03 15:24:29.978693550 +0100
|
||||
diff -up firefox-70.0/build/mozconfig.pgo firefox-70.0/build/mozconfig
|
||||
diff -up firefox-70.0/build/unix/mozconfig.unix.pgo firefox-70.0/build/unix/mozconfig.unix
|
||||
--- firefox-70.0/build/unix/mozconfig.unix.pgo 2019-10-18 18:05:36.461701704 +0200
|
||||
+++ firefox-70.0/build/unix/mozconfig.unix 2019-10-18 20:25:48.036037912 +0200
|
||||
@@ -6,6 +6,15 @@ if [ -n "$FORCE_GCC" ]; then
|
||||
CC="$TOOLTOOL_DIR/gcc/bin/gcc"
|
||||
CXX="$TOOLTOOL_DIR/gcc/bin/g++"
|
||||
CC="$MOZ_FETCHES_DIR/gcc/bin/gcc"
|
||||
CXX="$MOZ_FETCHES_DIR/gcc/bin/g++"
|
||||
|
||||
+ if [ -n "$MOZ_PGO" ]; then
|
||||
+ if [ -z "$USE_ARTIFACT" ]; then
|
||||
@ -16,11 +17,11 @@ diff -up firefox-64.0/build/unix/mozconfig.unix.pgo firefox-64.0/build/unix/mozc
|
||||
+
|
||||
# We want to make sure we use binutils and other binaries in the tooltool
|
||||
# package.
|
||||
mk_add_options "export PATH=$TOOLTOOL_DIR/gcc/bin:$PATH"
|
||||
diff -up firefox-64.0/extensions/spellcheck/src/moz.build.pgo firefox-64.0/extensions/spellcheck/src/moz.build
|
||||
--- firefox-64.0/extensions/spellcheck/src/moz.build.pgo 2018-12-07 03:56:27.000000000 +0100
|
||||
+++ firefox-64.0/extensions/spellcheck/src/moz.build 2019-01-03 15:21:32.793385074 +0100
|
||||
@@ -28,3 +28,5 @@ EXPORTS.mozilla += [
|
||||
mk_add_options "export PATH=$MOZ_FETCHES_DIR/gcc/bin:$PATH"
|
||||
diff -up firefox-70.0/extensions/spellcheck/src/moz.build.pgo firefox-70.0/extensions/spellcheck/src/moz.build
|
||||
--- firefox-70.0/extensions/spellcheck/src/moz.build.pgo 2019-10-16 23:20:18.000000000 +0200
|
||||
+++ firefox-70.0/extensions/spellcheck/src/moz.build 2019-10-18 18:05:36.461701704 +0200
|
||||
@@ -31,3 +31,5 @@ EXPORTS.mozilla += [
|
||||
|
||||
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
|
4
sources
4
sources
@ -1,3 +1,3 @@
|
||||
SHA512 (cbindgen-vendor.tar.xz) = 88afa0bc6af525cbb46bc75578b90419b28b95b396d5002fbf299a78a173681b840096ff83ef6e48553d1a5e0aa04e79383ab4d09bf431f3b864fcbacc7de46d
|
||||
SHA512 (firefox-69.0.3.source.tar.xz) = bc4020c5f1a1eac82944f6402aa374c830231a0f168c6cdab8924a1c7a1b296381b45bce0a0567811ad86c2688972a35fda3f6c15e562b03a47d48617fe7611a
|
||||
SHA512 (firefox-langpacks-69.0.3-20191010.tar.xz) = e293903557dffa0231345a2ae4085705ae3b5b9c1935c1fc2890d042e63862d45134a03403bbebec1fbe068b9d590797946feb8153e2d4129e5f4e309065381a
|
||||
SHA512 (firefox-70.0.source.tar.xz) = c2643d88d59012dfd762357d66005c8892dec066b0ae9d8d33a29ea4427d1e5ae4a0376725c7d960c0025d5c9567eca816eb612b4ea987069e455c06fc442973
|
||||
SHA512 (firefox-langpacks-70.0-20191018.tar.xz) = aa17651aa8d4bc82d014846db559df9e896c329d58acfc145433480ad60cebf5a0a3774958e452d76b3f78bb70545e27208dbe226cfa13fc0a42c65ddfd48d46
|
||||
|
Loading…
Reference in New Issue
Block a user