[Mesa-dev] [PATCH] RFC: drisw/glx: use XShm if possible

Marc-André Lureau marcandre.lureau at gmail.com
Mon Jun 8 11:05:32 PDT 2015


Hi Jose

Thanks a lot for the quick feedback!

On Fri, Jun 5, 2015 at 9:13 PM, Jose Fonseca <jfonseca at vmware.com> wrote:

> Sounds good in principle.  I'm actually surprised this was happening
> already. I always use llvmpipe the the non-DRI pure XLIB state tracker
> which already does this.
>
>
I saw that code, but I am afraid this is not usable in a distro like RHEL,
since DRI is enabled.


> Two comments:
>
> - There's src/gallium/winsys/sw/xlib/xlib_sw_winsys.c which implements
> this. I wonder if it would be simpler/cleaner for
> src/gallium/winsys/sw/dri/dri_sw_winsys.c to just piggy back on it somehow.
>

that doesn't look easy to me, probably for the same reason that drisw_glx.c
doesn't reuse xlib_sw_winsys.c

>
> - I think that more care must be taken to pre-emptively remove the shmids,
> as these can leak if application doesn't terminate cleanly, causing the
> system to run out of shmids, which causes the rendering faling back to slow
> XPutImage and even more stability problems.
>
>
you are right, it leaks, I will try to fix this


>   See also
>
>
>
> http://cgit.freedesktop.org/mesa/mesa/commit/?id=e29525f79fdb62993e14a4bc87a9e0955b838de0
>
>   BTW, this is the garbagge collection script I use on my Jenkins setup to
> ensure we don't leak shmids:
>
>     $ cat shmgc.sh
>     #!/bin/sh
>     ipcs -m | awk '{ if ($6 == 0) print "-m " $2; }' | xargs
> --no-run-if-empty ipcrm
>
>   I suggest you run piglit, and compare the output of `$ cat shmgc.sh
> #!/bin/sh
> ipcs -m | awk '{ if ($6 == 0) print "-m " $2; }' | xargs --no-run-if-empty
> ipcrm
> ` before and after, to see if they are leaking or not.
>
>
> One question about the commit message: What do you mean by "video
> frames"?  Are you talking about video players using GL backend? Or general
> 3D?
>

In gnome-shell, the desktop is composited with clutter. When you have a
video playing, the compositor (with dri/sw) sends a lot of XPutImage per
video frame. This confuses the video detection heuristic in the spice
server. (without compositor, XShmPutImage can be used directly, with one
request per frame)


