From dcf38724c74f0784dce919e48dff0f53938e5560 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Tue, 10 Aug 2021 14:49:12 +0800 Subject: [PATCH] egl/dri2: seperate EGLImage validate and lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version 2 of DRIImageLookupExtension add two interface for EGLImage validate and lookup. This is for resolving deak lock in the following commits. Reviewed-by: Marek Olšák Reviewed-by: Emil Velikov Signed-off-by: Qiang Yu Part-of: --- include/GL/internal/dri_interface.h | 24 ++++++++++++++++- src/egl/drivers/dri2/egl_dri2.c | 40 +++++++++++++++++++++-------- src/egl/drivers/dri2/egl_dri2.h | 6 +++++ 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 6d98f2506bb..6f436b00e90 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -1817,14 +1817,36 @@ struct __DRIimageExtensionRec { * with new lookup functions. */ #define __DRI_IMAGE_LOOKUP "DRI_IMAGE_LOOKUP" -#define __DRI_IMAGE_LOOKUP_VERSION 1 +#define __DRI_IMAGE_LOOKUP_VERSION 2 typedef struct __DRIimageLookupExtensionRec __DRIimageLookupExtension; struct __DRIimageLookupExtensionRec { __DRIextension base; + /** + * Lookup EGLImage without validated. Equivalent to call + * validateEGLImage() then lookupEGLImageValidated(). + * + * \since 1 + */ __DRIimage *(*lookupEGLImage)(__DRIscreen *screen, void *image, void *loaderPrivate); + + /** + * Check if EGLImage is associated with the EGL display before lookup with + * lookupEGLImageValidated(). It will hold EGLDisplay.Mutex, so is separated + * out from lookupEGLImage() to avoid deadlock. + * + * \since 2 + */ + GLboolean (*validateEGLImage)(void *image, void *loaderPrivate); + + /** + * Lookup EGLImage after validateEGLImage(). No lock in this function. + * + * \since 2 + */ + __DRIimage *(*lookupEGLImageValidated)(void *image, void *loaderPrivate); }; /** diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 99b05579c71..d687533168b 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -649,33 +649,53 @@ dri2_add_pbuffer_configs_for_visuals(_EGLDisplay *disp) return (config_count != 0); } -__DRIimage * -dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) +GLboolean +dri2_validate_egl_image(void *image, void *data) { _EGLDisplay *disp = data; - struct dri2_egl_image *dri2_img; _EGLImage *img; - (void) screen; - mtx_lock(&disp->Mutex); img = _eglLookupImage(image, disp); mtx_unlock(&disp->Mutex); if (img == NULL) { - _eglError(EGL_BAD_PARAMETER, "dri2_lookup_egl_image"); - return NULL; + _eglError(EGL_BAD_PARAMETER, "dri2_validate_egl_image"); + return false; } + return true; +} + +__DRIimage * +dri2_lookup_egl_image_validated(void *image, void *data) +{ + struct dri2_egl_image *dri2_img; + + (void)data; + dri2_img = dri2_egl_image(image); return dri2_img->dri_image; } -const __DRIimageLookupExtension image_lookup_extension = { - .base = { __DRI_IMAGE_LOOKUP, 1 }, +__DRIimage * +dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) +{ + (void) screen; - .lookupEGLImage = dri2_lookup_egl_image + if (!dri2_validate_egl_image(image, data)) + return NULL; + + return dri2_lookup_egl_image_validated(image, data); +} + +const __DRIimageLookupExtension image_lookup_extension = { + .base = { __DRI_IMAGE_LOOKUP, 2 }, + + .lookupEGLImage = dri2_lookup_egl_image, + .validateEGLImage = dri2_validate_egl_image, + .lookupEGLImageValidated = dri2_lookup_egl_image_validated, }; struct dri2_extension_match { diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 6a7eedea112..1f1c338cdcc 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -421,6 +421,12 @@ dri2_setup_extensions(_EGLDisplay *disp); __DRIdrawable * dri2_surface_get_dri_drawable(_EGLSurface *surf); +GLboolean +dri2_validate_egl_image(void *image, void *data); + +__DRIimage * +dri2_lookup_egl_image_validated(void *image, void *data); + __DRIimage * dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);