egl/dri2: seperate EGLImage validate and lookup
authorQiang Yu <yuq825@gmail.com>
Tue, 10 Aug 2021 06:49:12 +0000 (14:49 +0800)
committerMarge Bot <eric+marge@anholt.net>
Thu, 9 Sep 2021 01:42:39 +0000 (01:42 +0000)
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 <marek.olsak@amd.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12336>

include/GL/internal/dri_interface.h
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h

index 6d98f25..6f436b0 100644 (file)
@@ -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);
 };
 
 /**
index 99b0557..d687533 100644 (file)
@@ -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;
 }
 
+__DRIimage *
+dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
+{
+   (void) screen;
+
+   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, 1 },
+   .base = { __DRI_IMAGE_LOOKUP, 2 },
 
-   .lookupEGLImage       = dri2_lookup_egl_image
+   .lookupEGLImage       = dri2_lookup_egl_image,
+   .validateEGLImage     = dri2_validate_egl_image,
+   .lookupEGLImageValidated = dri2_lookup_egl_image_validated,
 };
 
 struct dri2_extension_match {
index 6a7eede..1f1c338 100644 (file)
@@ -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);