xserver: Branch 'master' - 3 commits
Keith Packard
keithp at kemper.freedesktop.org
Thu Sep 11 22:51:15 PDT 2014
hw/xwayland/xwayland-input.c | 9 ++++++++
hw/xwayland/xwayland.c | 48 ++++++++++++++++++++++++++++++-------------
hw/xwayland/xwayland.h | 1
3 files changed, 44 insertions(+), 14 deletions(-)
New commits:
commit d3427717f2c6a473dc3d20631dff653e4e37228e
Author: Adam Jackson <ajax at redhat.com>
Date: Wed Jul 2 12:09:52 2014 -0400
xwayland: Snap damage reports to the bounding box
Instead of sending every little rect. Lets x11perf run to completion,
makes 'while true; do gtkperf -a; done' take longer to crash.
This is effectively a resend of the same logic against the old
xfree86+xwayland branch:
http://lists.x.org/archives/xorg-devel/2013-October/038453.html
Reviewed-by: Daniel Stone <daniel at fooishbar.org>
Reviewed-by: Kristian Høgsberg <krh at bitplanet.net>
Signed-off-by: Adam Jackson <ajax at redhat.com>
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index e0ae2a9..9132969 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -342,7 +342,6 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
struct xwl_window *xwl_window, *next_xwl_window;
RegionPtr region;
BoxPtr box;
- int count, i;
struct wl_buffer *buffer;
PixmapPtr pixmap;
@@ -354,8 +353,6 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
continue;
region = DamageRegion(xwl_window->damage);
- count = RegionNumRects(region);
-
pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
#if GLAMOR_HAS_GBM
@@ -366,12 +363,10 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
- for (i = 0; i < count; i++) {
- box = &RegionRects(region)[i];
- wl_surface_damage(xwl_window->surface,
- box->x1, box->y1,
- box->x2 - box->x1, box->y2 - box->y1);
- }
+
+ box = RegionExtents(region);
+ wl_surface_damage(xwl_window->surface, box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
commit 5ecc0315a2b9bea44ace886f5706a7a3f5cbc4f6
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date: Mon Jun 30 13:53:50 2014 -0400
xwayland: Implement throttling for surfaces based on the frame event
This implements simple throttling that keeps us to one attach per
frame. There isn't really an active performance benefit, since the
buffers will be redrawn only once per frame anyway, but it does cut down
on the chatty network traffic. Since the Wayland sockets might fill
up as well, the cut down on the volume of data we send out also provides
us with a big stability benefit.
Namely, mutter is a lot more stable running gtkperf, a fairly intensive
X11 application, after this change.
Reviewed-by: Daniel Stone <daniel at fooishbar.org>
Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 17b7bf7..e0ae2a9 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -308,6 +308,9 @@ xwl_unrealize_window(WindowPtr window)
xorg_list_del(&xwl_window->link_damage);
DamageUnregister(xwl_window->damage);
DamageDestroy(xwl_window->damage);
+ if (xwl_window->frame_callback)
+ wl_callback_destroy(xwl_window->frame_callback);
+
free(xwl_window);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
@@ -321,17 +324,35 @@ xwl_save_screen(ScreenPtr pScreen, int on)
}
static void
+frame_callback(void *data,
+ struct wl_callback *callback,
+ uint32_t time)
+{
+ struct xwl_window *xwl_window = data;
+ xwl_window->frame_callback = NULL;
+}
+
+static const struct wl_callback_listener frame_listener = {
+ frame_callback
+};
+
+static void
xwl_screen_post_damage(struct xwl_screen *xwl_screen)
{
- struct xwl_window *xwl_window;
+ struct xwl_window *xwl_window, *next_xwl_window;
RegionPtr region;
BoxPtr box;
int count, i;
struct wl_buffer *buffer;
PixmapPtr pixmap;
- xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
- link_damage) {
+ xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
+ &xwl_screen->damage_window_list, link_damage) {
+ /* If we're waiting on a frame callback from the server,
+ * don't attach a new buffer. */
+ if (xwl_window->frame_callback)
+ continue;
+
region = DamageRegion(xwl_window->damage);
count = RegionNumRects(region);
@@ -351,11 +372,15 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
box->x1, box->y1,
box->x2 - box->x1, box->y2 - box->y1);
}
+
+ xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
+ wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
+
wl_surface_commit(xwl_window->surface);
DamageEmpty(xwl_window->damage);
- }
- xorg_list_init(&xwl_screen->damage_window_list);
+ xorg_list_del(&xwl_window->link_damage);
+ }
}
static void
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 60b0c29..bfffa71 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -102,6 +102,7 @@ struct xwl_window {
WindowPtr window;
DamagePtr damage;
struct xorg_list link_damage;
+ struct wl_callback *frame_callback;
};
#define MODIFIER_META 0x01
commit 6c442fc4f7d84508665dfdee8a75ec91f50395dc
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date: Mon Jun 30 15:28:16 2014 -0400
xwayland-input: Fix a crasher for a race with the Wayland compositor
If something quickly maps and unmaps a window, then we'll immediately
create and destroy the Wayland surface that cooresponds to that
window. If our mouse pointer is over the window when the surface is
created, we'll receive a enter on the window.
Since resource creation and destruction is not synchronous, that
means that the compositor will queue up an event for a resource that's
eventually destroyed. On the client-side, when we receive this message,
we note that the resource isn't allocated, and get a NULL surface in our
enter handler. We immediately try to dereference this, and then crash.
This was caused by running gtkperf while moving the window a lot.
Reviewed-by: Daniel Stone <daniel at fooishbar.org>
Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index cc5f7df..b8c543c 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -152,6 +152,15 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
ValuatorMask mask;
+ /* There's a race here where if we create and then immediately
+ * destroy a surface, we might end up in a state where the Wayland
+ * compositor sends us an event for a surface that doesn't exist.
+ *
+ * Don't process enter events in this case.
+ */
+ if (surface == NULL)
+ return;
+
xwl_seat->xwl_screen->serial = serial;
xwl_seat->pointer_enter_serial = serial;
More information about the xorg-commit
mailing list