[Mesa-dev] [PATCH 4/4] glx/dri2: Try and detect invalid DRI buffers

George Barrett bob at bob131.so
Tue Nov 21 11:15:30 UTC 2017


DRI routines in X drivers can return null buffers if they're unable to
allocate them as requested (for example, [1]) but the DRI 2 protocol
doesn't expose a mechanism to communicate this explicitly. Instead, we
assume that zeroed out buffer info structs are invalid and go from
there.

This commit also corrects a minor bug wherein dri2_bind_context
(dri2_glx.c) inadvertently indicates success upon the failure of the
provided dri2_screen->bindContext method.

[1]: https://cgit.freedesktop.org/xorg/driver/xf86-video-ati/tree/src/radeon_glamor.c?id=5cdd334b3402c2431deb3a87a8d04ef590da53ee#n201
---
 src/glx/dri2_glx.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 0f44635725..cc3b43146b 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -152,7 +152,9 @@ dri2_bind_context(struct glx_context *context, struct glx_context *old,
       return GLXBadDrawable;
 
    if (!(*psc->core->bindContext) (pcp->driContext, dri_draw, dri_read))
-      return GLXBadContext;
+      /* GLXBadContext has the same value as Success, so return something
+       * similar instead. */
+      return GLXBadContextState;
 
    /* If the server doesn't send invalidate events, we may miss a
     * resize before the rendering starts.  Invalidate the buffers now
@@ -719,16 +721,27 @@ dri2DestroyScreen(struct glx_screen *base)
  * Processes the list of buffers received in a reply from the server to either
  * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
  */
-static void
+static Bool
 process_buffers(struct dri2_drawable * pdraw, DRI2Buffer * buffers,
                 unsigned count)
 {
    int i;
+   /* The buffer we would expect if a pixmap allocator within X returned
+    * NullPixmap to a DRI routine. */
+   static const DRI2Buffer NullBuffer = {};
 
    pdraw->bufferCount = count;
    pdraw->have_fake_front = 0;
    pdraw->have_back = 0;
 
+   /* Attempt to test the validity of the buffer array we've been handed. A
+    * zero-valued pitch value should be indicative, but we call memcmp anyway
+    * to try and minimise false-positives. */
+   if (count == 1 && memcmp(buffers, &NullBuffer, sizeof(DRI2Buffer)) == 0) {
+       pdraw->bufferCount = 0;
+       return GL_FALSE;
+   }
+
    /* This assumes the DRI2 buffer attachment tokens matches the
     * __DRIbuffer tokens. */
    for (i = 0; i < count; i++) {
@@ -743,6 +756,7 @@ process_buffers(struct dri2_drawable * pdraw, DRI2Buffer * buffers,
          pdraw->have_back = 1;
    }
 
+   return GL_TRUE;
 }
 
 unsigned dri2GetSwapEventType(Display* dpy, XID drawable)
@@ -873,6 +887,7 @@ dri2GetBuffers(__DRIdrawable * driDrawable,
 {
    struct dri2_drawable *pdraw = loaderPrivate;
    DRI2Buffer *buffers;
+   int buffers_valid;
 
    buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
                             width, height, attachments, count, out_count);
@@ -881,11 +896,11 @@ dri2GetBuffers(__DRIdrawable * driDrawable,
 
    pdraw->width = *width;
    pdraw->height = *height;
-   process_buffers(pdraw, buffers, *out_count);
+   buffers_valid = process_buffers(pdraw, buffers, *out_count);
 
    free(buffers);
 
-   return pdraw->buffers;
+   return buffers_valid ? pdraw->buffers : NULL;
 }
 
 static __DRIbuffer *
@@ -896,6 +911,7 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
 {
    struct dri2_drawable *pdraw = loaderPrivate;
    DRI2Buffer *buffers;
+   int buffers_valid;
 
    buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
                                       pdraw->base.xDrawable,
@@ -906,11 +922,11 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
 
    pdraw->width = *width;
    pdraw->height = *height;
-   process_buffers(pdraw, buffers, *out_count);
+   buffers_valid = process_buffers(pdraw, buffers, *out_count);
 
    free(buffers);
 
-   return pdraw->buffers;
+   return buffers_valid ? pdraw->buffers : NULL;
 }
 
 static int
-- 
2.14.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20171121/bdf00afd/attachment.sig>


More information about the mesa-dev mailing list