Xpra: Ticket #345: use XShm to grab window pixels rather than the slower XGetImage


The patch attached allows us to reduce the time it takes to grab pixels for a 1024x1024 window from about 12ms (was ~17ms with GDK Pixbuf instead of XGetImage - before ~r3368) down to just ~3ms.

Things still to be addressed:

Sun, 26 May 2013 13:54:54 GMT - Antoine Martin: attachment set

XShm basic implementation

Sun, 26 May 2013 16:09:11 GMT - Antoine Martin: attachment set

updated patch on top of r3512

Sun, 26 May 2013 16:58:18 GMT - Antoine Martin: owner, status changed

And maybe this should be worked around (Segfault on server ctrl-C):

Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0  0x00007f29f1bb9b93 in __pyx_pf_4xpra_3x11_7gtk_x11_12gdk_bindings_13XImageWrapper_34__dealloc__ (__pyx_v_self=0x1bbe590) \
  at xpra/x11/gtk_x11/gdk_bindings.c:7906
#1  __pyx_pw_4xpra_3x11_7gtk_x11_12gdk_bindings_13XImageWrapper_35__dealloc__ (__pyx_v_self=<xpra.x11.gtk_x11.gdk_bindings.XImageWrapper \
  at remote 0x1bbe590>)
    at xpra/x11/gtk_x11/gdk_bindings.c:7862
#2  __pyx_tp_dealloc_4xpra_3x11_7gtk_x11_12gdk_bindings_XImageWrapper (o=<xpra.x11.gtk_x11.gdk_bindings.XImageWrapper at remote 0x1bbe590>) \
  at xpra/x11/gtk_x11/gdk_bindings.c:16124
#3  0x00000035b1e818e3 in meth_dealloc (m=0x7f29e403fe18) \
  at /usr/src/debug/Python-2.7.3/Objects/methodobject.c:134
#4  0x00007f29f1bb9ddf in __pyx_pf_4xpra_3x11_7gtk_x11_12gdk_bindings_13XImageWrapper_34__dealloc__ (__pyx_v_self=0x1bbe590) \
  at xpra/x11/gtk_x11/gdk_bindings.c:7975
#5  __pyx_pw_4xpra_3x11_7gtk_x11_12gdk_bindings_13XImageWrapper_35__dealloc__ (__pyx_v_self=<xpra.x11.gtk_x11.gdk_bindings.XImageWrapper at remote 0x1bbe590>)
    at xpra/x11/gtk_x11/gdk_bindings.c:7862
#6  __pyx_tp_dealloc_4xpra_3x11_7gtk_x11_12gdk_bindings_XImageWrapper (o=<xpra.x11.gtk_x11.gdk_bindings.XImageWrapper at remote 0x1bbe590>) \
  at xpra/x11/gtk_x11/gdk_bindings.c:16124
#7  0x00007f29f1bb91dc in __pyx_pf_4xpra_3x11_7gtk_x11_12gdk_bindings_11XShmWrapper_6cleanup (__pyx_v_self=0x1bc15f0) \
  at xpra/x11/gtk_x11/gdk_bindings.c:5595
#8  __pyx_pw_4xpra_3x11_7gtk_x11_12gdk_bindings_11XShmWrapper_7cleanup (__pyx_v_self=<xpra.x11.gtk_x11.gdk_bindings.XShmWrapper \
  at remote 0x1bc15f0>, unused=<optimized out>)
    at xpra/x11/gtk_x11/gdk_bindings.c:5502
#9  0x00000035b1edcfd6 in call_function (oparg=<optimized out>, pp_stack=0x7fff9376d5c8) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4082
#10 PyEval_EvalFrameEx (f=<optimized out>, throwflag=throwflag@entry=0) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2740
#11 0x00000035b1edcef1 in fast_function (nk=<optimized out>, na=1, n=<optimized out>, pp_stack=0x7fff9376d7c8, func=<function at remote 0x17006e0>)
    at /usr/src/debug/Python-2.7.3/Python/ceval.c:4184
#12 call_function (oparg=<optimized out>, pp_stack=0x7fff9376d7c8) at /usr/src/debug/Python-2.7.3/Python/ceval.c:4119
#13 PyEval_EvalFrameEx (f=f@entry=
    Frame 0x1895610, for file /usr/lib64/python2.7/site-packages/xpra/x11/gtk_x11/window.py, line 351, in do_unmanaged (self= \
      <WindowModel(_input_field=1, _gproperties={'size-hints': <WMSizeHints(max_aspect_ratio=None, min_aspect_ratio=None, \
        base_size=(19, 4), min_aspect=None, max_aspect=None, min_size=(25, 17), win_gravity=1, resize_inc=(6, 13), max_size=None) at remote 0x17eeed0>, \
      'client-machine': u'desktop', 'pid': 15439, 'owner': None, 'requested-size': (499, 316), \
      'title': u'antoine@desktop:~/projects/Xpra/trunk/src', 'group-leader': None, 'icon-title': u'antoine@desktop:~/projects/Xpra/trunk/src', \
      'icon-pixmap': None, 'user-friendly-size': (80, 24), 'state': frozenset([]), 'transient-for': None, \
      'class-instance': (u'xterm', u'XTerm'), 'iconic': False, 'strut': None, 'window-type': [<gtk.gdk.GdkAtom at remote 0x1716af0>], \
      'requested-position': (0, 0), 'actual-size': (499, 316), 'protocols': ['WM_DELETE_WINDOW'], 'icon': None, \
      'client-window': <gtk.gdk.Window at remote 0x17f70a0>, 'modal': False}, client_wind...(truncated), \
     throwflag=throwflag@entry=0) at /usr/src/debug/Python-2.7.3/Python/ceval.c:2740

Mon, 27 May 2013 10:49:27 GMT - Antoine Martin:

r3530 adds initial support (work in progress)

Fri, 07 Jun 2013 14:20:26 GMT - Antoine Martin:

r3596 fixes segfaults caused by XDestroyImage on an image we still use! (oops)

I still get segfault crashes on exit via control-C, similar to #352 but the solution posted there isn't enough in this case (looks like we must ensure we cleanup the shared memory in the right order)

Handling smaller regions should be doable without too much trouble, we just need to return a new XShmImageWrapper for each region, all pointing to the underlying XShmWrapper - the problem is keeping track of all those objects for managing the garbage collection (lists are easy in python, not so in C/Cython)

Then we still need to handle the resizing issues...

Sat, 08 Jun 2013 05:27:43 GMT - Antoine Martin:

working XShm in r3598 (see commit message for details)

Mon, 10 Jun 2013 13:24:41 GMT - Antoine Martin:

Still todo:

Mon, 17 Jun 2013 12:12:48 GMT - Antoine Martin: status changed; resolution set

XShm is now enabled by default as of r3613

Sat, 22 Jun 2013 03:25:16 GMT - Antoine Martin: status changed; resolution deleted

One more problem: we need to deal with failures and figure out if they are transient, for this window only or if we can forget about using XShm altogether on the server by looking at errno when we get an error from shmget:

Probably not worth trying again, we lack permissions.

Not applicable.

In this case, we don't want to try again for this window unless its size is reduced (not worth trying to parse /proc/sys/kernel/shmmax)

Could be worth trying again later, but we would only make things worse again..

Not applicable.

Should try again later if segments are freed?

Should try again later if segments are freed?

Sat, 22 Jun 2013 11:20:50 GMT - Antoine Martin: status changed; resolution set

Closing again: dealing with failures is now done in r3694

Sat, 23 Jan 2021 04:52:18 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/345