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