summaryrefslogtreecommitdiff
path: root/mozilla-1467128.patch
diff options
context:
space:
mode:
authorOndrej Zoder <ozoder@redhat.com>2018-07-17 08:56:42 +0200
committerOndrej Zoder <ozoder@redhat.com>2018-07-17 08:56:42 +0200
commite963c8683d45c7702621537ebf76ced87f5219fd (patch)
treea72e6dc6a6957996577a4bf717158708c0fafc55 /mozilla-1467128.patch
parentMerge branch 'master' into f27 (diff)
downloadlibrewolf-fedora-ff-e963c8683d45c7702621537ebf76ced87f5219fd.tar.gz
librewolf-fedora-ff-e963c8683d45c7702621537ebf76ced87f5219fd.tar.bz2
librewolf-fedora-ff-e963c8683d45c7702621537ebf76ced87f5219fd.zip
Added wayland patches
Diffstat (limited to 'mozilla-1467128.patch')
-rw-r--r--mozilla-1467128.patch359
1 files changed, 359 insertions, 0 deletions
diff --git a/mozilla-1467128.patch b/mozilla-1467128.patch
new file mode 100644
index 0000000..75cf92c
--- /dev/null
+++ b/mozilla-1467128.patch
@@ -0,0 +1,359 @@
+diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h
+--- a/gfx/thebes/gfxPlatformGtk.h
++++ b/gfx/thebes/gfxPlatformGtk.h
+@@ -102,23 +102,42 @@ public:
+ #endif
+
+ #ifdef MOZ_X11
+ Display* GetCompositorDisplay() {
+ return mCompositorDisplay;
+ }
+ #endif // MOZ_X11
+
++#ifdef MOZ_WAYLAND
++ void SetWaylandLastVsync(uint32_t aVsyncTimestamp) {
++ mWaylandLastVsyncTimestamp = aVsyncTimestamp;
++ }
++ int64_t GetWaylandLastVsync() {
++ return mWaylandLastVsyncTimestamp;
++ }
++ void SetWaylandFrameDelay(int64_t aFrameDelay) {
++ mWaylandFrameDelay = aFrameDelay;
++ }
++ int64_t GetWaylandFrameDelay() {
++ return mWaylandFrameDelay;
++ }
++#endif
++
+ protected:
+ bool CheckVariationFontSupport() override;
+
+ int8_t mMaxGenericSubstitutions;
+
+ private:
+ virtual void GetPlatformCMSOutputProfile(void *&mem,
+ size_t &size) override;
+
+ #ifdef MOZ_X11
+ Display* mCompositorDisplay;
+ #endif
++#ifdef MOZ_WAYLAND
++ int64_t mWaylandLastVsyncTimestamp;
++ int64_t mWaylandFrameDelay;
++#endif
+ };
+
+ #endif /* GFX_PLATFORM_GTK_H */
+diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp
+--- a/gfx/thebes/gfxPlatformGtk.cpp
++++ b/gfx/thebes/gfxPlatformGtk.cpp
+@@ -46,16 +46,20 @@
+ #include "GLContextGLX.h"
+ #include "GLXLibrary.h"
+
+ /* Undefine the Status from Xlib since it will conflict with system headers on OSX */
+ #if defined(__APPLE__) && defined(Status)
+ #undef Status
+ #endif
+
++#ifdef MOZ_WAYLAND
++#include <gdk/gdkwayland.h>
++#endif
++
+ #endif /* MOZ_X11 */
+
+ #include <fontconfig/fontconfig.h>
+
+ #include "nsMathUtils.h"
+
+ #define GDK_PIXMAP_SIZE_MAX 32767
+
+@@ -89,16 +93,22 @@ gfxPlatformGtk::gfxPlatformGtk()
+ #ifdef MOZ_X11
+ if (gfxPlatform::IsHeadless() && GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+ mCompositorDisplay = XOpenDisplay(nullptr);
+ MOZ_ASSERT(mCompositorDisplay, "Failed to create compositor display!");
+ } else {
+ mCompositorDisplay = nullptr;
+ }
+ #endif // MOZ_X11
++#ifdef MOZ_WAYLAND
++ // Wayland compositors use g_get_monotonic_time() to get timestamps.
++ mWaylandLastVsyncTimestamp = (g_get_monotonic_time() / 1000);
++ // Set default display fps to 60
++ mWaylandFrameDelay = 1000/60;
++#endif
+ }
+
+ gfxPlatformGtk::~gfxPlatformGtk()
+ {
+ #ifdef MOZ_X11
+ if (mCompositorDisplay) {
+ XCloseDisplay(mCompositorDisplay);
+ }
+@@ -505,26 +515,26 @@ gfxPlatformGtk::CheckVariationFontSuppor
+ // until at least 2.7.1.
+ FT_Int major, minor, patch;
+ FT_Library_Version(GetFTLibrary(), &major, &minor, &patch);
+ return major * 1000000 + minor * 1000 + patch >= 2007001;
+ }
+
+ #ifdef MOZ_X11
+
+-class GLXVsyncSource final : public VsyncSource
++class GtkVsyncSource final : public VsyncSource
+ {
+ public:
+- GLXVsyncSource()
++ GtkVsyncSource()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ mGlobalDisplay = new GLXDisplay();
+ }
+
+- virtual ~GLXVsyncSource()
++ virtual ~GtkVsyncSource()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ }
+
+ virtual Display& GetGlobalDisplay() override
+ {
+ return *mGlobalDisplay;
+ }
+@@ -536,39 +546,52 @@ public:
+ public:
+ GLXDisplay() : mGLContext(nullptr)
+ , mXDisplay(nullptr)
+ , mSetupLock("GLXVsyncSetupLock")
+ , mVsyncThread("GLXVsyncThread")
+ , mVsyncTask(nullptr)
+ , mVsyncEnabledLock("GLXVsyncEnabledLock")
+ , mVsyncEnabled(false)
++#ifdef MOZ_WAYLAND
++ , mIsWaylandDisplay(false)
++#endif
+ {
+ }
+
+ // Sets up the display's GL context on a worker thread.
+ // Required as GLContexts may only be used by the creating thread.
+ // Returns true if setup was a success.
+ bool Setup()
+ {
+ MonitorAutoLock lock(mSetupLock);
+ MOZ_ASSERT(NS_IsMainThread());
+ if (!mVsyncThread.Start())
+ return false;
+
+ RefPtr<Runnable> vsyncSetup =
+- NewRunnableMethod("GLXVsyncSource::GLXDisplay::SetupGLContext",
++ NewRunnableMethod("GtkVsyncSource::GLXDisplay::SetupGLContext",
+ this,
+ &GLXDisplay::SetupGLContext);
+ mVsyncThread.message_loop()->PostTask(vsyncSetup.forget());
+ // Wait until the setup has completed.
+ lock.Wait();
+ return mGLContext != nullptr;
+ }
+
++#ifdef MOZ_WAYLAND
++ bool SetupWayland()
++ {
++ MonitorAutoLock lock(mSetupLock);
++ MOZ_ASSERT(NS_IsMainThread());
++ mIsWaylandDisplay = true;
++ return mVsyncThread.Start();
++ }
++#endif
++
+ // Called on the Vsync thread to setup the GL context.
+ void SetupGLContext()
+ {
+ MonitorAutoLock lock(mSetupLock);
+ MOZ_ASSERT(!NS_IsMainThread());
+ MOZ_ASSERT(!mGLContext, "GLContext already setup!");
+
+ // Create video sync timer on a separate Display to prevent locking the
+@@ -613,29 +636,35 @@ public:
+ }
+
+ lock.NotifyAll();
+ }
+
+ virtual void EnableVsync() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
++#if !defined(MOZ_WAYLAND)
+ MOZ_ASSERT(mGLContext, "GLContext not setup!");
++#endif
+
+ MonitorAutoLock lock(mVsyncEnabledLock);
+ if (mVsyncEnabled) {
+ return;
+ }
+ mVsyncEnabled = true;
+
+ // If the task has not nulled itself out, it hasn't yet realized
+ // that vsync was disabled earlier, so continue its execution.
+ if (!mVsyncTask) {
+ mVsyncTask = NewRunnableMethod(
+- "GLXVsyncSource::GLXDisplay::RunVsync", this, &GLXDisplay::RunVsync);
++ "GtkVsyncSource::GLXDisplay::RunVsync", this,
++#if defined(MOZ_WAYLAND)
++ mIsWaylandDisplay ? &GLXDisplay::RunVsyncWayland :
++#endif
++ &GLXDisplay::RunVsync);
+ RefPtr<Runnable> addrefedTask = mVsyncTask;
+ mVsyncThread.message_loop()->PostTask(addrefedTask.forget());
+ }
+ }
+
+ virtual void DisableVsync() override
+ {
+ MonitorAutoLock lock(mVsyncEnabledLock);
+@@ -650,17 +679,17 @@ public:
+
+ virtual void Shutdown() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ DisableVsync();
+
+ // Cleanup thread-specific resources before shutting down.
+ RefPtr<Runnable> shutdownTask = NewRunnableMethod(
+- "GLXVsyncSource::GLXDisplay::Cleanup", this, &GLXDisplay::Cleanup);
++ "GtkVsyncSource::GLXDisplay::Cleanup", this, &GLXDisplay::Cleanup);
+ mVsyncThread.message_loop()->PostTask(shutdownTask.forget());
+
+ // Stop, waiting for the cleanup task to finish execution.
+ mVsyncThread.Stop();
+ }
+
+ private:
+ virtual ~GLXDisplay()
+@@ -709,50 +738,96 @@ public:
+ }
+ }
+
+ lastVsync = TimeStamp::Now();
+ NotifyVsync(lastVsync);
+ }
+ }
+
++#ifdef MOZ_WAYLAND
++ /* VSync on Wayland is tricky as we can get only "last VSync" event signal.
++ * That means we should draw next frame at "last Vsync + frame delay" time.
++ */
++ void RunVsyncWayland()
++ {
++ MOZ_ASSERT(!NS_IsMainThread());
++
++ for (;;) {
++ {
++ MonitorAutoLock lock(mVsyncEnabledLock);
++ if (!mVsyncEnabled) {
++ mVsyncTask = nullptr;
++ return;
++ }
++ }
++
++ gint64 lastVsync = gfxPlatformGtk::GetPlatform()->GetWaylandLastVsync();
++ gint64 currTime = (g_get_monotonic_time() / 1000);
++
++ gint64 remaining = gfxPlatformGtk::GetPlatform()->GetWaylandFrameDelay() -
++ (currTime - lastVsync);
++ if (remaining > 0) {
++ PlatformThread::Sleep(remaining);
++ } else {
++ // Time from last HW Vsync is longer than our frame delay,
++ // use our approximation then.
++ gfxPlatformGtk::GetPlatform()->SetWaylandLastVsync(currTime);
++ }
++
++ NotifyVsync(TimeStamp::Now());
++ }
++ }
++#endif
++
+ void Cleanup() {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mGLContext = nullptr;
+- XCloseDisplay(mXDisplay);
++ if (mXDisplay)
++ XCloseDisplay(mXDisplay);
+ }
+
+ // Owned by the vsync thread.
+ RefPtr<gl::GLContextGLX> mGLContext;
+ _XDisplay* mXDisplay;
+ Monitor mSetupLock;
+ base::Thread mVsyncThread;
+ RefPtr<Runnable> mVsyncTask;
+ Monitor mVsyncEnabledLock;
+ bool mVsyncEnabled;
++#ifdef MOZ_WAYLAND
++ bool mIsWaylandDisplay;
++#endif
+ };
+ private:
+ // We need a refcounted VsyncSource::Display to use chromium IPC runnables.
+ RefPtr<GLXDisplay> mGlobalDisplay;
+ };
+
+ already_AddRefed<gfx::VsyncSource>
+ gfxPlatformGtk::CreateHardwareVsyncSource()
+ {
++#ifdef MOZ_WAYLAND
++ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
++ RefPtr<VsyncSource> vsyncSource = new GtkVsyncSource();
++ VsyncSource::Display& display = vsyncSource->GetGlobalDisplay();
++ static_cast<GtkVsyncSource::GLXDisplay&>(display).SetupWayland();
++ return vsyncSource.forget();
++ }
++#endif
++
+ // Only use GLX vsync when the OpenGL compositor is being used.
+ // The extra cost of initializing a GLX context while blocking the main
+ // thread is not worth it when using basic composition.
+- // Also don't use it on non-X11 displays.
+ if (gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
+- if (GDK_IS_X11_DISPLAY(gdk_display_get_default()) &&
+- gl::sGLXLibrary.SupportsVideoSync()) {
+- RefPtr<VsyncSource> vsyncSource = new GLXVsyncSource();
++ if (gl::sGLXLibrary.SupportsVideoSync()) {
++ RefPtr<VsyncSource> vsyncSource = new GtkVsyncSource();
+ VsyncSource::Display& display = vsyncSource->GetGlobalDisplay();
+- if (!static_cast<GLXVsyncSource::GLXDisplay&>(display).Setup()) {
++ if (!static_cast<GtkVsyncSource::GLXDisplay&>(display).Setup()) {
+ NS_WARNING("Failed to setup GLContext, falling back to software vsync.");
+ return gfxPlatform::CreateHardwareVsyncSource();
+ }
+ return vsyncSource.forget();
+ }
+ NS_WARNING("SGI_video_sync unsupported. Falling back to software vsync.");
+ }
+ return gfxPlatform::CreateHardwareVsyncSource();
+diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
+--- a/widget/gtk/WindowSurfaceWayland.cpp
++++ b/widget/gtk/WindowSurfaceWayland.cpp
+@@ -546,16 +546,18 @@ WindowBackBuffer::Lock()
+ mWaylandDisplay->GetSurfaceFormat());
+ }
+
+ static void
+ frame_callback_handler(void *data, struct wl_callback *callback, uint32_t time)
+ {
+ auto surface = reinterpret_cast<WindowSurfaceWayland*>(data);
+ surface->FrameCallbackHandler();
++
++ gfxPlatformGtk::GetPlatform()->SetWaylandLastVsync(time);
+ }
+
+ static const struct wl_callback_listener frame_listener = {
+ frame_callback_handler
+ };
+
+ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow)
+ : mWindow(aWindow)
+
bgstack15