>
> Jose
>
>
>
>
> On 05/06/15 18:14, Marc-André Lureau wrote:
>
>> XPutImage requires to copy the images around, and the request may be
>> split over several chunks. Using XShm may improve performance.
>>
>> In particular, the performances are bad when using gnome-shell with
>> Spice and playing video. Chunking the update confuses the video
>> detection heuristic: unfortunately it's not easy to change it without
>> breaking further other cases. Making one big request per video frames
>> solves most of the issues.
>> ---
>>   include/GL/internal/dri_interface.h           |  12 ++-
>>   src/gallium/include/state_tracker/drisw_api.h |   3 +
>>   src/gallium/state_trackers/dri/drisw.c        |  37 +++++--
>>   src/gallium/winsys/sw/dri/dri_sw_winsys.c     |  69 ++++++++++---
>>   src/glx/drisw_glx.c                           | 141
>> +++++++++++++++++++++++---
>>   src/glx/drisw_priv.h                          |   7 +-
>>   6 files changed, 231 insertions(+), 38 deletions(-)
>>
>> diff --git a/include/GL/internal/dri_interface.h
>> b/include/GL/internal/dri_interface.h
>> index c827bb6..61cb58f 100644
>> --- a/include/GL/internal/dri_interface.h
>> +++ b/include/GL/internal/dri_interface.h
>> @@ -502,7 +502,7 @@ struct __DRIdamageExtensionRec {
>>    * SWRast Loader extension.
>>    */
>>   #define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
>> -#define __DRI_SWRAST_LOADER_VERSION 2
>> +#define __DRI_SWRAST_LOADER_VERSION 3
>>   struct __DRIswrastLoaderExtensionRec {
>>       __DRIextension base;
>>
>> @@ -535,6 +535,16 @@ struct __DRIswrastLoaderExtensionRec {
>>       void (*putImage2)(__DRIdrawable *drawable, int op,
>>                         int x, int y, int width, int height, int stride,
>>                         char *data, void *loaderPrivate);
>> +
>> +    /**
>> +     * Put image to drawable
>> +     *
>> +     * \since 3
>> +     */
>> +    void (*putImageShm)(__DRIdrawable *drawable, int op,
>> +                        int x, int y, int width, int height, int stride,
>> +                        int shmid, char *shmaddr, unsigned offset,
>> +                        void *loaderPrivate);
>>   };
>>
>>   /**
>> diff --git a/src/gallium/include/state_tracker/drisw_api.h
>> b/src/gallium/include/state_tracker/drisw_api.h
>> index 328440c..010a603 100644
>> --- a/src/gallium/include/state_tracker/drisw_api.h
>> +++ b/src/gallium/include/state_tracker/drisw_api.h
>> @@ -15,6 +15,9 @@ struct drisw_loader_funcs
>>                         void *data, unsigned width, unsigned height);
>>      void (*put_image2) (struct dri_drawable *dri_drawable,
>>                          void *data, int x, int y, unsigned width,
>> unsigned height, unsigned stride);
>> +   void (*put_image_shm) (struct dri_drawable *dri_drawable,
>> +                          int shmid, char *shmaddr, unsigned offset,
>> +                          int x, int y, unsigned width, unsigned height,
>> unsigned stride);
>>   };
>>
>>   /**
>> diff --git a/src/gallium/state_trackers/dri/drisw.c
>> b/src/gallium/state_trackers/dri/drisw.c
>> index 4a2c1bb..75c8e85e 100644
>> --- a/src/gallium/state_trackers/dri/drisw.c
>> +++ b/src/gallium/state_trackers/dri/drisw.c
>> @@ -26,14 +26,6 @@
>>    *
>>
>>  **************************************************************************/
>>
>> -/* TODO:
>> - *
>> - * xshm / EGLImage:
>> - *
>> - * Allow the loaders to use the XSHM extension. It probably requires
>> callbacks
>> - * for createImage/destroyImage similar to DRI2 getBuffers.
>> - */
>> -
>>   #include "util/u_format.h"
>>   #include "util/u_memory.h"
>>   #include "util/u_inlines.h"
>> @@ -85,6 +77,19 @@ put_image2(__DRIdrawable *dPriv, void *data, int x,
>> int y,
>>   }
>>
>>   static INLINE void
>> +put_image_shm(__DRIdrawable *dPriv, int shmid, char *shmaddr,
>> +              unsigned offset, int x, int y,
>> +              unsigned width, unsigned height, unsigned stride)
>> +{
>> +   __DRIscreen *sPriv = dPriv->driScreenPriv;
>> +   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
>> +
>> +   loader->putImageShm(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
>> +                       x, y, width, height, stride,
>> +                       shmid, shmaddr, offset, dPriv->loaderPrivate);
>> +}
>> +
>> +static INLINE void
>>   get_image(__DRIdrawable *dPriv, int x, int y, int width, int height,
>> void *data)
>>   {
>>      __DRIscreen *sPriv = dPriv->driScreenPriv;
>> @@ -123,6 +128,17 @@ drisw_put_image2(struct dri_drawable *drawable,
>>      put_image2(dPriv, data, x, y, width, height, stride);
>>   }
>>
>> +static void
>> +drisw_put_image_shm(struct dri_drawable *drawable,
>> +                    int shmid, char *shmaddr, unsigned offset,
>> +                    int x, int y, unsigned width, unsigned height,
>> +                    unsigned stride)
>> +{
>> +   __DRIdrawable *dPriv = drawable->dPriv;
>> +
>> +   put_image_shm(dPriv, shmid, shmaddr, offset, x, y, width, height,
>> stride);
>> +}
>> +
>>   static INLINE void
>>   drisw_present_texture(__DRIdrawable *dPriv,
>>                         struct pipe_resource *ptex, struct pipe_box
>> *sub_box)
>> @@ -345,6 +361,7 @@ static struct drisw_loader_funcs drisw_lf = {
>>   static const __DRIconfig **
>>   drisw_init_screen(__DRIscreen * sPriv)
>>   {
>> +   const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
>>      const __DRIconfig **configs;
>>      struct dri_screen *screen;
>>      struct pipe_screen *pscreen;
>> @@ -360,6 +377,10 @@ drisw_init_screen(__DRIscreen * sPriv)
>>
>>      sPriv->driverPrivate = (void *)screen;
>>      sPriv->extensions = drisw_screen_extensions;
>> +   if (loader->base.version >= 3) {
>> +      if (loader->putImageShm)
>> +         drisw_lf.put_image_shm = drisw_put_image_shm;
>> +   }
>>
>>      pscreen = drisw_create_screen(&drisw_lf);
>>      /* dri_init_screen_helper checks pscreen for us */
>> diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
>> b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
>> index 6fed22b..d35218a 100644
>> --- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
>> +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
>> @@ -26,17 +26,20 @@
>>    *
>>
>>  **************************************************************************/
>>
>> +#include <sys/ipc.h>
>> +#include <sys/shm.h>
>> +
>>   #include "pipe/p_compiler.h"
>>   #include "pipe/p_format.h"
>>   #include "util/u_inlines.h"
>>   #include "util/u_format.h"
>>   #include "util/u_math.h"
>>   #include "util/u_memory.h"
>> +#include "util/u_debug.h"
>>
>>   #include "state_tracker/sw_winsys.h"
>>   #include "dri_sw_winsys.h"
>>
>> -
>>   struct dri_sw_displaytarget
>>   {
>>      enum pipe_format format;
>> @@ -44,6 +47,7 @@ struct dri_sw_displaytarget
>>      unsigned height;
>>      unsigned stride;
>>
>> +   int shmid;
>>      void *data;
>>      void *mapped;
>>   };
>> @@ -77,6 +81,25 @@ dri_sw_is_displaytarget_format_supported( struct
>> sw_winsys *ws,
>>      return TRUE;
>>   }
>>
>> +static char *
>> +alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size)
>> +{
>> +   char *addr;
>> +
>> +   dri_sw_dt->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
>> +   if (dri_sw_dt->shmid < 0) {
>> +      return NULL;
>> +   }
>> +
>> +   addr = (char *) shmat(dri_sw_dt->shmid, 0, 0);
>> +   if (addr == (char *) -1) {
>> +      shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
>> +      return NULL;
>> +   }
>> +
>> +   return addr;
>> +}
>> +
>>   static struct sw_displaytarget *
>>   dri_sw_displaytarget_create(struct sw_winsys *winsys,
>>                               unsigned tex_usage,
>> @@ -85,6 +108,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
>>                               unsigned alignment,
>>                               unsigned *stride)
>>   {
>> +   struct dri_sw_winsys *ws = dri_sw_winsys(winsys);
>>      struct dri_sw_displaytarget *dri_sw_dt;
>>      unsigned nblocksy, size, format_stride;
>>
>> @@ -102,7 +126,13 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
>>      nblocksy = util_format_get_nblocksy(format, height);
>>      size = dri_sw_dt->stride * nblocksy;
>>
>> -   dri_sw_dt->data = align_malloc(size, alignment);
>> +   dri_sw_dt->shmid = -1;
>> +   if (ws->lf->put_image_shm)
>> +      dri_sw_dt->data = alloc_shm(dri_sw_dt, size);
>> +
>> +   if(!dri_sw_dt->data)
>> +      dri_sw_dt->data = align_malloc(size, alignment);
>> +
>>      if(!dri_sw_dt->data)
>>         goto no_data;
>>
>> @@ -121,7 +151,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
>>   {
>>      struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
>>
>> -   FREE(dri_sw_dt->data);
>> +   if (dri_sw_dt->shmid >= 0) {
>> +      shmdt(dri_sw_dt->data);
>> +      shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
>> +   } else {
>> +      FREE(dri_sw_dt->data);
>> +   }
>>
>>      FREE(dri_sw_dt);
>>   }
>> @@ -172,25 +207,33 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
>>      struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
>>      struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
>>      struct dri_drawable *dri_drawable = (struct dri_drawable
>> *)context_private;
>> -   unsigned width, height;
>> +   unsigned width, height, x = 0, y = 0;
>>      unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
>> +   unsigned offset = 0;
>> +   void *data = dri_sw_dt->data;
>>
>>      /* Set the width to 'stride / cpp'.
>>       *
>>       * PutImage correctly clips to the width of the dst drawable.
>>       */
>> -   width = dri_sw_dt->stride / blsize;
>> -
>> -   height = dri_sw_dt->height;
>> -
>>      if (box) {
>> -       void *data;
>> -       data = dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x *
>> blsize;
>> -       dri_sw_ws->lf->put_image2(dri_drawable, data,
>> -                                 box->x, box->y, box->width,
>> box->height, dri_sw_dt->stride);
>> +      offset = (dri_sw_dt->stride * box->y) + box->x * blsize;
>> +      data += offset;
>> +      x = box->x;
>> +      y = box->y;
>> +      width = box->width;
>> +      height = box->height;
>>      } else {
>> -       dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width,
>> height);
>> +      width = dri_sw_dt->stride / blsize;
>> +      height = dri_sw_dt->height;
>>      }
>> +
>> +   if (dri_sw_dt->shmid == -1)
>> +      dri_sw_ws->lf->put_image2(dri_drawable, data,
>> +                                x, y, width, height, dri_sw_dt->stride);
>> +   else
>> +      dri_sw_ws->lf->put_image_shm(dri_drawable, dri_sw_dt->shmid,
>> dri_sw_dt->data, offset,
>> +                                   x, y, width, height,
>> dri_sw_dt->stride);
>>   }
>>
>>   static void
>> diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
>> index 749ceb0..89b9525 100644
>> --- a/src/glx/drisw_glx.c
>> +++ b/src/glx/drisw_glx.c
>> @@ -30,8 +30,8 @@
>>   #include "drisw_priv.h"
>>
>>   static Bool
>> -XCreateDrawable(struct drisw_drawable * pdp,
>> -                Display * dpy, XID drawable, int visualid)
>> +XCreateGCs(struct drisw_drawable * pdp,
>> +           Display * dpy, XID drawable, int visualid)
>>   {
>>      XGCValues gcvalues;
>>      long visMask;
>> @@ -56,7 +56,63 @@ XCreateDrawable(struct drisw_drawable * pdp,
>>      if (!pdp->visinfo || num_visuals == 0)
>>         return False;
>>
>> +   return True;
>> +}
>> +
>> +static volatile int XErrorFlag = 0;
>> +
>> +/**
>> + * Catches potential Xlib errors.
>> + */
>> +static int
>> +handle_xerror(Display *dpy, XErrorEvent *event)
>> +{
>> +   (void) dpy;
>> +   (void) event;
>> +   XErrorFlag = 1;
>> +   return 0;
>> +}
>> +
>> +static Bool
>> +XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
>> +{
>> +   if (pdp->ximage)
>> +      XDestroyImage(pdp->ximage);
>> +
>> +   if (shmid >= 0) {
>> +      int (*old_handler)(Display *, XErrorEvent *);
>> +
>> +      pdp->shminfo.shmid = shmid;
>> +      pdp->ximage = XShmCreateImage(dpy,
>> +                                    pdp->visinfo->visual,
>> +                                    pdp->visinfo->depth,
>> +                                    ZPixmap,
>> +                                    NULL,
>> +                                    &pdp->shminfo,
>> +                                    0, 0);
>> +      if (pdp->ximage == NULL)
>> +         goto ximage;
>> +
>> +      XErrorFlag = 0;
>> +      old_handler = XSetErrorHandler(handle_xerror);
>> +      /* This may trigger the X protocol error we're ready to catch: */
>> +      XShmAttach(dpy, &pdp->shminfo);
>> +      XSync(dpy, False);
>> +
>> +      if (!XErrorFlag)
>> +         goto end;
>> +
>> +      /* we are on a remote display, this error is normal, don't print
>> it */
>> +      XFlush(dpy);
>> +      XErrorFlag = 0;
>> +      XDestroyImage(pdp->ximage);
>> +      pdp->ximage = NULL;
>> +      (void) XSetErrorHandler(old_handler);
>> +   }
>> +
>> +ximage:
>>      /* create XImage */
>> +   pdp->shminfo.shmid = -1;
>>      pdp->ximage = XCreateImage(dpy,
>>                                 pdp->visinfo->visual,
>>                                 pdp->visinfo->depth,
>> @@ -66,6 +122,7 @@ XCreateDrawable(struct drisw_drawable * pdp,
>>                                 32,                     /* bitmap_pad */
>>                                 0);                     /* bytes_per_line
>> */
>>
>> +end:
>>     /**
>>      * swrast does not handle 24-bit depth with 24 bpp, so let X do the
>>      * the conversion for us.
>> @@ -79,7 +136,9 @@ XCreateDrawable(struct drisw_drawable * pdp,
>>   static void
>>   XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID
>> drawable)
>>   {
>> -   XDestroyImage(pdp->ximage);
>> +   if (pdp->ximage)
>> +      XDestroyImage(pdp->ximage);
>> +
>>      free(pdp->visinfo);
>>
>>      XFreeGC(dpy, pdp->gc);
>> @@ -133,9 +192,9 @@ bytes_per_line(unsigned pitch_bits, unsigned mul)
>>   }
>>
>>   static void
>> -swrastPutImage2(__DRIdrawable * draw, int op,
>> +swrastXPutImage(__DRIdrawable * draw, int op,
>>                   int x, int y, int w, int h, int stride,
>> -                char *data, void *loaderPrivate)
>> +                int shmid, char *data, void *loaderPrivate)
>>   {
>>      struct drisw_drawable *pdp = loaderPrivate;
>>      __GLXDRIdrawable *pdraw = &(pdp->base);
>> @@ -144,6 +203,11 @@ swrastPutImage2(__DRIdrawable * draw, int op,
>>      XImage *ximage;
>>      GC gc;
>>
>> +   if (!pdp->ximage || shmid != pdp->shminfo.shmid) {
>> +      if (!XCreateDrawable(pdp, shmid, dpy))
>> +         return;
>> +   }
>> +
>>      switch (op) {
>>      case __DRI_SWRAST_IMAGE_OP_DRAW:
>>         gc = pdp->gc;
>> @@ -156,24 +220,51 @@ swrastPutImage2(__DRIdrawable * draw, int op,
>>      }
>>
>>      drawable = pdraw->xDrawable;
>> -
>>      ximage = pdp->ximage;
>> -   ximage->data = data;
>> -   ximage->width = w;
>> -   ximage->height = h;
>>      ximage->bytes_per_line = stride ? stride : bytes_per_line(w *
>> ximage->bits_per_pixel, 32);
>> +   ximage->data = data;
>>
>> -   XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
>> -
>> +   if (pdp->shminfo.shmid >= 0) {
>> +      ximage->width = ximage->bytes_per_line / 4;
>> +      ximage->height = h;
>> +      XShmPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h, False);
>> +   } else {
>> +      ximage->width = w;
>> +      ximage->height = h;
>> +      XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
>> +   }
>>      ximage->data = NULL;
>>   }
>>
>>   static void
>> +swrastPutImageShm(__DRIdrawable * draw, int op,
>> +                  int x, int y, int w, int h, int stride,
>> +                  int shmid, char *shmaddr, unsigned offset,
>> +                  void *loaderPrivate)
>> +{
>> +   struct drisw_drawable *pdp = loaderPrivate;
>> +
>> +   pdp->shminfo.shmaddr = shmaddr;
>> +   swrastXPutImage(draw, op, x, y, w, h, stride, shmid,
>> +                   shmaddr + offset, loaderPrivate);
>> +}
>> +
>> +static void
>> +swrastPutImage2(__DRIdrawable * draw, int op,
>> +                int x, int y, int w, int h, int stride,
>> +                char *data, void *loaderPrivate)
>> +{
>> +   swrastXPutImage(draw, op, x, y, w, h, stride, -1,
>> +                   data, loaderPrivate);
>> +}
>> +
>> +static void
>>   swrastPutImage(__DRIdrawable * draw, int op,
>>                  int x, int y, int w, int h,
>>                  char *data, void *loaderPrivate)
>>   {
>> -   swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate);
>> +   swrastXPutImage(draw, op, x, y, w, h, 0, -1,
>> +                   data, loaderPrivate);
>>   }
>>
>>   static void
>> @@ -187,6 +278,11 @@ swrastGetImage(__DRIdrawable * read,
>>      Drawable readable;
>>      XImage *ximage;
>>
>> +   if (!prp->ximage || prp->shminfo.shmid >= 0) {
>> +      if (!XCreateDrawable(prp, -1, dpy))
>> +         return;
>> +   }
>> +
>>      readable = pread->xDrawable;
>>
>>      ximage = prp->ximage;
>> @@ -200,13 +296,14 @@ swrastGetImage(__DRIdrawable * read,
>>      ximage->data = NULL;
>>   }
>>
>> -static const __DRIswrastLoaderExtension swrastLoaderExtension = {
>> -   .base = {__DRI_SWRAST_LOADER, 2 },
>> +static __DRIswrastLoaderExtension swrastLoaderExtension = {
>> +   .base = {__DRI_SWRAST_LOADER, 3 },
>>
>>      .getDrawableInfo     = swrastGetDrawableInfo,
>>      .putImage            = swrastPutImage,
>>      .getImage            = swrastGetImage,
>>      .putImage2           = swrastPutImage2,
>> +   .putImageShm         = swrastPutImageShm,
>>   };
>>
>>   static const __DRIextension *loader_extensions[] = {
>> @@ -512,7 +609,7 @@ driswCreateDrawable(struct glx_screen *base, XID
>> xDrawable,
>>      pdp->base.drawable = drawable;
>>      pdp->base.psc = &psc->base;
>>
>> -   ret = XCreateDrawable(pdp, psc->base.dpy, xDrawable, modes->visualID);
>> +   ret = XCreateGCs(pdp, psc->base.dpy, xDrawable, modes->visualID);
>>      if (!ret) {
>>         free(pdp);
>>         return NULL;
>> @@ -640,6 +737,17 @@ driswBindExtensions(struct drisw_screen *psc, const
>> __DRIextension **extensions)
>>      }
>>   }
>>
>> +static int
>> +check_xshm(Display *dpy)
>> +{
>> +   int ignore;
>> +
>> +   /* XXX: could check XShmAttach too for remote case */
>> +   /* handles it fine when calling later though */
>> +
>> +   return XQueryExtension(dpy, "MIT-SHM", &ignore, &ignore, &ignore);
>> +}
>> +
>>   static struct glx_screen *
>>   driswCreateScreen(int screen, struct glx_display *priv)
>>   {
>> @@ -667,6 +775,9 @@ driswCreateScreen(int screen, struct glx_display
>> *priv)
>>      if (extensions == NULL)
>>         goto handle_error;
>>
>> +   if (!check_xshm(psc->base.dpy))
>> +      swrastLoaderExtension.putImageShm = NULL;
>> +
>>      for (i = 0; extensions[i]; i++) {
>>         if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
>>          psc->core = (__DRIcoreExtension *) extensions[i];
>> diff --git a/src/glx/drisw_priv.h b/src/glx/drisw_priv.h
>> index 5d47900..dc1fc58 100644
>> --- a/src/glx/drisw_priv.h
>> +++ b/src/glx/drisw_priv.h
>> @@ -22,6 +22,11 @@
>>    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> DEALINGS IN THE
>>    * SOFTWARE.
>>    */
>> +#include <assert.h>
>> +
>> +#include <sys/ipc.h>
>> +#include <sys/shm.h>
>> +#include <X11/extensions/XShm.h>
>>
>>   struct drisw_display
>>   {
>> @@ -32,7 +37,6 @@ struct drisw_context
>>   {
>>      struct glx_context base;
>>      __DRIcontext *driContext;
>> -
>>   };
>>
>>   struct drisw_screen
>> @@ -62,6 +66,7 @@ struct drisw_drawable
>>      __DRIdrawable *driDrawable;
>>      XVisualInfo *visinfo;
>>      XImage *ximage;
>> +   XShmSegmentInfo shminfo;
>>   };
>>
>>   _X_HIDDEN int
>>
>>
>


-- 
Marc-André Lureau
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150608/c6e1ff5c/attachment-0001.html>


More information about the mesa-dev mailing list