Merge branch 'f27'
This commit is contained in:
commit
77c05527ad
12
firefox.spec
12
firefox.spec
@ -181,6 +181,12 @@ Patch563: rb245262.patch
|
|||||||
Patch564: mozilla-1464808.patch
|
Patch564: mozilla-1464808.patch
|
||||||
Patch565: mozilla-1464823.patch
|
Patch565: mozilla-1464823.patch
|
||||||
Patch566: mozilla-1466473.patch
|
Patch566: mozilla-1466473.patch
|
||||||
|
Patch567: mozilla-1444437.patch
|
||||||
|
Patch568: mozilla-1441743.patch
|
||||||
|
Patch569: mozilla-1465371.patch
|
||||||
|
Patch570: mozilla-1467125.patch
|
||||||
|
Patch571: mozilla-1468670.patch
|
||||||
|
Patch572: mozilla-1467128.patch
|
||||||
|
|
||||||
# Debian patches
|
# Debian patches
|
||||||
Patch500: mozilla-440908.patch
|
Patch500: mozilla-440908.patch
|
||||||
@ -389,6 +395,12 @@ This package contains results of tests executed during build.
|
|||||||
%patch564 -p1 -b .mozilla-1464808
|
%patch564 -p1 -b .mozilla-1464808
|
||||||
%patch565 -p1 -b .mozilla-1464823
|
%patch565 -p1 -b .mozilla-1464823
|
||||||
%patch566 -p1 -b .mozilla-1466473
|
%patch566 -p1 -b .mozilla-1466473
|
||||||
|
%patch567 -p1 -b .mozilla-1444437
|
||||||
|
%patch568 -p1 -b .mozilla-1441743
|
||||||
|
%patch569 -p1 -b .mozilla-1465371
|
||||||
|
%patch570 -p1 -b .mozilla-1467125
|
||||||
|
%patch571 -p1 -b .mozilla-1468670
|
||||||
|
%patch572 -p1 -b .mozilla-1467128
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%{__rm} -f .mozconfig
|
%{__rm} -f .mozconfig
|
||||||
|
336
mozilla-1441743.patch
Normal file
336
mozilla-1441743.patch
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h
|
||||||
|
--- a/widget/gtk/WindowSurfaceWayland.h
|
||||||
|
+++ b/widget/gtk/WindowSurfaceWayland.h
|
||||||
|
@@ -3,16 +3,17 @@
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H
|
||||||
|
#define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H
|
||||||
|
|
||||||
|
#include <prthread.h>
|
||||||
|
+#include "mozilla/gfx/Types.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace widget {
|
||||||
|
|
||||||
|
// Our general connection to Wayland display server,
|
||||||
|
// holds our display connection and runs event loop.
|
||||||
|
class nsWaylandDisplay : public nsISupports {
|
||||||
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
@@ -61,17 +62,17 @@ private:
|
||||||
|
};
|
||||||
|
|
||||||
|
// Holds actual graphics data for wl_surface
|
||||||
|
class WindowBackBuffer {
|
||||||
|
public:
|
||||||
|
WindowBackBuffer(nsWaylandDisplay* aDisplay, int aWidth, int aHeight);
|
||||||
|
~WindowBackBuffer();
|
||||||
|
|
||||||
|
- already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion);
|
||||||
|
+ already_AddRefed<gfx::DrawTarget> Lock();
|
||||||
|
|
||||||
|
void Attach(wl_surface* aSurface);
|
||||||
|
void Detach();
|
||||||
|
bool IsAttached() { return mAttached; }
|
||||||
|
|
||||||
|
bool Resize(int aWidth, int aHeight);
|
||||||
|
bool SetImageDataFromBackBuffer(class WindowBackBuffer* aSourceBuffer);
|
||||||
|
|
||||||
|
@@ -107,27 +108,33 @@ public:
|
||||||
|
WindowSurfaceWayland(nsWindow *aWindow);
|
||||||
|
~WindowSurfaceWayland();
|
||||||
|
|
||||||
|
already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion) override;
|
||||||
|
void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
|
||||||
|
void FrameCallbackHandler();
|
||||||
|
|
||||||
|
private:
|
||||||
|
- WindowBackBuffer* GetBufferToDraw(int aWidth, int aHeight);
|
||||||
|
+ WindowBackBuffer* GetFrontBufferToDraw(int aWidth, int aHeight);
|
||||||
|
void UpdateScaleFactor();
|
||||||
|
|
||||||
|
+ already_AddRefed<gfx::DrawTarget> LockFrontBuffer(int aWidth, int aHeight);
|
||||||
|
+ already_AddRefed<gfx::DrawTarget> LockImageSurface(const gfx::IntSize& aLockSize);
|
||||||
|
+ bool CommitImageSurface(const LayoutDeviceIntRegion& aRegion);
|
||||||
|
+
|
||||||
|
// TODO: Do we need to hold a reference to nsWindow object?
|
||||||
|
nsWindow* mWindow;
|
||||||
|
nsWaylandDisplay* mWaylandDisplay;
|
||||||
|
WindowBackBuffer* mFrontBuffer;
|
||||||
|
WindowBackBuffer* mBackBuffer;
|
||||||
|
+ RefPtr<gfxImageSurface> mImageSurface;
|
||||||
|
wl_callback* mFrameCallback;
|
||||||
|
wl_surface* mFrameCallbackSurface;
|
||||||
|
MessageLoop* mDisplayThreadMessageLoop;
|
||||||
|
+ bool mDirectWlBufferDraw;
|
||||||
|
bool mDelayedCommit;
|
||||||
|
bool mFullScreenDamage;
|
||||||
|
bool mIsMainThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace widget
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
|
||||||
|
--- a/widget/gtk/WindowSurfaceWayland.cpp
|
||||||
|
+++ b/widget/gtk/WindowSurfaceWayland.cpp
|
||||||
|
@@ -299,16 +299,17 @@ nsWaylandDisplay::Matches(wl_display *aD
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(nsWaylandDisplay, nsISupports);
|
||||||
|
|
||||||
|
nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay)
|
||||||
|
: mThreadId(PR_GetCurrentThread())
|
||||||
|
// gfx::SurfaceFormat::B8G8R8A8 is a basic Wayland format
|
||||||
|
// and is always present.
|
||||||
|
+ // TODO: Provide also format without alpha (Bug 1470126).
|
||||||
|
, mFormat(gfx::SurfaceFormat::B8G8R8A8)
|
||||||
|
, mShm(nullptr)
|
||||||
|
, mDisplay(aDisplay)
|
||||||
|
{
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
// Use default event queue in main thread operated by Gtk+.
|
||||||
|
mEventQueue = nullptr;
|
||||||
|
} else {
|
||||||
|
@@ -530,21 +531,19 @@ WindowBackBuffer::SetImageDataFromBackBu
|
||||||
|
}
|
||||||
|
|
||||||
|
mShmPool.SetImageDataFromPool(&aSourceBuffer->mShmPool,
|
||||||
|
aSourceBuffer->mWidth * aSourceBuffer->mHeight * BUFFER_BPP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<gfx::DrawTarget>
|
||||||
|
-WindowBackBuffer::Lock(const LayoutDeviceIntRegion& aRegion)
|
||||||
|
+WindowBackBuffer::Lock()
|
||||||
|
{
|
||||||
|
- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||||
|
- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
|
||||||
|
-
|
||||||
|
+ gfx::IntSize lockSize(mWidth, mHeight);
|
||||||
|
return gfxPlatform::CreateDrawTargetForData(static_cast<unsigned char*>(mShmPool.GetImageData()),
|
||||||
|
lockSize,
|
||||||
|
BUFFER_BPP * mWidth,
|
||||||
|
mWaylandDisplay->GetSurfaceFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
frame_callback_handler(void *data, struct wl_callback *callback, uint32_t time)
|
||||||
|
@@ -560,16 +559,17 @@ static const struct wl_callback_listener
|
||||||
|
WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow)
|
||||||
|
: mWindow(aWindow)
|
||||||
|
, mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay()))
|
||||||
|
, mFrontBuffer(nullptr)
|
||||||
|
, mBackBuffer(nullptr)
|
||||||
|
, mFrameCallback(nullptr)
|
||||||
|
, mFrameCallbackSurface(nullptr)
|
||||||
|
, mDisplayThreadMessageLoop(MessageLoop::current())
|
||||||
|
+ , mDirectWlBufferDraw(true)
|
||||||
|
, mDelayedCommit(false)
|
||||||
|
, mFullScreenDamage(false)
|
||||||
|
, mIsMainThread(NS_IsMainThread())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowSurfaceWayland::~WindowSurfaceWayland()
|
||||||
|
{
|
||||||
|
@@ -598,17 +598,17 @@ WindowSurfaceWayland::UpdateScaleFactor(
|
||||||
|
{
|
||||||
|
wl_surface* waylandSurface = mWindow->GetWaylandSurface();
|
||||||
|
if (waylandSurface) {
|
||||||
|
wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowBackBuffer*
|
||||||
|
-WindowSurfaceWayland::GetBufferToDraw(int aWidth, int aHeight)
|
||||||
|
+WindowSurfaceWayland::GetFrontBufferToDraw(int aWidth, int aHeight)
|
||||||
|
{
|
||||||
|
if (!mFrontBuffer) {
|
||||||
|
mFrontBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight);
|
||||||
|
mBackBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight);
|
||||||
|
return mFrontBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mFrontBuffer->IsAttached()) {
|
||||||
|
@@ -647,46 +647,149 @@ WindowSurfaceWayland::GetBufferToDraw(in
|
||||||
|
// the new buffer and leave gecko to render new whole content.
|
||||||
|
mFrontBuffer->Resize(aWidth, aHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mFrontBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<gfx::DrawTarget>
|
||||||
|
+WindowSurfaceWayland::LockFrontBuffer(int aWidth, int aHeight)
|
||||||
|
+{
|
||||||
|
+ WindowBackBuffer* buffer = GetFrontBufferToDraw(aWidth, aHeight);
|
||||||
|
+ if (buffer) {
|
||||||
|
+ return buffer->Lock();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ NS_WARNING("WindowSurfaceWayland::LockFrontBuffer(): No buffer available");
|
||||||
|
+ return nullptr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+already_AddRefed<gfx::DrawTarget>
|
||||||
|
+WindowSurfaceWayland::LockImageSurface(const gfx::IntSize& aLockSize)
|
||||||
|
+{
|
||||||
|
+ if (!mImageSurface || mImageSurface->CairoStatus() ||
|
||||||
|
+ !(aLockSize <= mImageSurface->GetSize())) {
|
||||||
|
+ mImageSurface = new gfxImageSurface(aLockSize,
|
||||||
|
+ SurfaceFormatToImageFormat(mWaylandDisplay->GetSurfaceFormat()));
|
||||||
|
+ if (mImageSurface->CairoStatus()) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return gfxPlatform::CreateDrawTargetForData(mImageSurface->Data(),
|
||||||
|
+ mImageSurface->GetSize(),
|
||||||
|
+ mImageSurface->Stride(),
|
||||||
|
+ mWaylandDisplay->GetSurfaceFormat());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ 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.
|
||||||
|
+ - mFrontBuffer is available - that's an ideal situation.
|
||||||
|
+ - mFrontBuffer is locked by compositor - flip buffers and draw.
|
||||||
|
+ - if we can't flip buffers - 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());
|
||||||
|
|
||||||
|
- // We allocate back buffer to widget size but return only
|
||||||
|
- // portion requested by aRegion.
|
||||||
|
- LayoutDeviceIntRect rect = mWindow->GetBounds();
|
||||||
|
- WindowBackBuffer* buffer = GetBufferToDraw(rect.width,
|
||||||
|
- rect.height);
|
||||||
|
- if (!buffer) {
|
||||||
|
- NS_WARNING("No drawing buffer available");
|
||||||
|
- return nullptr;
|
||||||
|
+ LayoutDeviceIntRect screenRect = mWindow->GetBounds();
|
||||||
|
+ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||||
|
+ gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
|
||||||
|
+
|
||||||
|
+ // Are we asked for entire nsWindow to draw?
|
||||||
|
+ mDirectWlBufferDraw = (aRegion.GetNumRects() == 1 &&
|
||||||
|
+ bounds.x == 0 && bounds.y == 0 &&
|
||||||
|
+ lockSize.width == screenRect.width &&
|
||||||
|
+ lockSize.height == screenRect.height);
|
||||||
|
+
|
||||||
|
+ if (mDirectWlBufferDraw) {
|
||||||
|
+ RefPtr<gfx::DrawTarget> dt = LockFrontBuffer(screenRect.width,
|
||||||
|
+ screenRect.height);
|
||||||
|
+ if (dt) {
|
||||||
|
+ return dt.forget();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // We don't have any front buffer available. Try indirect drawing
|
||||||
|
+ // to mImageSurface which is mirrored to front buffer at commit.
|
||||||
|
+ mDirectWlBufferDraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return buffer->Lock(aRegion);
|
||||||
|
+ return LockImageSurface(lockSize);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool
|
||||||
|
+WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion)
|
||||||
|
+{
|
||||||
|
+ MOZ_ASSERT(!mDirectWlBufferDraw);
|
||||||
|
+
|
||||||
|
+ LayoutDeviceIntRect screenRect = mWindow->GetBounds();
|
||||||
|
+ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
|
||||||
|
+
|
||||||
|
+ gfx::Rect rect(bounds);
|
||||||
|
+ if (rect.IsEmpty()) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ RefPtr<gfx::DrawTarget> dt = LockFrontBuffer(screenRect.width,
|
||||||
|
+ screenRect.height);
|
||||||
|
+ RefPtr<gfx::SourceSurface> surf =
|
||||||
|
+ gfx::Factory::CreateSourceSurfaceForCairoSurface(mImageSurface->CairoSurface(),
|
||||||
|
+ mImageSurface->GetSize(),
|
||||||
|
+ mImageSurface->Format());
|
||||||
|
+ if (!dt || !surf) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uint32_t numRects = aRegion.GetNumRects();
|
||||||
|
+ if (numRects != 1) {
|
||||||
|
+ AutoTArray<IntRect, 32> rects;
|
||||||
|
+ rects.SetCapacity(numRects);
|
||||||
|
+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||||
|
+ rects.AppendElement(iter.Get().ToUnknownRect());
|
||||||
|
+ }
|
||||||
|
+ dt->PushDeviceSpaceClipRects(rects.Elements(), rects.Length());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dt->DrawSurface(surf, rect, rect);
|
||||||
|
+
|
||||||
|
+ if (numRects != 1) {
|
||||||
|
+ dt->PopClip();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||||
|
|
||||||
|
wl_surface* waylandSurface = mWindow->GetWaylandSurface();
|
||||||
|
if (!waylandSurface) {
|
||||||
|
// Target window is already destroyed - don't bother to render there.
|
||||||
|
+ NS_WARNING("WindowSurfaceWayland::Commit(): parent wl_surface is already hidden/deleted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_proxy_set_queue((struct wl_proxy *)waylandSurface,
|
||||||
|
mWaylandDisplay->GetEventQueue());
|
||||||
|
|
||||||
|
+ if (!mDirectWlBufferDraw) {
|
||||||
|
+ // We have new content at mImageSurface - copy data to mFrontBuffer first.
|
||||||
|
+ CommitImageSurface(aInvalidRegion);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (mFullScreenDamage) {
|
||||||
|
LayoutDeviceIntRect rect = mWindow->GetBounds();
|
||||||
|
wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height);
|
||||||
|
mFullScreenDamage = false;
|
||||||
|
} else {
|
||||||
|
for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||||
|
const mozilla::LayoutDeviceIntRect &r = iter.Get();
|
||||||
|
wl_surface_damage(waylandSurface, r.x, r.y, r.width, r.height);
|
||||||
|
@@ -730,17 +833,17 @@ WindowSurfaceWayland::FrameCallbackHandl
|
||||||
|
mFrameCallback = nullptr;
|
||||||
|
mFrameCallbackSurface = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDelayedCommit) {
|
||||||
|
wl_surface* waylandSurface = mWindow->GetWaylandSurface();
|
||||||
|
if (!waylandSurface) {
|
||||||
|
// Target window is already destroyed - don't bother to render there.
|
||||||
|
- NS_WARNING("No drawing buffer available");
|
||||||
|
+ NS_WARNING("WindowSurfaceWayland::FrameCallbackHandler(): parent wl_surface is already hidden/deleted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_proxy_set_queue((struct wl_proxy *)waylandSurface,
|
||||||
|
mWaylandDisplay->GetEventQueue());
|
||||||
|
|
||||||
|
// Send pending surface to compositor and register frame callback
|
||||||
|
// for possible subsequent drawing.
|
||||||
|
mFrameCallback = wl_surface_frame(waylandSurface);
|
81
mozilla-1444437.patch
Normal file
81
mozilla-1444437.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
diff -up firefox-61.0.1/widget/gtk/mozcontainer.cpp.mozilla-1444437 firefox-61.0.1/widget/gtk/mozcontainer.cpp
|
||||||
|
--- firefox-61.0.1/widget/gtk/mozcontainer.cpp.mozilla-1444437 2018-07-16 16:38:36.059138061 +0200
|
||||||
|
+++ firefox-61.0.1/widget/gtk/mozcontainer.cpp 2018-07-16 17:04:10.127003844 +0200
|
||||||
|
@@ -212,6 +212,7 @@ moz_container_init (MozContainer *contai
|
||||||
|
container->surface = nullptr;
|
||||||
|
container->subsurface = nullptr;
|
||||||
|
container->eglwindow = nullptr;
|
||||||
|
+ container->parent_surface_committed = false;
|
||||||
|
|
||||||
|
GdkDisplay *gdk_display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||||
|
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
|
||||||
|
@@ -231,6 +232,15 @@ moz_container_init (MozContainer *contai
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MOZ_WAYLAND)
|
||||||
|
+static void
|
||||||
|
+moz_container_commited_handler(GdkFrameClock *clock, MozContainer *container)
|
||||||
|
+{
|
||||||
|
+ container->parent_surface_committed = true;
|
||||||
|
+ g_signal_handler_disconnect(clock,
|
||||||
|
+ container->parent_surface_committed_handler);
|
||||||
|
+ container->parent_surface_committed_handler = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* We want to draw to GdkWindow owned by mContainer from Compositor thread but
|
||||||
|
* Gtk+ can be used in main thread only. So we create wayland wl_surface
|
||||||
|
* and attach it as an overlay to GdkWindow.
|
||||||
|
@@ -256,6 +266,21 @@ moz_container_map_surface(MozContainer *
|
||||||
|
if (container->subsurface && container->surface)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
+ if (!container->parent_surface_committed) {
|
||||||
|
+ if (!container->parent_surface_committed_handler) {
|
||||||
|
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||||
|
+ static auto sGdkWindowGetFrameClock =
|
||||||
|
+ (GdkFrameClock *(*)(GdkWindow *))
|
||||||
|
+ dlsym(RTLD_DEFAULT, "gdk_window_get_frame_clock");
|
||||||
|
+ GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
|
||||||
|
+ container->parent_surface_committed_handler =
|
||||||
|
+ g_signal_connect_after(clock, "after-paint",
|
||||||
|
+ G_CALLBACK(moz_container_commited_handler),
|
||||||
|
+ container);
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!container->surface) {
|
||||||
|
struct wl_compositor *compositor;
|
||||||
|
compositor = sGdkWaylandDisplayGetWlCompositor(display);
|
||||||
|
@@ -298,6 +323,19 @@ moz_container_unmap_surface(MozContainer
|
||||||
|
g_clear_pointer(&container->eglwindow, wl_egl_window_destroy);
|
||||||
|
g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
|
||||||
|
g_clear_pointer(&container->surface, wl_surface_destroy);
|
||||||
|
+
|
||||||
|
+ if (container->parent_surface_committed_handler) {
|
||||||
|
+ static auto sGdkWindowGetFrameClock =
|
||||||
|
+ (GdkFrameClock *(*)(GdkWindow *))
|
||||||
|
+ dlsym(RTLD_DEFAULT, "gdk_window_get_frame_clock");
|
||||||
|
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||||
|
+ GdkFrameClock *clock = sGdkWindowGetFrameClock(window);
|
||||||
|
+
|
||||||
|
+ g_signal_handler_disconnect(clock,
|
||||||
|
+ container->parent_surface_committed_handler);
|
||||||
|
+ container->parent_surface_committed_handler = 0;
|
||||||
|
+ }
|
||||||
|
+ container->parent_surface_committed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff -up firefox-61.0.1/widget/gtk/mozcontainer.h.mozilla-1444437 firefox-61.0.1/widget/gtk/mozcontainer.h
|
||||||
|
--- firefox-61.0.1/widget/gtk/mozcontainer.h.mozilla-1444437 2018-07-16 16:38:36.059138061 +0200
|
||||||
|
+++ firefox-61.0.1/widget/gtk/mozcontainer.h 2018-07-16 16:38:36.105138588 +0200
|
||||||
|
@@ -73,6 +73,8 @@ struct _MozContainer
|
||||||
|
struct wl_surface *surface;
|
||||||
|
struct wl_subsurface *subsurface;
|
||||||
|
struct wl_egl_window *eglwindow;
|
||||||
|
+ gboolean parent_surface_committed;
|
||||||
|
+ gulong parent_surface_committed_handler;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
59
mozilla-1465371.patch
Normal file
59
mozilla-1465371.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
|
||||||
|
--- a/toolkit/xre/nsAppRunner.cpp
|
||||||
|
+++ b/toolkit/xre/nsAppRunner.cpp
|
||||||
|
@@ -1700,31 +1700,25 @@ ParseRemoteCommandLine(nsCString& progra
|
||||||
|
|
||||||
|
return REMOTE_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RemoteResult
|
||||||
|
StartRemoteClient(const char* aDesktopStartupID,
|
||||||
|
nsCString& program,
|
||||||
|
const char* profile,
|
||||||
|
- const char* username,
|
||||||
|
- bool aIsX11Display)
|
||||||
|
+ const char* username)
|
||||||
|
{
|
||||||
|
nsAutoPtr<nsRemoteClient> client;
|
||||||
|
|
||||||
|
- if (aIsX11Display) {
|
||||||
|
- client = new XRemoteClient();
|
||||||
|
- } else {
|
||||||
|
#if defined(MOZ_ENABLE_DBUS) && defined(MOZ_WAYLAND)
|
||||||
|
- client = new DBusRemoteClient();
|
||||||
|
+ client = new DBusRemoteClient();
|
||||||
|
#else
|
||||||
|
- MOZ_ASSERT(false, "Missing remote implementation!");
|
||||||
|
- return REMOTE_NOT_FOUND;
|
||||||
|
+ client = new XRemoteClient();
|
||||||
|
#endif
|
||||||
|
- }
|
||||||
|
|
||||||
|
nsresult rv = client->Init();
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return REMOTE_NOT_FOUND;
|
||||||
|
|
||||||
|
nsCString response;
|
||||||
|
bool success = false;
|
||||||
|
rv = client->SendCommandLine(program.get(), username, profile,
|
||||||
|
@@ -4070,18 +4064,17 @@ XREMain::XRE_mainStartup(bool* aExitFlag
|
||||||
|
NS_WARNING("Cannot lock XRemote start mutex");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to remote the entire command line. If this fails, start up normally.
|
||||||
|
const char* desktopStartupIDPtr =
|
||||||
|
mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
|
||||||
|
|
||||||
|
- rr = StartRemoteClient(desktopStartupIDPtr, program, profile, username,
|
||||||
|
- GDK_IS_X11_DISPLAY(mGdkDisplay));
|
||||||
|
+ rr = StartRemoteClient(desktopStartupIDPtr, program, profile, username);
|
||||||
|
if (rr == REMOTE_FOUND) {
|
||||||
|
*aExitFlag = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (rr == REMOTE_ARG_BAD) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
26
mozilla-1467125.patch
Normal file
26
mozilla-1467125.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
|
||||||
|
--- a/widget/gtk/WindowSurfaceWayland.cpp
|
||||||
|
+++ b/widget/gtk/WindowSurfaceWayland.cpp
|
||||||
|
@@ -146,18 +146,19 @@ static StaticMutex gWaylandDisplaysMutex
|
||||||
|
//
|
||||||
|
// nsWaylandDisplay is our interface to wayland compositor. It provides wayland
|
||||||
|
// global objects as we need (wl_display, wl_shm) and operates wl_event_queue on
|
||||||
|
// compositor (not the main) thread.
|
||||||
|
static nsWaylandDisplay* WaylandDisplayGet(wl_display *aDisplay);
|
||||||
|
static void WaylandDisplayRelease(wl_display *aDisplay);
|
||||||
|
static void WaylandDisplayLoop(wl_display *aDisplay);
|
||||||
|
|
||||||
|
-// TODO: is the 60pfs loop correct?
|
||||||
|
-#define EVENT_LOOP_DELAY (1000/60)
|
||||||
|
+// TODO: Bug 1467125 - We need to integrate wl_display_dispatch_queue_pending() with
|
||||||
|
+// compositor event loop.
|
||||||
|
+#define EVENT_LOOP_DELAY (1000/240)
|
||||||
|
|
||||||
|
// Get WaylandDisplay for given wl_display and actual calling thread.
|
||||||
|
static nsWaylandDisplay*
|
||||||
|
WaylandDisplayGetLocked(wl_display *aDisplay, const StaticMutexAutoLock&)
|
||||||
|
{
|
||||||
|
nsWaylandDisplay* waylandDisplay = nullptr;
|
||||||
|
|
||||||
|
int len = gWaylandDisplays.Count();
|
||||||
|
|
359
mozilla-1467128.patch
Normal file
359
mozilla-1467128.patch
Normal file
@ -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)
|
||||||
|
|
102
mozilla-1468670.patch
Normal file
102
mozilla-1468670.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
diff --git a/widget/gtk/nsGtkKeyUtils.h b/widget/gtk/nsGtkKeyUtils.h
|
||||||
|
--- a/widget/gtk/nsGtkKeyUtils.h
|
||||||
|
+++ b/widget/gtk/nsGtkKeyUtils.h
|
||||||
|
@@ -169,17 +169,20 @@ protected:
|
||||||
|
|
||||||
|
bool mInitialized;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializing methods.
|
||||||
|
*/
|
||||||
|
void Init();
|
||||||
|
void InitXKBExtension();
|
||||||
|
- void InitBySystemSettings();
|
||||||
|
+ void InitBySystemSettingsX11();
|
||||||
|
+#ifdef MOZ_WAYLAND
|
||||||
|
+ void InitBySystemSettingsWayland();
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mModifierKeys stores each hardware key information.
|
||||||
|
*/
|
||||||
|
struct ModifierKey {
|
||||||
|
guint mHardwareKeycode;
|
||||||
|
guint mMask;
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/widget/gtk/nsGtkKeyUtils.cpp b/widget/gtk/nsGtkKeyUtils.cpp
|
||||||
|
--- a/widget/gtk/nsGtkKeyUtils.cpp
|
||||||
|
+++ b/widget/gtk/nsGtkKeyUtils.cpp
|
||||||
|
@@ -190,17 +190,21 @@ KeymapWrapper::Init()
|
||||||
|
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
|
||||||
|
("%p Init, mGdkKeymap=%p",
|
||||||
|
this, mGdkKeymap));
|
||||||
|
|
||||||
|
mModifierKeys.Clear();
|
||||||
|
memset(mModifierMasks, 0, sizeof(mModifierMasks));
|
||||||
|
|
||||||
|
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
|
||||||
|
- InitBySystemSettings();
|
||||||
|
+ InitBySystemSettingsX11();
|
||||||
|
+#ifdef MOZ_WAYLAND
|
||||||
|
+ else
|
||||||
|
+ InitBySystemSettingsWayland();
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
gdk_window_add_filter(nullptr, FilterEvents, this);
|
||||||
|
|
||||||
|
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
|
||||||
|
("%p Init, CapsLock=0x%X, NumLock=0x%X, "
|
||||||
|
"ScrollLock=0x%X, Level3=0x%X, Level5=0x%X, "
|
||||||
|
"Shift=0x%X, Ctrl=0x%X, Alt=0x%X, Meta=0x%X, Super=0x%X, Hyper=0x%X",
|
||||||
|
this,
|
||||||
|
@@ -270,20 +274,20 @@ KeymapWrapper::InitXKBExtension()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
|
||||||
|
("%p InitXKBExtension, Succeeded", this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
-KeymapWrapper::InitBySystemSettings()
|
||||||
|
+KeymapWrapper::InitBySystemSettingsX11()
|
||||||
|
{
|
||||||
|
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
|
||||||
|
- ("%p InitBySystemSettings, mGdkKeymap=%p",
|
||||||
|
+ ("%p InitBySystemSettingsX11, mGdkKeymap=%p",
|
||||||
|
this, mGdkKeymap));
|
||||||
|
|
||||||
|
Display* display =
|
||||||
|
gdk_x11_display_get_xdisplay(gdk_display_get_default());
|
||||||
|
|
||||||
|
int min_keycode = 0;
|
||||||
|
int max_keycode = 0;
|
||||||
|
XDisplayKeycodes(display, &min_keycode, &max_keycode);
|
||||||
|
@@ -434,16 +438,26 @@ KeymapWrapper::InitBySystemSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XFreeModifiermap(xmodmap);
|
||||||
|
XFree(xkeymap);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef MOZ_WAYLAND
|
||||||
|
+void
|
||||||
|
+KeymapWrapper::InitBySystemSettingsWayland()
|
||||||
|
+{
|
||||||
|
+ // Not implemented yet, but at least Alt modifier should be handled to save
|
||||||
|
+ // popular usage.
|
||||||
|
+ mModifierMasks[INDEX_ALT] = 1 << 3;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
KeymapWrapper::~KeymapWrapper()
|
||||||
|
{
|
||||||
|
gdk_window_remove_filter(nullptr, FilterEvents, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(mGdkKeymap,
|
||||||
|
FuncToGpointer(OnKeysChanged), this);
|
||||||
|
g_signal_handlers_disconnect_by_func(mGdkKeymap,
|
||||||
|
FuncToGpointer(OnDirectionChanged), this);
|
||||||
|
g_object_unref(mGdkKeymap);
|
Loading…
Reference in New Issue
Block a user