summaryrefslogtreecommitdiff
path: root/mozilla-1441743.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-1441743.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-1441743.patch')
-rw-r--r--mozilla-1441743.patch336
1 files changed, 336 insertions, 0 deletions
diff --git a/mozilla-1441743.patch b/mozilla-1441743.patch
new file mode 100644
index 0000000..59018c7
--- /dev/null
+++ b/mozilla-1441743.patch
@@ -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);
bgstack15