summaryrefslogtreecommitdiffstats
path: root/src/egl/drivers
diff options
context:
space:
mode:
authorDaniel Stone <[email protected]>2017-10-02 16:40:53 +0100
committerDaniel Stone <[email protected]>2017-10-04 15:17:46 +0100
commit6273d2f2693c365ac84e8808577d16698a6ae46a (patch)
treee1e6658b38128fa3bd72018405a3208fd845bf2d /src/egl/drivers
parentd246aa3a0dbbdf0766521392669251eabdd67e79 (diff)
egl/wayland: Check queryImage return for wl_buffer
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 <[email protected]> Reviewed-by: Emil Velikov <[email protected]> Reported-by: Andy Furniss <[email protected]> Cc: Marek Olšák <[email protected]>
Diffstat (limited to 'src/egl/drivers')
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 011dddfabf4..04c04cc304c 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -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);