xserver 1.20.4

This commit is contained in:
Adam Jackson 2019-02-26 15:04:39 -05:00
parent ad1a5b36a8
commit 2a3298614e
13 changed files with 6 additions and 893 deletions

View File

@ -1,69 +0,0 @@
From f89518e17f7d507734af212785e0b3e47954f603 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 22 Oct 2018 11:48:25 +0200
Subject: [PATCH xserver] present/wnmd: Fix use after free on CRTC removal
Xwayland will add and remove CRTCs as Wayland outputs are added or
removed.
If there is a pending flip when this occurs, the
`xwl_present_sync_callback()` will be triggered after the Xwayland
output's RRCtrcPtr has been destroyed, hence causing a crash in Xwayland
while trying to use freed memory:
#1 abort ()
#2 OsAbort () at utils.c:1350
#3 AbortServer () at log.c:877
#4 FatalError () at log.c:1015
#5 OsSigHandler () at osinit.c:156
#6 <signal handler called>
#7 dixGetPrivate () at ../include/privates.h:122
#8 dixLookupPrivate () at ../include/privates.h:166
#9 present_screen_priv () at present_priv.h:198
#10 present_wnmd_flip () at present_wnmd.c:358
#11 present_wnmd_execute () at present_wnmd.c:466
#12 present_wnmd_re_execute () at present_wnmd.c:80
#13 xwl_present_sync_callback () at xwayland-present.c:287
#14 ffi_call_unix64 () from /lib64/libffi.so.6
#15 ffi_call () from /lib64/libffi.so.6
#16 wl_closure_invoke () at src/connection.c:1006
#17 dispatch_event () at src/wayland-client.c:1427
#18 dispatch_queue () at src/wayland-client.c:1573
#19 wl_display_dispatch_queue_pending () at src/wayland-client.c:1815
#20 wl_display_dispatch_pending () at src/wayland-client.c:1878
#21 xwl_read_events () at xwayland.c:814
#22 ospoll_wait () at ospoll.c:651
#23 WaitForSomething () at WaitFor.c:208
#24 Dispatch () at ../include/list.h:220
#25 dix_main () at main.c:276
To avoid the issue, get the `ScreenPtr` from the window instead of the
CRTC that might have been just freed, `xwl_present_flip()` has no use
for the CRTC anyway.
Bugzilla: https://bugs.freedesktop.org/108249
Suggested-by: Michel Daenzer <michel.daenzer@amd.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Daenzer <michel.daenzer@amd.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit b768b7d6cec41b8b320c468ec41aab5a8b49b27b)
---
present/present_wnmd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 8f3836440..2c6412a72 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -354,7 +354,7 @@ present_wnmd_flip(WindowPtr window,
Bool sync_flip,
RegionPtr damage)
{
- ScreenPtr screen = crtc->pScreen;
+ ScreenPtr screen = window->drawable.pScreen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
return (*screen_priv->wnmd_info->flip) (window,
--
2.20.1

View File

@ -24,7 +24,7 @@ index 8158c2b62..78d1c947d 100644
@@ -1190,6 +1191,25 @@ xf86VideoPtrToDriverList(struct pci_device *dev, @@ -1190,6 +1191,25 @@ xf86VideoPtrToDriverList(struct pci_device *dev,
int idx = 0; int idx = 0;
#ifdef __linux__ #if defined(__linux__) || defined(__NetBSD__)
+ char busid[32]; + char busid[32];
+ int fd; + int fd;
+ +

View File

@ -1,48 +0,0 @@
From 64f5e6ec2d297f90e9b9785a1cb7285d609a1877 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Fri, 19 Oct 2018 18:27:37 +0200
Subject: [PATCH xserver] xwayland: Plug leaks in xwl_present_sync_callback
xwl_present_window->sync_callback was leaked.
The event memory was leaked if the corresponding buffer had already been
released.
(cherry picked from commit cb0de153bf0c486da7e968ab0f258c9c0c9ed34a)
---
hw/xwayland/xwayland-present.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 316e04443..fb5c6499e 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -274,6 +274,9 @@ xwl_present_sync_callback(void *data,
struct xwl_present_event *event = data;
struct xwl_present_window *xwl_present_window = event->xwl_present_window;
+ wl_callback_destroy(xwl_present_window->sync_callback);
+ xwl_present_window->sync_callback = NULL;
+
event->pending = FALSE;
if (event->abort) {
@@ -289,12 +292,14 @@ xwl_present_sync_callback(void *data,
xwl_present_window->ust,
xwl_present_window->msc);
- if (event->buffer_released)
+ if (event->buffer_released) {
/* If the buffer was already released, send the event now again */
present_wnmd_event_notify(xwl_present_window->window,
event->event_id,
xwl_present_window->ust,
xwl_present_window->msc);
+ xwl_present_free_event(event);
+ }
}
static const struct wl_callback_listener xwl_present_sync_listener = {
--
2.20.1

View File

@ -1,59 +0,0 @@
From 26eb8a0020ebf0e3a550f98be5f58820db765b2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Wed, 24 Oct 2018 11:23:05 +0200
Subject: [PATCH xserver 1/7] xwayland: Use xwl_present_reset_timer in
xwl_present_timer_callback
Apart from simplifying the code, this should also prevent a condition
(which might only be possible with the following fix) reported in
https://gitlab.freedesktop.org/wayland/weston/issues/115#note_52467:
1. xwl_present_timer_callback indirectly calls xwl_present_reset_timer
-> xwl_present_free_timer
2. xwl_present_timer_callback then returns a non-0 value, so DoTimer
calls TimerSet with the old xwl_present_window->frame_timer pointer
which was freed in step 1 => use after free
Calling xwl_present_reset_timer explicitly passes NULL to TimerSet if
step 1 freed xwl_present_window->frame_timer, and it will allocate a new
one.
(cherry picked from commit 5e8b9a3a563047e3998d45e761f7a50e4b0f6cb3)
---
hw/xwayland/xwayland-present.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 316e04443..7539c1636 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -216,24 +216,15 @@ xwl_present_timer_callback(OsTimerPtr timer,
void *arg)
{
struct xwl_present_window *xwl_present_window = arg;
- WindowPtr present_window = xwl_present_window->window;
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
xwl_present_window->frame_timer_firing = TRUE;
xwl_present_window->msc++;
xwl_present_window->ust = GetTimeInMicros();
xwl_present_events_notify(xwl_present_window);
+ xwl_present_reset_timer(xwl_present_window);
- if (xwl_present_has_events(xwl_present_window)) {
- /* Still events, restart timer */
- return xwl_present_is_flipping(present_window, xwl_window) ? TIMER_LEN_FLIP :
- TIMER_LEN_COPY;
- } else {
- /* No more events, do not restart timer and delete it instead */
- xwl_present_free_timer(xwl_present_window);
- return 0;
- }
+ return 0;
}
static void
--
2.19.2

View File

@ -1,72 +0,0 @@
From d2af650a280f94d7ddd155cb499110ab45135100 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 19 Oct 2018 16:04:32 +0200
Subject: [PATCH xserver] xwayland: do not crash if `gbm_bo_create()` fails
The function `xwl_glamor_gbm_create_pixmap()` first creates a buffer
objects and then creates the xwl_pixmap from it.
However, `xwl_glamor_gbm_create_pixmap_for_bo()` is not called if the
buffer object creation fails, and `xwl_glamor_gbm_create_pixmap()`
simply returns `glamor_create_pixmap()`.
The problem with this is that if `xwl_glamor_gbm_create_pixmap_for_bo()`
is not called then neither is `xwl_pixmap_set_private()` and further
calls to `xwl_pixmap_get()` will return NULL and cause a NULL pointer
dereference if the return value is not checked:
#0 xwl_glamor_gbm_get_wl_buffer_for_pixmap ()
at hw/xwayland/xwayland-glamor-gbm.c:248
#1 xwl_window_post_damage () at hw/xwayland/xwayland.c:697
#2 xwl_display_post_damage () at hw/xwayland/xwayland.c:759
#3 block_handler () at hw/xwayland/xwayland.c:890
#4 BlockHandler () at dix/dixutils.c:388
#5 WaitForSomething () at os/WaitFor.c:201
#6 Dispatch () at dix/dispatch.c:421
#7 dix_main () at dix/main.c:276
#8 __libc_start_main () at ../csu/libc-start.c:308
#9 _start ()
(gdb) print xwl_pixmap
$1 = (struct xwl_pixmap *) 0x0
Make sure we check for `xwl_pixmap_get()` returned value where relevant
and fail gracefully if this is the case.
See also: https://gitlab.gnome.org/GNOME/mutter/issues/340
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Marco Trevisan <mail@3v1n0.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 036794bebce72a3fa2f95996d2e537ff568e0ff1)
---
hw/xwayland/xwayland-glamor-gbm.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 6aa1e4641d..5f8a68fd8c 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -244,6 +244,9 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
uint64_t modifier;
int i;
+ if (xwl_pixmap == NULL)
+ return NULL;
+
if (xwl_pixmap->buffer) {
/* Buffer already exists. Return it and inform caller if interested. */
if (created)
@@ -494,6 +497,9 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
xwl_pixmap = xwl_pixmap_get(pixmap);
+ if (xwl_pixmap == NULL)
+ return 0;
+
if (!xwl_pixmap->bo)
return 0;
--
2.19.1

View File

@ -1,62 +0,0 @@
From a352f979545723054b0a74862a56dc53b1be93fb Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 8 Jan 2019 12:48:53 +0100
Subject: [PATCH xserver] xwayland: handle case without any crtc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Xwayland creates and destroys the CRTC along with the Wayland outputs,
so there is possibly a case where the number of CRTC drops to 0.
However, `xwl_present_get_crtc()` always return `crtcs[0]` which is
invalid when `numCrtcs` is 0.
That leads to crash if a client queries the Present capabilities when
there is no CRTC, the backtrace looks like:
#0 raise() from libc.so
#1 abort() from libc.so
#2 OsAbort() at utils.c:1350
#3 AbortServer() at log.c:879
#4 FatalError() at log.c:1017
#5 OsSigHandler() at osinit.c:156
#6 OsSigHandler() at osinit.c:110
#7 <signal handler called>
#8 main_arena() from libc.so
#9 proc_present_query_capabilities() at present_request.c:236
#10 Dispatch() at dispatch.c:478
#11 dix_main() at main.c:276
To avoid returning an invalid pointer (`crtcs[0]`) in that case, simply
check for `numCrtcs` being 0 and return `NULL` in that case.
Thanks to Michel Dänzer <michel.daenzer@amd.com> for pointing this as a
possible cause of the crash.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Bugzilla: https://bugzilla.redhat.com/1609181
(cherry picked from commit e8295c50209f2963fa2823e8de7e8363a38cd2d1)
---
hw/xwayland/xwayland-present.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 980034db4..74fe84672 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -323,6 +323,10 @@ xwl_present_get_crtc(WindowPtr present_window)
return NULL;
rr_private = rrGetScrPriv(present_window->drawable.pScreen);
+
+ if (rr_private->numCrtcs == 0)
+ return NULL;
+
return rr_private->crtcs[0];
}
--
2.20.1

View File

@ -1,61 +0,0 @@
From bd4b3eb727b14133929d7bf04fed3829a632fc5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Thu, 18 Oct 2018 17:36:24 +0200
Subject: [PATCH xserver 2/7] xwayland: Rename xwl_present_events_notify to
xwl_present_msc_bump
And consolidate more code from xwl_present_timer_callback and
xwl_present_frame_callback in it.
(cherry picked from commit 2bfc46d4147dc0bec4cdbb80431a0f4cc1d3b030)
---
hw/xwayland/xwayland-present.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 7539c1636..117ce781d 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -192,11 +192,13 @@ static const struct wl_buffer_listener xwl_present_release_listener = {
};
static void
-xwl_present_events_notify(struct xwl_present_window *xwl_present_window)
+xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
{
- uint64_t msc = xwl_present_window->msc;
+ uint64_t msc = ++xwl_present_window->msc;
struct xwl_present_event *event, *tmp;
+ xwl_present_window->ust = GetTimeInMicros();
+
xorg_list_for_each_entry_safe(event, tmp,
&xwl_present_window->event_list,
list) {
@@ -218,10 +220,8 @@ xwl_present_timer_callback(OsTimerPtr timer,
struct xwl_present_window *xwl_present_window = arg;
xwl_present_window->frame_timer_firing = TRUE;
- xwl_present_window->msc++;
- xwl_present_window->ust = GetTimeInMicros();
- xwl_present_events_notify(xwl_present_window);
+ xwl_present_msc_bump(xwl_present_window);
xwl_present_reset_timer(xwl_present_window);
return 0;
@@ -242,10 +242,7 @@ xwl_present_frame_callback(void *data,
return;
}
- xwl_present_window->msc++;
- xwl_present_window->ust = GetTimeInMicros();
-
- xwl_present_events_notify(xwl_present_window);
+ xwl_present_msc_bump(xwl_present_window);
/* we do not need the timer anymore for this frame,
* reset it for potentially the next one
--
2.19.2

View File

@ -1,139 +0,0 @@
From 908c3b4c291e62e63677a75e125f6fd7706493aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Thu, 18 Oct 2018 17:42:01 +0200
Subject: [PATCH xserver 3/7] xwayland: Complete "synchronous" Present flips
from xwl_present_msc_bump
Completing them from xwl_present_sync_callback had at least two issues:
* It was before the MSC was incremented in xwl_present_frame_callback,
so the MSC value in the completion event could be lower than the
target specified by the client. This could cause hangs with the Mesa
Vulkan drivers.
* It allowed clients to run at a frame-rate higher than the Wayland
compositor's frame-rate, wasting energy on generating frames which
were never displayed. This isn't expected to happen unless the client
specified PresentOptionAsync (in which case flips are still completed
from xwl_present_sync_callback, allowing higher frame-rates).
v2:
* Make xwl_present_has_events return true when there's a pending
"synchronous" flip, so those complete after at most ~1 second even if
the Wayland server doesn't send a frame event.
Bugzilla: https://bugs.freedesktop.org/106713
(cherry picked from commit ace551d8a2603e37b18237a52f62d627c75d9e2a)
---
hw/xwayland/xwayland-present.c | 51 +++++++++++++++++++++++++++++-----
hw/xwayland/xwayland.h | 1 +
2 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 117ce781d..4f517d46b 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -85,7 +85,8 @@ xwl_present_timer_callback(OsTimerPtr timer,
static inline Bool
xwl_present_has_events(struct xwl_present_window *xwl_present_window)
{
- return !xorg_list_is_empty(&xwl_present_window->event_list) ||
+ return !!xwl_present_window->sync_flip ||
+ !xorg_list_is_empty(&xwl_present_window->event_list) ||
!xorg_list_is_empty(&xwl_present_window->release_queue);
}
@@ -139,6 +140,16 @@ xwl_present_cleanup(WindowPtr window)
}
/* Clear remaining buffer releases and inform Present about free ressources */
+ event = xwl_present_window->sync_flip;
+ xwl_present_window->sync_flip = NULL;
+ if (event) {
+ if (event->buffer_released) {
+ free(event);
+ } else {
+ event->pending = FALSE;
+ event->abort = TRUE;
+ }
+ }
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) {
xorg_list_del(&event->list);
event->abort = TRUE;
@@ -199,6 +210,24 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
xwl_present_window->ust = GetTimeInMicros();
+ event = xwl_present_window->sync_flip;
+ xwl_present_window->sync_flip = NULL;
+ if (event) {
+ event->pending = FALSE;
+
+ present_wnmd_event_notify(xwl_present_window->window, event->event_id,
+ xwl_present_window->ust, msc);
+
+ if (event->buffer_released) {
+ /* If the buffer was already released, clean up now */
+ present_wnmd_event_notify(xwl_present_window->window, event->event_id,
+ xwl_present_window->ust, msc);
+ free(event);
+ } else {
+ xorg_list_add(&event->list, &xwl_present_window->release_queue);
+ }
+ }
+
xorg_list_for_each_entry_safe(event, tmp,
&xwl_present_window->event_list,
list) {
@@ -454,12 +483,17 @@ xwl_present_flip(WindowPtr present_window,
event->event_id = event_id;
event->xwl_present_window = xwl_present_window;
event->buffer = buffer;
- event->target_msc = xwl_present_window->msc;
+ event->target_msc = target_msc;
event->pending = TRUE;
event->abort = FALSE;
event->buffer_released = FALSE;
- xorg_list_add(&event->list, &xwl_present_window->release_queue);
+ if (sync_flip) {
+ xorg_list_init(&event->list);
+ xwl_present_window->sync_flip = event;
+ } else {
+ xorg_list_add(&event->list, &xwl_present_window->release_queue);
+ }
if (buffer_created)
wl_buffer_add_listener(buffer, &xwl_present_release_listener, NULL);
@@ -488,10 +522,13 @@ xwl_present_flip(WindowPtr present_window,
wl_surface_commit(xwl_window->surface);
- xwl_present_window->sync_callback = wl_display_sync(xwl_window->xwl_screen->display);
- wl_callback_add_listener(xwl_present_window->sync_callback,
- &xwl_present_sync_listener,
- event);
+ if (!sync_flip) {
+ xwl_present_window->sync_callback =
+ wl_display_sync(xwl_window->xwl_screen->display);
+ wl_callback_add_listener(xwl_present_window->sync_callback,
+ &xwl_present_sync_listener,
+ event);
+ }
wl_display_flush(xwl_window->xwl_screen->display);
return TRUE;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 67819e178..3f4a601fe 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -188,6 +188,7 @@ struct xwl_window {
#ifdef GLAMOR_HAS_GBM
struct xwl_present_window {
struct xwl_screen *xwl_screen;
+ struct xwl_present_event *sync_flip;
WindowPtr window;
struct xorg_list link;
--
2.19.2

View File

@ -1,213 +0,0 @@
From 5a1cb0989274fd745569a60c28c9a5ca729cabf6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Thu, 1 Nov 2018 18:44:24 +0100
Subject: [PATCH xserver 4/7] xwayland: Replace xwl_window::present_window with
::present_flipped
There's no need to keep track of the window which last performed a
Present flip. This fixes crashes due to the assertion in
xwl_present_flips_stop failing. Fixes issue #10.
The damage generated by a flip only needs to be ignored once, then
xwl_window::present_flipped can be cleared. This may fix freezing in
the (hypothetical) scenario where Present flips are performed on a
window, followed by other drawing requests using the window as the
destination, but nothing triggering xwl_present_flips_stop. The damage
from the latter drawing requests would continue being ignored.
(cherry picked from commit 6b016d58d23d16eaae9908a92ed90547d1926317)
---
hw/xwayland/xwayland-present.c | 56 ++++++++--------------------------
hw/xwayland/xwayland.c | 17 ++++++++---
hw/xwayland/xwayland.h | 4 ++-
3 files changed, 27 insertions(+), 50 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 4f517d46b..e6dca5ed0 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -90,24 +90,19 @@ xwl_present_has_events(struct xwl_present_window *xwl_present_window)
!xorg_list_is_empty(&xwl_present_window->release_queue);
}
-static inline Bool
-xwl_present_is_flipping(WindowPtr window, struct xwl_window *xwl_window)
-{
- return xwl_window && xwl_window->present_window == window;
-}
-
static void
xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
{
if (xwl_present_has_events(xwl_present_window)) {
- WindowPtr present_window = xwl_present_window->window;
- Bool is_flipping = xwl_present_is_flipping(present_window,
- xwl_window_from_window(present_window));
+ CARD32 timeout;
+
+ if (xwl_present_window->frame_callback)
+ timeout = TIMER_LEN_FLIP;
+ else
+ timeout = TIMER_LEN_COPY;
xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
- 0,
- is_flipping ? TIMER_LEN_FLIP :
- TIMER_LEN_COPY,
+ 0, timeout,
&xwl_present_timer_callback,
xwl_present_window);
} else {
@@ -118,16 +113,12 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
void
xwl_present_cleanup(WindowPtr window)
{
- struct xwl_window *xwl_window = xwl_window_from_window(window);
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
struct xwl_present_event *event, *tmp;
if (!xwl_present_window)
return;
- if (xwl_window && xwl_window->present_window == window)
- xwl_window->present_window = NULL;
-
if (xwl_present_window->frame_callback) {
wl_callback_destroy(xwl_present_window->frame_callback);
xwl_present_window->frame_callback = NULL;
@@ -361,10 +352,6 @@ xwl_present_queue_vblank(WindowPtr present_window,
if (!xwl_window)
return BadMatch;
- if (xwl_window->present_window &&
- xwl_window->present_window != present_window)
- return BadMatch;
-
event = malloc(sizeof *event);
if (!event)
return BadAlloc;
@@ -433,13 +420,6 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
if (!xwl_window)
return FALSE;
- /*
- * Do not flip if there is already another child window doing flips.
- */
- if (xwl_window->present_window &&
- xwl_window->present_window != present_window)
- return FALSE;
-
/*
* We currently only allow flips of windows, that have the same
* dimensions as their xwl_window parent window. For the case of
@@ -476,8 +456,6 @@ xwl_present_flip(WindowPtr present_window,
if (!event)
return FALSE;
- xwl_window->present_window = present_window;
-
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created);
event->event_id = event_id;
@@ -502,13 +480,6 @@ xwl_present_flip(WindowPtr present_window,
/* We can flip directly to the main surface (full screen window without clips) */
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
- if (!xwl_present_window->frame_timer ||
- xwl_present_window->frame_timer_firing) {
- /* Realign timer */
- xwl_present_window->frame_timer_firing = FALSE;
- xwl_present_reset_timer(xwl_present_window);
- }
-
if (!xwl_present_window->frame_callback) {
xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface);
wl_callback_add_listener(xwl_present_window->frame_callback,
@@ -516,6 +487,10 @@ xwl_present_flip(WindowPtr present_window,
xwl_present_window);
}
+ /* Realign timer */
+ xwl_present_window->frame_timer_firing = FALSE;
+ xwl_present_reset_timer(xwl_present_window);
+
wl_surface_damage(xwl_window->surface, 0, 0,
damage_box->x2 - damage_box->x1,
damage_box->y2 - damage_box->y1);
@@ -531,22 +506,15 @@ xwl_present_flip(WindowPtr present_window,
}
wl_display_flush(xwl_window->xwl_screen->display);
+ xwl_window->present_flipped = TRUE;
return TRUE;
}
static void
xwl_present_flips_stop(WindowPtr window)
{
- struct xwl_window *xwl_window = xwl_window_from_window(window);
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
- if (!xwl_window)
- return;
-
- assert(xwl_window->present_window == window);
-
- xwl_window->present_window = NULL;
-
/* Change back to the fast refresh rate */
xwl_present_reset_timer(xwl_present_window);
}
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 96b4db18c..988b8e17d 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -370,6 +370,18 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
struct xwl_window *xwl_window = data;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+#ifdef GLAMOR_HAS_GBM
+ if (xwl_window->present_flipped) {
+ /* This damage is from a Present flip, which already committed a new
+ * buffer for the surface, so we don't need to do anything in response
+ */
+ RegionEmpty(DamageRegion(pDamage));
+ xorg_list_del(&xwl_window->link_damage);
+ xwl_window->present_flipped = FALSE;
+ return;
+ }
+#endif
+
xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
}
@@ -721,11 +733,6 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
&xwl_screen->damage_window_list, link_damage) {
-#ifdef GLAMOR_HAS_GBM
- /* Present on the main surface. So don't commit here as well. */
- if (xwl_window->present_window)
- continue;
-#endif
/* If we're waiting on a frame callback from the server,
* don't attach a new buffer. */
if (xwl_window->frame_callback)
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 3f4a601fe..a79f836ad 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -182,7 +182,9 @@ struct xwl_window {
struct xorg_list link_damage;
struct wl_callback *frame_callback;
Bool allow_commits;
- WindowPtr present_window;
+#ifdef GLAMOR_HAS_GBM
+ Bool present_flipped;
+#endif
};
#ifdef GLAMOR_HAS_GBM
--
2.19.2

View File

@ -1,77 +0,0 @@
From cd243d4c858d9193ba0eeab778c488b74505d0e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Thu, 1 Nov 2018 18:24:28 +0100
Subject: [PATCH xserver 5/7] xwayland: Add xwl_present_unrealize_window
When a window is unrealized, a pending frame callback may never be
called, which could result in repeatedly freezing until the frame timer
fires after a second.
Fixes these symptoms when switching from fullscreen to windowed mode in
sauerbraten.
(cherry picked from commit 8c9538573cb9a342897eb3fb4b0c1e4ed917bd0e)
---
hw/xwayland/xwayland-present.c | 16 ++++++++++++++++
hw/xwayland/xwayland.c | 5 +++++
hw/xwayland/xwayland.h | 1 +
3 files changed, 22 insertions(+)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index e6dca5ed0..7e49cb366 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -519,6 +519,22 @@ xwl_present_flips_stop(WindowPtr window)
xwl_present_reset_timer(xwl_present_window);
}
+void
+xwl_present_unrealize_window(WindowPtr window)
+{
+ struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+
+ if (!xwl_present_window || !xwl_present_window->frame_callback)
+ return;
+
+ /* The pending frame callback may never be called, so drop it and shorten
+ * the frame timer interval.
+ */
+ wl_callback_destroy(xwl_present_window->frame_callback);
+ xwl_present_window->frame_callback = NULL;
+ xwl_present_reset_timer(xwl_present_window);
+}
+
static present_wnmd_info_rec xwl_present_info = {
.version = PRESENT_SCREEN_INFO_VERSION,
.get_crtc = xwl_present_get_crtc,
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 988b8e17d..7e6e0ab25 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -609,6 +609,11 @@ xwl_unrealize_window(WindowPtr window)
xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
screen->UnrealizeWindow = xwl_unrealize_window;
+#ifdef GLAMOR_HAS_GBM
+ if (xwl_screen->present)
+ xwl_present_unrealize_window(window);
+#endif
+
xwl_window = xwl_window_get(window);
if (!xwl_window)
return ret;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index a79f836ad..463622669 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -454,6 +454,7 @@ void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
#ifdef GLAMOR_HAS_GBM
Bool xwl_present_init(ScreenPtr screen);
void xwl_present_cleanup(WindowPtr window);
+void xwl_present_unrealize_window(WindowPtr window);
#endif /* GLAMOR_HAS_GBM */
#ifdef XV
--
2.19.2

View File

@ -1,36 +0,0 @@
From 679aa2a629e09aba00f26c819431e7d3a9113834 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Fri, 9 Nov 2018 17:18:53 +0100
Subject: [PATCH xserver 6/7] xwayland: Don't need xwl_window anymore in
xwl_present_queue_vblank
Fixes issue #12. Presumably the problem was that Present operations on
unmapped windows were executed immediately instead of only when reaching
the target MSC.
(cherry picked from commit f541615342ce6bfb0e6d4e68deb3a924a87e8ba9)
---
hw/xwayland/xwayland-present.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 7e49cb366..eea7415f3 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -345,13 +345,9 @@ xwl_present_queue_vblank(WindowPtr present_window,
uint64_t event_id,
uint64_t msc)
{
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
struct xwl_present_event *event;
- if (!xwl_window)
- return BadMatch;
-
event = malloc(sizeof *event);
if (!event)
return BadAlloc;
--
2.19.2

View File

@ -1,37 +0,0 @@
From 354ed9fa48118026456ec2bc64136993f3c53606 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
Date: Thu, 15 Nov 2018 17:16:59 +0100
Subject: [PATCH xserver 7/7] xwayland: Don't take buffer release queue into
account for frame timer
The buffer release queue has two kinds of entries:
* Pending async flips.
* Completed flips waiting for their buffer to be released by the Wayland
compositor.
xwl_present_timer_callback neither completes async flips nor releases
buffers, so the timer isn't needed for the buffer release queue.
(cherry picked from commit e6cd1c9bdefe83e7d99b703a68d26eebb451f889)
---
hw/xwayland/xwayland-present.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index eea7415f3..594e2e822 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -86,8 +86,7 @@ static inline Bool
xwl_present_has_events(struct xwl_present_window *xwl_present_window)
{
return !!xwl_present_window->sync_flip ||
- !xorg_list_is_empty(&xwl_present_window->event_list) ||
- !xorg_list_is_empty(&xwl_present_window->release_queue);
+ !xorg_list_is_empty(&xwl_present_window->event_list);
}
static void
--
2.19.2

View File

@ -45,8 +45,8 @@
Summary: X.Org X11 X server Summary: X.Org X11 X server
Name: xorg-x11-server Name: xorg-x11-server
Version: 1.20.3 Version: 1.20.4
Release: 4%{?gitdate:.%{gitdate}}%{?dist} Release: 1%{?gitdate:.%{gitdate}}%{?dist}
URL: http://www.x.org URL: http://www.x.org
License: MIT License: MIT
@ -94,23 +94,6 @@ Patch5: 0001-autobind-GPUs-to-the-screen.patch
# because the display-managers are not ready yet, do not upstream # because the display-managers are not ready yet, do not upstream
Patch6: 0001-Fedora-hack-Make-the-suid-root-wrapper-always-start-.patch Patch6: 0001-Fedora-hack-Make-the-suid-root-wrapper-always-start-.patch
# https://gitlab.freedesktop.org/ajax/xserver/tree/server-1.20-branch
Patch7: 0001-xwayland-do-not-crash-if-gbm_bo_create-fails.patch
# Xwayland/Present fixes from master upstream
Patch11: 0001-xwayland-Use-xwl_present_reset_timer-in-xwl_present_.patch
Patch12: 0002-xwayland-Rename-xwl_present_events_notify-to-xwl_pre.patch
Patch13: 0003-xwayland-Complete-synchronous-Present-flips-from-xwl.patch
Patch14: 0004-xwayland-Replace-xwl_window-present_window-with-pres.patch
Patch15: 0005-xwayland-Add-xwl_present_unrealize_window.patch
Patch16: 0006-xwayland-Don-t-need-xwl_window-anymore-in-xwl_presen.patch
Patch17: 0007-xwayland-Don-t-take-buffer-release-queue-into-accoun.patch
Patch18: 0001-xwayland-Plug-leaks-in-xwl_present_sync_callback.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1609181
Patch19: 0001-xwayland-handle-case-without-any-crtc.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1661748
Patch20: 0001-present-wnmd-Fix-use-after-free-on-CRTC-removal.patch
BuildRequires: systemtap-sdt-devel BuildRequires: systemtap-sdt-devel
BuildRequires: git BuildRequires: git
BuildRequires: automake autoconf libtool pkgconfig BuildRequires: automake autoconf libtool pkgconfig
@ -535,6 +518,9 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%changelog %changelog
* Tue Feb 26 2019 Adam Jackson <ajax@redhat.com> - 1.20.4-1
- xserver 1.20.4
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.20.3-4 * Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.20.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild