drisw: Cache the depth of the X drawable
authorAdam Jackson <ajax@redhat.com>
Mon, 6 Jan 2020 16:06:30 +0000 (11:06 -0500)
committerMarge Bot <eric+marge@anholt.net>
Thu, 23 Jan 2020 23:03:13 +0000 (23:03 +0000)
This is not always ->rgbBits, because there are cases where that could
be 32 but we're (legally) bound to a depth-24 pixmap. The important
thing to have match here is the actual server-side notion of depth.  You
can look this up (at modest expense) from the xlib visual info if the
fbconfig has a visual. But it might not, so if not, fetch it (at
slightly greater expense) from XGetGeometry. Do this at GLX drawable
creation so you don't have to do it on the SwapBuffers path.

Apparently this fixes glx/glx-swap-singlebuffer, which is unintentional
but quite pleasant.

Fixes: mesa/mesa#2291
Fixes: 90d58286 ("drisw: Fix and simplify drawable setup")
Reviewed-by: Eric Anholt <eric@anholt.net>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3305>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3305>

.gitlab-ci/piglit/quick_gl.txt
src/glx/drisw_glx.c
src/glx/drisw_priv.h

index 51c2cbd68fe0c836e0029856cb7591f7edaf24ff..586ec3c046d68ee3a22e724a762c9a3a62480830 100644 (file)
@@ -22,7 +22,6 @@ glx/glx-swap-event_event: skip
 glx/glx-swap-event_interval: skip
 glx/glx-swap-exchange: skip
 glx/glx-swap-pixmap-bad: fail
-glx/glx-swap-singlebuffer: fail
 glx/glx-visuals-depth: fail
 glx/glx-visuals-depth -pixmap: fail
 glx/glx-visuals-stencil: fail
@@ -2206,8 +2205,8 @@ wgl/wgl-sanity: skip
 summary:
        name:  results
        ----  --------
-       pass:    19319
-       fail:      235
+       pass:    19320
+       fail:      234
       crash:        2
        skip:     1948
     timeout:        0
index 3bf15322ff85e1397aa3174a308a870c50ec4756..069f64d52167e423140d2478028cb1b9a083b4f0 100644 (file)
@@ -64,7 +64,7 @@ XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
       pdp->shminfo.shmid = shmid;
       pdp->ximage = XShmCreateImage(dpy,
                                     NULL,
-                                    pdp->config->rgbBits,
+                                    pdp->xDepth,
                                     ZPixmap,              /* format */
                                     NULL,                 /* data */
                                     &pdp->shminfo,        /* shminfo */
@@ -94,7 +94,7 @@ XCreateDrawable(struct drisw_drawable * pdp, int shmid, Display * dpy)
       pdp->shminfo.shmid = -1;
       pdp->ximage = XCreateImage(dpy,
                                  NULL,
-                                 pdp->config->rgbBits,
+                                 pdp->xDepth,
                                  ZPixmap, 0,             /* format, offset */
                                  NULL,                   /* data */
                                  0, 0,                   /* width, height */
@@ -647,6 +647,7 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable,
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
    struct drisw_screen *psc = (struct drisw_screen *) base;
    const __DRIswrastExtension *swrast = psc->swrast;
+   Display *dpy = psc->base.dpy;
 
    pdp = calloc(1, sizeof(*pdp));
    if (!pdp)
@@ -656,7 +657,34 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable,
    pdp->base.drawable = drawable;
    pdp->base.psc = &psc->base;
    pdp->config = modes;
-   pdp->gc = XCreateGC(psc->base.dpy, xDrawable, 0, NULL);
+   pdp->gc = XCreateGC(dpy, xDrawable, 0, NULL);
+   pdp->xDepth = 0;
+
+   /* Use the visual depth, if this fbconfig corresponds to a visual */
+   if (pdp->config->visualID != 0) {
+      int matches = 0;
+      XVisualInfo *visinfo, template;
+
+      template.visualid = pdp->config->visualID;
+      template.screen = pdp->config->screen;
+      visinfo = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask,
+                               &template, &matches);
+
+      if (visinfo && matches) {
+         pdp->xDepth = visinfo->depth;
+         XFree(visinfo);
+      }
+   }
+
+   /* Otherwise, or if XGetVisualInfo failed, ask the server */
+   if (pdp->xDepth == 0) {
+      Window root;
+      int x, y;
+      unsigned uw, uh, bw, depth;
+
+      XGetGeometry(dpy, xDrawable, &root, &x, &y, &uw, &uh, &bw, &depth);
+      pdp->xDepth = depth;
+   }
 
    /* Create a new drawable */
    pdp->driDrawable =
index bfcf5946c570bf6b296b8209f191d54140fb2111..663decee4c37942edfc415dab24a818b04e9985e 100644 (file)
@@ -66,6 +66,7 @@ struct drisw_drawable
    struct glx_config *config;
    XImage *ximage;
    XShmSegmentInfo shminfo;
+   int xDepth;
 };
 
 _X_HIDDEN int