egl/wayland: Check queryImage return for wl_buffer
authorDaniel Stone <daniels@collabora.com>
Mon, 2 Oct 2017 15:40:53 +0000 (16:40 +0100)
committerDaniel Stone <daniels@collabora.com>
Wed, 4 Oct 2017 14:17:46 +0000 (15:17 +0100)
When creating a wl_buffer from a DRIImage, we extract all the DRIImage
information via queryImage. Check whether or not it actually succeeds,
either bailing out if the query was critical, or providing sensible
fallbacks for information which was not available in older DRIImage
versions.

Fixes: a65db0ad1c ("st/dri: don't expose modifiers in EGL if the driver doesn't implement them")
Fixes: 02cc359372 ("egl/wayland: Use linux-dmabuf interface for buffers")
Signed-off-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Reported-by: Andy Furniss <adf.lists@gmail.com>
Cc: Marek Olšák <marek.olsak@amd.com>
src/egl/drivers/dri2/platform_wayland.c

index 011dddfabf422f30cb6cb62315231897ee047d81..04c04cc304cc4d6edab1342aaabd2f4c2872356e 100644 (file)
@@ -678,23 +678,37 @@ create_wl_buffer(struct dri2_egl_display *dri2_dpy,
                  __DRIimage *image)
 {
    struct wl_buffer *ret;
+   EGLBoolean query;
    int width, height, fourcc, num_planes;
 
-   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width);
-   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height);
-   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FOURCC, &fourcc);
-   dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NUM_PLANES,
-                               &num_planes);
+   query = dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width);
+   query &= dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT,
+                                        &height);
+   query &= dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FOURCC,
+                                        &fourcc);
+   if (!query)
+      return NULL;
+
+   query = dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NUM_PLANES,
+                                       &num_planes);
+   if (!query)
+      num_planes = 1;
 
    if (dri2_dpy->wl_dmabuf && dri2_dpy->image->base.version >= 15) {
       struct zwp_linux_buffer_params_v1 *params;
       int mod_hi, mod_lo;
       int i;
 
-      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER,
-                                  &mod_hi);
-      dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER,
-                                  &mod_lo);
+      query = dri2_dpy->image->queryImage(image,
+                                          __DRI_IMAGE_ATTRIB_MODIFIER_UPPER,
+                                          &mod_hi);
+      query &= dri2_dpy->image->queryImage(image,
+                                           __DRI_IMAGE_ATTRIB_MODIFIER_LOWER,
+                                           &mod_lo);
+      if (!query) {
+         mod_hi = DRM_FORMAT_MOD_INVALID >> 32;
+         mod_lo = DRM_FORMAT_MOD_INVALID & 0xffffffff;
+      }
 
       /* We don't need a wrapper for wl_dmabuf objects, because we have to
        * create the intermediate params object; we can set the queue on this,
@@ -705,7 +719,8 @@ create_wl_buffer(struct dri2_egl_display *dri2_dpy,
 
       for (i = 0; i < num_planes; i++) {
          __DRIimage *p_image;
-         int stride, offset, fd;
+         int stride, offset;
+         int fd = -1;
 
          if (i == 0)
             p_image = image;
@@ -716,14 +731,25 @@ create_wl_buffer(struct dri2_egl_display *dri2_dpy,
             return NULL;
          }
 
-         dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_FD, &fd);
-         dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_STRIDE,
-                                     &stride);
-         dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_OFFSET,
-                                     &offset);
+         query = dri2_dpy->image->queryImage(p_image,
+                                             __DRI_IMAGE_ATTRIB_FD,
+                                             &fd);
+         query &= dri2_dpy->image->queryImage(p_image,
+                                              __DRI_IMAGE_ATTRIB_STRIDE,
+                                              &stride);
+         query &= dri2_dpy->image->queryImage(p_image,
+                                              __DRI_IMAGE_ATTRIB_OFFSET,
+                                              &offset);
          if (image != p_image)
             dri2_dpy->image->destroyImage(p_image);
 
+         if (!query) {
+            if (fd >= 0)
+               close(fd);
+            zwp_linux_buffer_params_v1_destroy(params);
+            return NULL;
+         }
+
          zwp_linux_buffer_params_v1_add(params, fd, i, offset, stride,
                                         mod_hi, mod_lo);
          close(fd);