This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch devs/cedric/wl/gl-x11-dmabuf
in repository efl.

View the commit online.

commit 7ff334a6e90c218e7f7a097a59ff17e8bba2cc70
Author: Cedric BAIL <[email protected]>
AuthorDate: Thu Aug 13 19:03:58 2026 -0600

    evas/gl: move wl_dmabuf import into gl_common
    
    The previous commit taught gl_x11 to import EVAS_NATIVE_SURFACE_WL_DMABUF
    by copying gl_drm's code. That is the second copy of something that has no
    business being per-engine: a linux dmabuf becomes a texture through
    EGL_EXT_image_dma_buf_import, which is the same call on drm, on X11, and on
    anything else holding an EGLDisplay. The display is the only thing an engine
    contributes.
    
    So it moves to gl_common, which is compiled into gl_generic and reachable
    from every GL engine through the glsym_evas_gl_common_* entry points they
    already use for eglCreateImage. Nothing stood in the way: Native and
    struct dmabuf_attributes are defined once in software_generic and included
    by both engines already, and gl_common has had secsym_glEGLImageTargetTexture2DOES
    since forever.
    
    Four entry points, one per place an engine touches the type:
    
      _dmabuf_supported()       answers eng_image_native_init()
      _dmabuf_test_image_new()  the probe for a caller with attributes but no
                                wl_resource, which is what asks whether such a
                                buffer could be imported at all
      _dmabuf_native_lookup()   has this buffer already been imported
      _dmabuf_native_attach()   take the surface over
    
    bind/unbind/free are private to the new file and installed by _attach(), so
    an engine's own native callbacks never have to know the type exists. gl_drm
    loses 276 lines, gl_x11 needs 62 rather than 225, and an engine that does not
    exist yet gets this by writing four one-liners.
    
    Three bugs fall out on the way.
    
    gl_x11's copy was inert. The extension scan sat behind HAVE_WAYLAND, which
    nothing in the tree ever defines, so dmabuf_present stayed false, every
    import bailed on its first line, and native_init always answered no. It
    compiled, it linked, it did nothing.
    
    gl_x11 also had no probe path: eng_image_native_set() with a NULL image
    answered NULL for every type but OPENGL. That is the call a compositor makes
    before it will advertise zwp_linux_dmabuf_v1, so it would have refused to
    even with the import working.
    
    gl_drm leaked EGLImages. _native_cb_free() gated the destroy on
    ns_data.wl_surface.surface, the wrong arm of the union while the dmabuf arm
    was live, so it was reading overlapping bytes of dmabuf_attributes and
    skipping the destroy whenever they happened to read zero. Its
    eng_image_native_init() also never listed WL_DMABUF at all, so asking about
    a type it has handled for years returned 0 and logged an error, and its
    fallback defines guarded EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT with a typo'd
    name so it redefined an already-defined token. That whole block is dead now
    and goes.
    
    Two things change rather than move. Whether a driver can import, and whether
    it understands explicit modifiers, are properties of the EGLDisplay, so the
    answer is cached against the display it was asked about instead of being a
    static filled in by whichever engine scanned first. And the extension test
    matches whole tokens: asking for EGL_EXT_image_dma_buf_import with strstr
    also matches the _modifiers one, which is harmless here and is the kind of
    harmless that does not stay that way.
    
    drm_import_simple_dmabuf() stays in gl_drm. A scanout framebuffer really is
    ecore_drm2's business.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
    Claude-Session: https://claude.ai/code/session_01FtoiXoSKUmZb6Aix6U3GZS
---
 .../evas/engines/gl_common/evas_gl_common.h        |   8 +
 .../evas/engines/gl_common/evas_gl_native_dmabuf.c | 367 +++++++++++++++++++++
 src/modules/evas/engines/gl_drm/evas_engine.c      | 308 ++---------------
 src/modules/evas/engines/gl_generic/meson.build    |   1 +
 src/modules/evas/engines/gl_x11/evas_engine.c      | 247 +++-----------
 5 files changed, 451 insertions(+), 480 deletions(-)

diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h
index 02bf2dc162..04379b65ac 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -789,6 +789,14 @@ extern void       (*glsym_glRenderbufferStorageMultisample)(GLenum target, GLsiz
 #ifdef GL_GLES
 EMODAPI void *           evas_gl_common_eglCreateImage          (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
 EMODAPI int              evas_gl_common_eglDestroyImage         (EGLDisplay dpy, void *im);
+
+/* EVAS_NATIVE_SURFACE_WL_DMABUF, for any engine holding an EGLDisplay.
+ * See evas_gl_native_dmabuf.c for how the four hook into an engine. */
+EMODAPI int              evas_gl_common_dmabuf_supported        (EGLDisplay dpy);
+EMODAPI Evas_GL_Image *  evas_gl_common_dmabuf_test_image_new   (Evas_Engine_GL_Context *gc, Evas_Native_Surface *ns, EGLDisplay dpy);
+EMODAPI Evas_GL_Image *  evas_gl_common_dmabuf_native_lookup    (Evas_Engine_GL_Context *gc, Evas_GL_Image *im, Evas_Native_Surface *ns);
+EMODAPI Eina_Bool        evas_gl_common_dmabuf_native_attach    (Evas_Engine_GL_Context *gc, Evas_GL_Image *im, Evas_Native_Surface *ns, EGLDisplay dpy);
+
 extern unsigned int   (*eglsym_eglDestroyImage)              (void *a, void *b);
 extern void           (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b);
 extern void          *(*secsym_eglMapImageSEC)               (void *a, void *b, int c, int d);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_native_dmabuf.c b/src/modules/evas/engines/gl_common/evas_gl_native_dmabuf.c
new file mode 100644
index 0000000000..af959924fa
--- /dev/null
+++ b/src/modules/evas/engines/gl_common/evas_gl_native_dmabuf.c
@@ -0,0 +1,367 @@
+/* Import of EVAS_NATIVE_SURFACE_WL_DMABUF buffers, for every GL engine.
+ *
+ * Nothing about a linux dmabuf is platform specific. It becomes a texture
+ * through EGL_EXT_image_dma_buf_import, which is the same call on drm, on
+ * X11, and on anything else holding an EGLDisplay. The only thing an engine
+ * has to supply is that display, so the whole of it lives here rather than
+ * being copied into each engine - including the engines not written yet.
+ *
+ * A platform engine wires this up in four places, all one-liners: answer
+ * eng_image_native_init() with _supported(), make the no-image probe with
+ * _test_image_new(), look for an already imported buffer with
+ * _native_lookup(), and hand the surface over with _native_attach(). The
+ * bind/unbind/free callbacks are installed by _native_attach() and are
+ * private to this file, so an engine's own native callbacks never have to
+ * know the type exists.
+ */
+#include "evas_gl_private.h"
+#include "../software_generic/evas_native_common.h"
+
+#ifdef GL_GLES
+
+/* evas_gl_common.h takes EGL/egl.h but not the extension header, and every
+ * token below EGL_DMA_BUF_PLANE2 comes from there. */
+# include <EGL/eglext.h>
+
+/* The layout of these is fixed ABI, shared with the kernel and with every
+ * other compositor, so defining them when the build's headers are older
+ * than the extension is safe. gl_drm has carried the same list for years. */
+# ifndef DRM_FORMAT_MOD_INVALID
+#  define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
+# endif
+# ifndef EGL_DMA_BUF_PLANE3_FD_EXT
+#  define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440
+# endif
+# ifndef EGL_DMA_BUF_PLANE3_OFFSET_EXT
+#  define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441
+# endif
+# ifndef EGL_DMA_BUF_PLANE3_PITCH_EXT
+#  define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442
+# endif
+# ifndef EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT
+#  define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
+# endif
+# ifndef EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
+#  define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
+# endif
+# ifndef EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT
+#  define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445
+# endif
+# ifndef EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
+#  define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446
+# endif
+# ifndef EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT
+#  define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447
+# endif
+# ifndef EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT
+#  define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448
+# endif
+# ifndef EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT
+#  define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449
+# endif
+# ifndef EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
+#  define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A
+# endif
+
+/* Whether the driver can import at all, and whether it understands explicit
+ * modifiers, are properties of the EGLDisplay. Engines used to each keep
+ * their own copy of the answer, filled in from their own extension scan;
+ * caching it against the display it was asked about means a new engine gets
+ * it for free and an engine with more than one display cannot get it wrong.
+ */
+static EGLDisplay _dmabuf_disp = NULL;
+static Eina_Bool _dmabuf_probed = EINA_FALSE;
+static Eina_Bool _dmabuf_have_import = EINA_FALSE;
+static Eina_Bool _dmabuf_modifiers = EINA_FALSE;
+
+static Eina_Bool
+_dmabuf_probe(EGLDisplay disp)
+{
+   const char *exts;
+
+   if ((_dmabuf_probed) && (_dmabuf_disp == disp)) return _dmabuf_have_import;
+
+   _dmabuf_disp = disp;
+   _dmabuf_probed = EINA_TRUE;
+   _dmabuf_have_import = EINA_FALSE;
+   _dmabuf_modifiers = EINA_FALSE;
+
+   exts = eglQueryString(disp, EGL_EXTENSIONS);
+   if (!exts) return EINA_FALSE;
+
+   /* Whole-token matching: a plain strstr for the base extension also
+    * matches the _modifiers one, which happens to be harmless here but is
+    * the sort of thing that is only harmless until it isn't. */
+   _dmabuf_have_import =
+     evas_gl_extension_string_check(exts, "EGL_EXT_image_dma_buf_import");
+   _dmabuf_modifiers =
+     evas_gl_extension_string_check(exts,
+                                    "EGL_EXT_image_dma_buf_import_modifiers");
+
+   return _dmabuf_have_import;
+}
+
+/* Code from weston's gl-renderer, by way of the gl_drm engine. */
+static void *
+_dmabuf_import_attempt(EGLDisplay disp, struct dmabuf_attributes *attr, Eina_Bool with_modifier)
+{
+   static const EGLint fd_attr[4] =
+     { EGL_DMA_BUF_PLANE0_FD_EXT, EGL_DMA_BUF_PLANE1_FD_EXT,
+       EGL_DMA_BUF_PLANE2_FD_EXT, EGL_DMA_BUF_PLANE3_FD_EXT };
+   static const EGLint off_attr[4] =
+     { EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGL_DMA_BUF_PLANE1_OFFSET_EXT,
+       EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGL_DMA_BUF_PLANE3_OFFSET_EXT };
+   static const EGLint pitch_attr[4] =
+     { EGL_DMA_BUF_PLANE0_PITCH_EXT, EGL_DMA_BUF_PLANE1_PITCH_EXT,
+       EGL_DMA_BUF_PLANE2_PITCH_EXT, EGL_DMA_BUF_PLANE3_PITCH_EXT };
+   static const EGLint mod_lo_attr[4] =
+     { EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
+       EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT };
+   static const EGLint mod_hi_attr[4] =
+     { EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
+       EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT };
+   EGLAttrib attribs[6 + 4 * 10 + 1];
+   Eina_Bool has_modifier = EINA_FALSE;
+   int atti = 0, i;
+
+   /* Passing modifier attributes to a driver without
+    * EGL_EXT_image_dma_buf_import_modifiers gets the whole import rejected
+    * with EGL_BAD_ATTRIBUTE, which surfaces as a silently black window.
+    * Only send them when the driver actually understands them; otherwise
+    * fall back to letting it work the layout out implicitly. */
+   if ((with_modifier) && (_dmabuf_modifiers) &&
+       (attr->modifier[0] != DRM_FORMAT_MOD_INVALID))
+     has_modifier = EINA_TRUE;
+
+   attribs[atti++] = EGL_WIDTH;
+   attribs[atti++] = attr->width;
+   attribs[atti++] = EGL_HEIGHT;
+   attribs[atti++] = attr->height;
+   attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
+   attribs[atti++] = attr->format;
+
+   for (i = 0; (i < attr->n_planes) && (i < 4); i++)
+     {
+        attribs[atti++] = fd_attr[i];
+        attribs[atti++] = attr->fd[i];
+        attribs[atti++] = off_attr[i];
+        attribs[atti++] = attr->offset[i];
+        attribs[atti++] = pitch_attr[i];
+        attribs[atti++] = attr->stride[i];
+        if (has_modifier)
+          {
+             attribs[atti++] = mod_lo_attr[i];
+             attribs[atti++] = attr->modifier[i] & 0xFFFFFFFF;
+             attribs[atti++] = mod_hi_attr[i];
+             attribs[atti++] = attr->modifier[i] >> 32;
+          }
+     }
+
+   attribs[atti++] = EGL_NONE;
+
+   /* This requires the Mesa commit in
+    * Mesa 10.3 (08264e5dad4df448e7718e782ad9077902089a07) or
+    * Mesa 10.2.7 (55d28925e6109a4afd61f109e845a8a51bd17652).
+    * Otherwise Mesa closes the fd behind our back and re-importing
+    * will fail.
+    * https://bugs.freedesktop.org/show_bug.cgi?id=76188
+    */
+   return evas_gl_common_eglCreateImage(disp, EGL_NO_CONTEXT,
+                                        EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
+}
+
+static void *
+_dmabuf_import(EGLDisplay disp, struct dmabuf_attributes *attr)
+{
+   void *img;
+
+   if (!attr) return NULL;
+   if (attr->version != EVAS_DMABUF_ATTRIBUTE_VERSION) return NULL;
+   if (!_dmabuf_probe(disp)) return NULL;
+
+   img = _dmabuf_import_attempt(disp, attr, EINA_TRUE);
+   if (img) return img;
+
+   /* The explicit layout was refused - a driver may advertise
+    * import_modifiers and still reject a particular modifier. Retry
+    * implicitly before giving up and rendering nothing. */
+   if ((_dmabuf_modifiers) && (attr->modifier[0] != DRM_FORMAT_MOD_INVALID))
+     {
+        DBG("dmabuf import with modifier %#" PRIx64 " failed (%#x), "
+            "retrying without", attr->modifier[0], eglGetError());
+        img = _dmabuf_import_attempt(disp, attr, EINA_FALSE);
+     }
+
+   return img;
+}
+
+static void
+_dmabuf_native_bind_cb(void *image)
+{
+   Evas_GL_Image *im = image;
+   Native *n;
+
+   if (!im) return;
+   if (!(n = im->native.data)) return;
+
+   /* Must re-import every time for coherency. */
+   if (n->ns_data.wl_surface_dmabuf.image)
+     evas_gl_common_eglDestroyImage(im->native.disp,
+                                    n->ns_data.wl_surface_dmabuf.image);
+   n->ns_data.wl_surface_dmabuf.image =
+     _dmabuf_import(im->native.disp, &n->ns_data.wl_surface_dmabuf.attr);
+   if (!n->ns_data.wl_surface_dmabuf.image)
+     {
+        im->native.invalid = EINA_TRUE;
+        return;
+     }
+   im->native.invalid = EINA_FALSE;
+   if (secsym_glEGLImageTargetTexture2DOES)
+     secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
+                                         n->ns_data.wl_surface_dmabuf.image);
+}
+
+static void
+_dmabuf_native_unbind_cb(void *image)
+{
+   Evas_GL_Image *im = image;
+   Native *n;
+
+   if (!im) return;
+   if (!(n = im->native.data)) return;
+
+   if (n->ns_data.wl_surface_dmabuf.image)
+     {
+        evas_gl_common_eglDestroyImage(im->native.disp,
+                                       n->ns_data.wl_surface_dmabuf.image);
+        n->ns_data.wl_surface_dmabuf.image = NULL;
+     }
+}
+
+static void
+_dmabuf_native_free_cb(void *image)
+{
+   Evas_GL_Image *im = image;
+   Native *n;
+   void *key;
+
+   if (!im) return;
+   if (!(n = im->native.data)) return;
+
+   if (im->native.shared)
+     {
+        key = n->ns_data.wl_surface_dmabuf.resource;
+        eina_hash_del(im->native.shared->native_wl_hash, &key, im);
+     }
+   if (n->ns_data.wl_surface_dmabuf.image)
+     {
+        evas_gl_common_eglDestroyImage(im->native.disp,
+                                       n->ns_data.wl_surface_dmabuf.image);
+        GLERRV("eglDestroyImage() failed.");
+        n->ns_data.wl_surface_dmabuf.image = NULL;
+     }
+   im->native.data = ""
+   im->native.func.bind = NULL;
+   im->native.func.unbind = NULL;
+   im->native.func.free = NULL;
+   free(n);
+}
+
+/* Can this display take a dmabuf at all? Answering honestly lets a
+ * compositor fall back to shared memory rather than be handed buffers it
+ * would only ever render black. */
+EMODAPI int
+evas_gl_common_dmabuf_supported(EGLDisplay disp)
+{
+   if (!_dmabuf_probe(disp)) return 0;
+   if (!secsym_glEGLImageTargetTexture2DOES) return 0;
+   return 1;
+}
+
+/* The buffer-less probe: a caller with attributes but no wl_resource is
+ * asking whether such a buffer could be imported, not asking to keep one.
+ * Import it, throw it away, and answer with an image of the right size.
+ * This is the path e_pixmap_dmabuf_test() takes before a compositor will
+ * advertise zwp_linux_dmabuf_v1 at all. */
+EMODAPI Evas_GL_Image *
+evas_gl_common_dmabuf_test_image_new(Evas_Engine_GL_Context *gc, Evas_Native_Surface *ns, EGLDisplay disp)
+{
+   struct dmabuf_attributes *attr;
+   void *img;
+
+   if ((!gc) || (!ns)) return NULL;
+   attr = ns->data.wl_dmabuf.attr;
+   if (!attr) return NULL;
+
+   img = _dmabuf_import(disp, attr);
+   if (!img) return NULL;
+   evas_gl_common_eglDestroyImage(disp, img);
+
+   return evas_gl_common_image_new_from_data(gc, attr->width, attr->height,
+                                             NULL, 1, EVAS_COLORSPACE_ARGB8888);
+}
+
+/* Has this wl_buffer already been imported? If so the caller is done: the
+ * returned image is refed and the one passed in has been dropped. */
+EMODAPI Evas_GL_Image *
+evas_gl_common_dmabuf_native_lookup(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, Evas_Native_Surface *ns)
+{
+   Evas_GL_Image *im2;
+   void *key;
+
+   if ((!gc) || (!ns)) return NULL;
+   key = ns->data.wl_dmabuf.resource;
+
+   im2 = eina_hash_find(gc->shared->native_wl_hash, &key);
+   if (!im2) return NULL;
+   if (im2 == im) return im;
+   if (!im2->native.data) return NULL;
+
+   evas_gl_common_image_ref(im2);
+   evas_gl_common_image_free(im);
+
+   return im2;
+}
+
+/* Take the surface over: allocate the Native, remember the buffer, and put
+ * this file's callbacks on the image. Answers EINA_FALSE without touching
+ * the image if the attributes cannot be used. */
+EMODAPI Eina_Bool
+evas_gl_common_dmabuf_native_attach(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, Evas_Native_Surface *ns, EGLDisplay disp)
+{
+   struct dmabuf_attributes *attr;
+   Native *n;
+   void *key;
+
+   if ((!gc) || (!im) || (!ns)) return EINA_FALSE;
+   attr = ns->data.wl_dmabuf.attr;
+   if (!attr) return EINA_FALSE;
+   if (attr->version != EVAS_DMABUF_ATTRIBUTE_VERSION) return EINA_FALSE;
+
+   n = calloc(1, sizeof(Native));
+   if (!n) return EINA_FALSE;
+
+   memcpy(&n->ns, ns, sizeof(Evas_Native_Surface));
+   memcpy(&n->ns_data.wl_surface_dmabuf.attr, attr, sizeof(*attr));
+   n->ns_data.wl_surface_dmabuf.resource = ns->data.wl_dmabuf.resource;
+
+   key = n->ns_data.wl_surface_dmabuf.resource;
+   eina_hash_add(gc->shared->native_wl_hash, &key, im);
+
+   im->native.yinvert = 1;
+   im->native.loose = 0;
+   im->native.disp = disp;
+   im->native.shared = gc->shared;
+   im->native.data = ""
+   im->native.func.bind = _dmabuf_native_bind_cb;
+   im->native.func.unbind = _dmabuf_native_unbind_cb;
+   im->native.func.free = _dmabuf_native_free_cb;
+   im->native.target = GL_TEXTURE_2D;
+   im->native.mipmap = 0;
+
+   evas_gl_common_image_native_enable(im);
+
+   return EINA_TRUE;
+}
+
+#endif
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c
index 8cef64837e..eb2d92baeb 100644
--- a/src/modules/evas/engines/gl_drm/evas_engine.c
+++ b/src/modules/evas/engines/gl_drm/evas_engine.c
@@ -14,47 +14,6 @@
 
 #define EVAS_GL_UPDATE_TILE_SIZE 16
 
-#ifndef DRM_FORMAT_MOD_LINEAR
-# define DRM_FORMAT_MOD_LINEAR 0
-#endif
-#ifndef DRM_FORMAT_MOD_INVALID
-# define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
-#endif
-
-#ifndef EGL_DMA_BUF_PLANE3_FD_EXT
-# define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440
-#endif
-#ifndef EGL_DMA_BUF_PLANE3_OFFSET_EXT
-# define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441
-#endif
-#ifndef EGL_DMA_BUF_PLANE3_PITCH_EXT
-# define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442
-#endif
-#ifndef EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT
-# define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
-#endif
-#ifndef EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
-# define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
-#endif
-#ifndef EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT
-# define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445
-#endif
-#ifndef EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
-# define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446
-#endif
-#ifndef EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT
-# define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447
-#endif
-#ifndef EGL_DMA_BUF_PLANE2_MODIFIER_HIa_EXT
-# define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448
-#endif
-#ifndef EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT
-# define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449
-#endif
-#ifndef EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
-# define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A
-#endif
-
 struct scanout_handle
 {
    Evas_Native_Scanout_Handler handler;
@@ -68,8 +27,6 @@ int _extn_have_context_priority = 0;
 
 /* local variables */
 static Eina_Bool initted = EINA_FALSE;
-static Eina_Bool dmabuf_present = EINA_FALSE;
-static Eina_Bool dmabuf_modifiers_present = EINA_FALSE;
 static int gl_wins = 0;
 static struct gbm_device *gbm_dev = NULL;
 static int gbm_dev_refs = 0;
@@ -110,6 +67,10 @@ glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL;
 void *(*glsym_eglGetProcAddress)(const char *a) = NULL;
 EGLImageKHR  (*glsym_evas_gl_common_eglCreateImage) (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const EGLAttrib *e) = NULL;
 int          (*glsym_evas_gl_common_eglDestroyImage) (EGLDisplay a, void *b) = NULL;
+int            (*glsym_evas_gl_common_dmabuf_supported)      (EGLDisplay a) = NULL;
+Evas_GL_Image *(*glsym_evas_gl_common_dmabuf_test_image_new) (Evas_Engine_GL_Context *a, Evas_Native_Surface *b, EGLDisplay c) = NULL;
+Evas_GL_Image *(*glsym_evas_gl_common_dmabuf_native_lookup)  (Evas_Engine_GL_Context *a, Evas_GL_Image *b, Evas_Native_Surface *c) = NULL;
+Eina_Bool      (*glsym_evas_gl_common_dmabuf_native_attach)  (Evas_Engine_GL_Context *a, Evas_GL_Image *b, Evas_Native_Surface *c, EGLDisplay d) = NULL;
 void (*glsym_glEGLImageTargetTexture2DOES)(int a, void *b) = NULL;
 unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
 unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, void *b, EGLint c, EGLint *d) = NULL;
@@ -237,6 +198,10 @@ symbols(void)
    LINK2GENERIC(eglGetProcAddress);
    LINK2GENERIC(evas_gl_common_eglCreateImage);
    LINK2GENERIC(evas_gl_common_eglDestroyImage);
+   LINK2GENERIC(evas_gl_common_dmabuf_supported);
+   LINK2GENERIC(evas_gl_common_dmabuf_test_image_new);
+   LINK2GENERIC(evas_gl_common_dmabuf_native_lookup);
+   LINK2GENERIC(evas_gl_common_dmabuf_native_attach);
    LINK2GENERIC(evas_gl_extension_string_check);
 
    _ckext = glsym_evas_gl_extension_string_check;
@@ -302,10 +267,6 @@ gl_extn_veto(Render_Engine *re)
         if ((!_ckext(str, "EGL_EXT_swap_buffers_with_damage")) &&
             (!_ckext(str, "EGL_KHR_swap_buffers_with_damage")))
           glsym_eglSwapBuffersWithDamage = NULL;
-        if (_ckext(str, "EGL_EXT_image_dma_buf_import"))
-          dmabuf_present = EINA_TRUE;
-        if (_ckext(str, "EGL_EXT_image_dma_buf_import_modifiers"))
-          dmabuf_modifiers_present = EINA_TRUE;
      }
    else
      {
@@ -673,137 +634,6 @@ drm_import_simple_dmabuf(Ecore_Drm2_Device *dev, struct dmabuf_attributes *attri
                                       dmabuf_fd, attributes->n_planes);
 }
 
-/* Code from weston's gl-renderer... */
-static EGLImageKHR
-_gl_import_dmabuf(EGLDisplay display, struct dmabuf_attributes *attributes, Eina_Bool with_modifier)
-{
-   EGLAttrib attribs[50];
-   int atti = 0;
-   Eina_Bool has_modifier = EINA_FALSE;
-
-   if (!dmabuf_present) return NULL;
-   if (!glsym_evas_gl_common_eglDestroyImage) return NULL;
-
-   /* This requires the Mesa commit in
-    * Mesa 10.3 (08264e5dad4df448e7718e782ad9077902089a07) or
-    * Mesa 10.2.7 (55d28925e6109a4afd61f109e845a8a51bd17652).
-    * Otherwise Mesa closes the fd behind our back and re-importing
-    * will fail.
-    * https://bugs.freedesktop.org/show_bug.cgi?id=76188
-    */
-
-   attribs[atti++] = EGL_WIDTH;
-   attribs[atti++] = attributes->width;
-   attribs[atti++] = EGL_HEIGHT;
-   attribs[atti++] = attributes->height;
-   attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
-   attribs[atti++] = attributes->format;
-   /* Passing the modifier attributes to a driver without
-    * EGL_EXT_image_dma_buf_import_modifiers gets the whole import rejected
-    * with EGL_BAD_ATTRIBUTE, which surfaces as a silently black window.
-    * Only send them when the driver actually understands them; otherwise
-    * fall back to letting it work the layout out implicitly. */
-   if ((with_modifier) && (dmabuf_modifiers_present) &&
-       (attributes->modifier[0] != DRM_FORMAT_MOD_INVALID))
-     has_modifier = EINA_TRUE;
-
-   if (attributes->n_planes > 0)
-     {
-        attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
-        attribs[atti++] = attributes->fd[0];
-        attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
-        attribs[atti++] = attributes->offset[0];
-        attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
-        attribs[atti++] = attributes->stride[0];
-        if (has_modifier)
-          {
-             attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
-             attribs[atti++] = attributes->modifier[0] & 0xFFFFFFFF;
-             attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
-             attribs[atti++] = attributes->modifier[0] >> 32;
-          }
-     }
-
-   if (attributes->n_planes > 1)
-     {
-        attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
-        attribs[atti++] = attributes->fd[1];
-        attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
-        attribs[atti++] = attributes->offset[1];
-        attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
-        attribs[atti++] = attributes->stride[1];
-        if (has_modifier)
-          {
-             attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
-             attribs[atti++] = attributes->modifier[1] & 0xFFFFFFFF;
-             attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
-             attribs[atti++] = attributes->modifier[1] >> 32;
-          }
-     }
-
-   if (attributes->n_planes > 2)
-     {
-        attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
-        attribs[atti++] = attributes->fd[2];
-        attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
-        attribs[atti++] = attributes->offset[2];
-        attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
-        attribs[atti++] = attributes->stride[2];
-        if (has_modifier)
-          {
-             attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
-             attribs[atti++] = attributes->modifier[2] & 0xFFFFFFFF;
-             attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
-             attribs[atti++] = attributes->modifier[2] >> 32;
-          }
-     }
-
-   if (attributes->n_planes > 3)
-     {
-        attribs[atti++] = EGL_DMA_BUF_PLANE3_FD_EXT;
-        attribs[atti++] = attributes->fd[3];
-        attribs[atti++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
-        attribs[atti++] = attributes->offset[3];
-        attribs[atti++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
-        attribs[atti++] = attributes->stride[3];
-        if (has_modifier)
-          {
-             attribs[atti++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
-             attribs[atti++] = attributes->modifier[3] & 0xFFFFFFFF;
-             attribs[atti++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
-             attribs[atti++] = attributes->modifier[3] >> 32;
-          }
-     }
-
-   attribs[atti++] = EGL_NONE;
-
-   return glsym_evas_gl_common_eglCreateImage(display, EGL_NO_CONTEXT,
-                                              EGL_LINUX_DMA_BUF_EXT,
-                                              NULL, attribs);
-}
-
-static EGLImageKHR
-gl_import_simple_dmabuf(EGLDisplay display, struct dmabuf_attributes *attributes)
-{
-   EGLImageKHR img;
-
-   img = _gl_import_dmabuf(display, attributes, EINA_TRUE);
-   if (img) return img;
-
-   /* The explicit layout was refused - a driver may advertise
-    * import_modifiers and still reject a particular modifier.  Retry
-    * implicitly before giving up and rendering nothing. */
-   if ((dmabuf_modifiers_present) &&
-       (attributes->modifier[0] != DRM_FORMAT_MOD_INVALID))
-     {
-        DBG("dmabuf import with modifier %#" PRIx64 " failed (%#x), "
-            "retrying without", attributes->modifier[0], eglGetError());
-        img = _gl_import_dmabuf(display, attributes, EINA_FALSE);
-     }
-
-   return img;
-}
-
 static void
 _native_cb_bind(void *image)
 {
@@ -813,21 +643,7 @@ _native_cb_bind(void *image)
    if (!(img = image)) return;
    if (!(n = img->native.data)) return;
 
-   if (n->ns.type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-     {
-        /* Must re-import every time for coherency. */
-        if (n->ns_data.wl_surface_dmabuf.image)
-          glsym_evas_gl_common_eglDestroyImage(img->native.disp, n->ns_data.wl_surface_dmabuf.image);
-        n->ns_data.wl_surface_dmabuf.image = gl_import_simple_dmabuf(img->native.disp, &n->ns_data.wl_surface_dmabuf.attr);
-        if (!n->ns_data.wl_surface_dmabuf.image)
-          {
-             img->native.invalid = EINA_TRUE;
-             return;
-          }
-        img->native.invalid = EINA_FALSE;
-        glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->ns_data.wl_surface_dmabuf.image);
-     }
-   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
+   if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
      {
         if (n->ns_data.wl_surface.surface)
           {
@@ -855,15 +671,7 @@ _native_cb_unbind(void *image)
    if (!(img = image)) return;
    if (!(n = img->native.data)) return;
 
-   if (n->ns.type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-     {
-        if (n->ns_data.wl_surface_dmabuf.image)
-          {
-             glsym_evas_gl_common_eglDestroyImage(img->native.disp, n->ns_data.wl_surface_dmabuf.image);
-             n->ns_data.wl_surface_dmabuf.image = NULL;
-          }
-     }
-   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
+   if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
      {
         //glBindTexture(GL_TEXTURE_2D, 0); //really need?
      }
@@ -973,20 +781,7 @@ _native_cb_free(void *image)
    if (!(n = img->native.data)) return;
    if (!(img->native.shared)) return;
 
-   if (n->ns.type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-     {
-        wlid = n->ns_data.wl_surface_dmabuf.resource;
-        eina_hash_del(img->native.shared->native_wl_hash, &wlid, img);
-        if (n->ns_data.wl_surface.surface)
-          {
-             if (glsym_evas_gl_common_eglDestroyImage && n->ns_data.wl_surface_dmabuf.image)
-               {
-                  glsym_evas_gl_common_eglDestroyImage(img->native.disp, n->ns_data.wl_surface_dmabuf.image);
-                  GLERRV("eglDestroyImage() failed.");
-               }
-          }
-     }
-   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
+   if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
      {
         wlid = (void*)n->ns_data.wl_surface.wl_buf;
         eina_hash_del(img->native.shared->native_wl_hash, &wlid, img);
@@ -1210,13 +1005,20 @@ eng_output_dump(void *engine, void *data)
 }
 
 static int
-eng_image_native_init(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
+eng_image_native_init(void *engine, Evas_Native_Surface_Type type)
 {
    switch (type)
      {
       case EVAS_NATIVE_SURFACE_OPENGL:
       case EVAS_NATIVE_SURFACE_WL:
         return 1;
+      case EVAS_NATIVE_SURFACE_WL_DMABUF:
+        {
+           Outbuf *ob = eng_get_ob((Render_Engine *)engine);
+
+           if ((!ob) || (!glsym_evas_gl_common_dmabuf_supported)) return 0;
+           return glsym_evas_gl_common_dmabuf_supported(ob->egl.disp);
+        }
       default:
         ERR("Native surface type %d not supported!", type);
         return 0;
@@ -1230,6 +1032,7 @@ eng_image_native_shutdown(void *engine EINA_UNUSED, Evas_Native_Surface_Type typ
      {
       case EVAS_NATIVE_SURFACE_OPENGL:
       case EVAS_NATIVE_SURFACE_WL:
+      case EVAS_NATIVE_SURFACE_WL_DMABUF:
         return;
       default:
         ERR("Native surface type %d not supported!", type);
@@ -1264,27 +1067,12 @@ eng_image_native_set(void *engine, void *image, void *native)
                                                         NULL, 1,
                                                         EVAS_COLORSPACE_ARGB8888);
           }
-        else if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF))
+        else if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF) &&
+                 (!ns->data.wl_dmabuf.resource) &&
+                 (glsym_evas_gl_common_dmabuf_test_image_new))
           {
-             if (!ns->data.wl_dmabuf.resource)
-               {
-                  struct dmabuf_attributes *attr;
-                  void *v = NULL;
-
-                  attr = ns->data.wl_dmabuf.attr;
-                  if (attr->version == EVAS_DMABUF_ATTRIBUTE_VERSION)
-                    v = gl_import_simple_dmabuf(ob->egl.disp, attr);
-                  if (!v) return NULL;
-
-                  glsym_evas_gl_common_eglDestroyImage(ob->egl.disp, v);
-                  img =
-                    glsym_evas_gl_common_image_new_from_data(ob->gl_context,
-                                                             attr->width,
-                                                             attr->height,
-                                                             NULL, 1,
-                                                             EVAS_COLORSPACE_ARGB8888);
-                  return img;
-               }
+             return glsym_evas_gl_common_dmabuf_test_image_new(ob->gl_context,
+                                                              ns, ob->egl.disp);
           }
         else
           return NULL;
@@ -1334,17 +1122,11 @@ eng_image_native_set(void *engine, void *image, void *native)
 
    if (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF)
      {
-        wlid = wl_buf;
-        img2 = eina_hash_find(ob->gl_context->shared->native_wl_hash, &wlid);
-        if (img2 == img) return img;
-        if (img2)
+        if (glsym_evas_gl_common_dmabuf_native_lookup)
           {
-             if((n = img2->native.data))
-               {
-                  glsym_evas_gl_common_image_ref(img2);
-                  glsym_evas_gl_common_image_free(img);
-                  return img2;
-               }
+             img2 = glsym_evas_gl_common_dmabuf_native_lookup(ob->gl_context,
+                                                             img, ns);
+             if (img2) return img2;
           }
      }
    else if (ns->type == EVAS_NATIVE_SURFACE_WL)
@@ -1390,38 +1172,14 @@ eng_image_native_set(void *engine, void *image, void *native)
      {
         if (native)
           {
-             struct dmabuf_attributes *a;
-
-             a = ns->data.wl_dmabuf.attr;
-             if (a->version != EVAS_DMABUF_ATTRIBUTE_VERSION)
+             if ((!glsym_evas_gl_common_dmabuf_native_attach) ||
+                 (!glsym_evas_gl_common_dmabuf_native_attach(ob->gl_context,
+                                                             img, ns,
+                                                             ob->egl.disp)))
                {
                   glsym_evas_gl_common_image_free(img);
                   return NULL;
                }
-             if ((n = calloc(1, sizeof(Native))))
-               {
-                  struct dmabuf_attributes *a2;
-
-                  a2 = ns->data.wl_dmabuf.attr;
-                  memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
-                  memcpy(&n->ns_data.wl_surface_dmabuf.attr, a2, sizeof(*a2));
-                  eina_hash_add(ob->gl_context->shared->native_wl_hash,
-                                &wlid, img);
-
-                  n->ns_data.wl_surface_dmabuf.resource = wl_buf;
-                  img->native.yinvert = 1;
-                  img->native.loose = 0;
-                  img->native.disp = ob->egl.disp;
-                  img->native.shared = ob->gl_context->shared;
-                  img->native.data = ""
-                  img->native.func.bind = _native_cb_bind;
-                  img->native.func.unbind = _native_cb_unbind;
-                  img->native.func.free = _native_cb_free;
-                  img->native.target = GL_TEXTURE_2D;
-                  img->native.mipmap = 0;
-
-                  glsym_evas_gl_common_image_native_enable(img);
-               }
           }
      }
    else if (ns->type == EVAS_NATIVE_SURFACE_WL)
diff --git a/src/modules/evas/engines/gl_generic/meson.build b/src/modules/evas/engines/gl_generic/meson.build
index 0464ea43a8..a065b23f48 100644
--- a/src/modules/evas/engines/gl_generic/meson.build
+++ b/src/modules/evas/engines/gl_generic/meson.build
@@ -20,6 +20,7 @@ common_engine_src = [
   'evas_gl_common.h',
   'evas_gl_define.h',
   'evas_gl_context.c',
+  'evas_gl_native_dmabuf.c',
   'evas_gl_file_cache.c',
   'evas_gl_shader.c',
   'evas_gl_rectangle.c',
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c
index f4e3332596..0761594849 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -31,18 +31,6 @@ static int initted = 0;
 static int gl_wins = 0;
 #ifdef GL_GLES
 static int extn_have_y_inverted = 1;
-#ifdef GL_GLES
-# ifdef HAVE_DRM_FOURCC_H
-#  include <drm_fourcc.h>
-# endif
-# ifndef DRM_FORMAT_MOD_INVALID
-#  define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
-# endif
-/* EGL_EXT_image_dma_buf_import and its modifiers companion. Checked once in
- * gl_extn_veto(); a driver can have the first without the second. */
-static Eina_Bool dmabuf_present = EINA_FALSE;
-static Eina_Bool dmabuf_modifiers_present = EINA_FALSE;
-#endif
 #endif
 
 typedef void           *(*glsym_func_void_ptr) (void);
@@ -88,6 +76,10 @@ glsym_func_void_ptr      glsym_evas_gl_common_current_context_get = NULL;
 void        *(*glsym_eglGetProcAddress)            (const char *a) = NULL;
 EGLImageKHR  (*glsym_evas_gl_common_eglCreateImage)(EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const EGLAttrib *e) = NULL;
 int          (*glsym_evas_gl_common_eglDestroyImage) (EGLDisplay a, void *b) = NULL;
+int            (*glsym_evas_gl_common_dmabuf_supported)      (EGLDisplay a) = NULL;
+Evas_GL_Image *(*glsym_evas_gl_common_dmabuf_test_image_new) (Evas_Engine_GL_Context *a, Evas_Native_Surface *b, EGLDisplay c) = NULL;
+Evas_GL_Image *(*glsym_evas_gl_common_dmabuf_native_lookup)  (Evas_Engine_GL_Context *a, Evas_GL_Image *b, Evas_Native_Surface *c) = NULL;
+Eina_Bool      (*glsym_evas_gl_common_dmabuf_native_attach)  (Evas_Engine_GL_Context *a, Evas_GL_Image *b, Evas_Native_Surface *c, EGLDisplay d) = NULL;
 void         (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b)  = NULL;
 unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
 unsigned int (*glsym_eglSetDamageRegionKHR)  (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
@@ -1374,6 +1366,10 @@ eng_gl_symbols(Outbuf *ob)
 
    LINK2GENERIC(evas_gl_common_eglCreateImage);
    LINK2GENERIC(evas_gl_common_eglDestroyImage);
+   LINK2GENERIC(evas_gl_common_dmabuf_supported);
+   LINK2GENERIC(evas_gl_common_dmabuf_test_image_new);
+   LINK2GENERIC(evas_gl_common_dmabuf_native_lookup);
+   LINK2GENERIC(evas_gl_common_dmabuf_native_attach);
 
    FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", NULL);
    FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", "EGL_EXT_swap_buffers_with_damage");
@@ -1463,12 +1459,6 @@ gl_extn_veto(Render_Engine *re)
           {
              glsym_eglSetDamageRegionKHR = NULL;
           }
-#ifdef HAVE_WAYLAND
-        if (strstr(str, "EGL_EXT_image_dma_buf_import"))
-          dmabuf_present = EINA_TRUE;
-        if (strstr(str, "EGL_EXT_image_dma_buf_import_modifiers"))
-          dmabuf_modifiers_present = EINA_TRUE;
-#endif
         if (!strstr(str, "EGL_NOK_texture_from_pixmap"))
           {
              extn_have_y_inverted = 0;
@@ -1946,123 +1936,12 @@ end:
 //
 //#define GLX_TEX_PIXMAP_RECREATE 1
 
-#ifdef GL_GLES
-/* Code from weston's gl-renderer, by way of the gl_drm engine. */
-static EGLImageKHR
-_gl_import_dmabuf(EGLDisplay display, struct dmabuf_attributes *attributes, Eina_Bool with_modifier)
-{
-   EGLAttrib attribs[50];
-   int atti = 0, i;
-   Eina_Bool has_modifier = EINA_FALSE;
-   static const EGLint fd_attr[4] =
-     { EGL_DMA_BUF_PLANE0_FD_EXT, EGL_DMA_BUF_PLANE1_FD_EXT,
-       EGL_DMA_BUF_PLANE2_FD_EXT, EGL_DMA_BUF_PLANE3_FD_EXT };
-   static const EGLint off_attr[4] =
-     { EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGL_DMA_BUF_PLANE1_OFFSET_EXT,
-       EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGL_DMA_BUF_PLANE3_OFFSET_EXT };
-   static const EGLint pitch_attr[4] =
-     { EGL_DMA_BUF_PLANE0_PITCH_EXT, EGL_DMA_BUF_PLANE1_PITCH_EXT,
-       EGL_DMA_BUF_PLANE2_PITCH_EXT, EGL_DMA_BUF_PLANE3_PITCH_EXT };
-   static const EGLint mod_lo_attr[4] =
-     { EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
-       EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT };
-   static const EGLint mod_hi_attr[4] =
-     { EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
-       EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT, EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT };
-
-   if (!dmabuf_present) return NULL;
-   if (!glsym_evas_gl_common_eglCreateImage) return NULL;
-   if (!glsym_evas_gl_common_eglDestroyImage) return NULL;
-
-   /* Passing modifier attributes to a driver without
-    * EGL_EXT_image_dma_buf_import_modifiers gets the whole import rejected
-    * with EGL_BAD_ATTRIBUTE, which surfaces as a silently black window. */
-   if ((with_modifier) && (dmabuf_modifiers_present) &&
-       (attributes->modifier[0] != DRM_FORMAT_MOD_INVALID))
-     has_modifier = EINA_TRUE;
-
-   attribs[atti++] = EGL_WIDTH;
-   attribs[atti++] = attributes->width;
-   attribs[atti++] = EGL_HEIGHT;
-   attribs[atti++] = attributes->height;
-   attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
-   attribs[atti++] = attributes->format;
-
-   for (i = 0; (i < attributes->n_planes) && (i < 4); i++)
-     {
-        attribs[atti++] = fd_attr[i];
-        attribs[atti++] = attributes->fd[i];
-        attribs[atti++] = off_attr[i];
-        attribs[atti++] = attributes->offset[i];
-        attribs[atti++] = pitch_attr[i];
-        attribs[atti++] = attributes->stride[i];
-        if (has_modifier)
-          {
-             attribs[atti++] = mod_lo_attr[i];
-             attribs[atti++] = attributes->modifier[i] & 0xFFFFFFFF;
-             attribs[atti++] = mod_hi_attr[i];
-             attribs[atti++] = attributes->modifier[i] >> 32;
-          }
-     }
-
-   attribs[atti++] = EGL_NONE;
-
-   return glsym_evas_gl_common_eglCreateImage(display, EGL_NO_CONTEXT,
-                                              EGL_LINUX_DMA_BUF_EXT,
-                                              NULL, attribs);
-}
-
-static EGLImageKHR
-_gl_import_simple_dmabuf(EGLDisplay display, struct dmabuf_attributes *attributes)
-{
-   EGLImageKHR img;
-
-   img = _gl_import_dmabuf(display, attributes, EINA_TRUE);
-   if (img) return img;
-
-   /* The explicit layout was refused - a driver may advertise
-    * import_modifiers and still reject a particular modifier. Retry
-    * implicitly before giving up and rendering nothing. */
-   if ((dmabuf_modifiers_present) &&
-       (attributes->modifier[0] != DRM_FORMAT_MOD_INVALID))
-     {
-        DBG("dmabuf import with modifier %#" PRIx64 " failed (%#x), "
-            "retrying without", attributes->modifier[0], eglGetError());
-        img = _gl_import_dmabuf(display, attributes, EINA_FALSE);
-     }
-
-   return img;
-}
-#endif
-
 static void
 _native_bind_cb(void *image)
 {
    Evas_GL_Image *im = image;
    Native *n = im->native.data;
 
-#ifdef GL_GLES
-  if (n->ns.type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-    {
-       /* Must re-import every time for coherency. */
-       if (n->ns_data.wl_surface_dmabuf.image)
-         glsym_evas_gl_common_eglDestroyImage(im->native.disp,
-                                              n->ns_data.wl_surface_dmabuf.image);
-       n->ns_data.wl_surface_dmabuf.image =
-         _gl_import_simple_dmabuf(im->native.disp,
-                                  &n->ns_data.wl_surface_dmabuf.attr);
-       if (!n->ns_data.wl_surface_dmabuf.image)
-         {
-            im->native.invalid = EINA_TRUE;
-            return;
-         }
-       im->native.invalid = EINA_FALSE;
-       if (glsym_glEGLImageTargetTexture2DOES)
-         glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
-                                            n->ns_data.wl_surface_dmabuf.image);
-       return;
-    }
-#endif
   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
     {
 #ifdef GL_GLES
@@ -2188,18 +2067,6 @@ _native_unbind_cb(void *image)
    Evas_GL_Image *im = image;
    Native *n = im->native.data;
 
-#ifdef GL_GLES
-   if (n->ns.type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-     {
-        if (n->ns_data.wl_surface_dmabuf.image)
-          {
-             glsym_evas_gl_common_eglDestroyImage(im->native.disp,
-                                                  n->ns_data.wl_surface_dmabuf.image);
-             n->ns_data.wl_surface_dmabuf.image = NULL;
-          }
-        return;
-     }
-#endif
    if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
      {
 #ifdef GL_GLES
@@ -2327,20 +2194,6 @@ _native_free_cb(void *image)
     {
        eina_hash_del(im->native.shared->native_evasgl_hash, &n->ns.data.evasgl.surface, im);
     }
-  else if (n->ns.type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-     {
-#ifdef GL_GLES
-        void *dmaid = (void*)n->ns_data.wl_surface_dmabuf.resource;
-
-        eina_hash_del(im->native.shared->native_wl_hash, &dmaid, image);
-        if (n->ns_data.wl_surface_dmabuf.image)
-          {
-             glsym_evas_gl_common_eglDestroyImage(im->native.disp,
-                                                  n->ns_data.wl_surface_dmabuf.image);
-             n->ns_data.wl_surface_dmabuf.image = NULL;
-          }
-#endif
-     }
   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
      {
 #ifdef GL_GLES
@@ -2409,7 +2262,7 @@ _native_yinvert_cb(void *image)
 }
 
 static int
-eng_image_native_init(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
+eng_image_native_init(void *engine, Evas_Native_Surface_Type type)
 {
    switch (type)
      {
@@ -2421,15 +2274,21 @@ eng_image_native_init(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
       case EVAS_NATIVE_SURFACE_OPENGL:
       case EVAS_NATIVE_SURFACE_EVASGL:
         return 1;
-#ifdef GL_GLES
+#if defined(GL_GLES) && defined(HAVE_WAYLAND)
       case EVAS_NATIVE_SURFACE_WL:
         return (glsym_eglQueryWaylandBufferWL != NULL) ? 1 : 0;
+#endif
+#ifdef GL_GLES
       case EVAS_NATIVE_SURFACE_WL_DMABUF:
-        /* Say no when the driver cannot import, so a compositor can fall
-         * back rather than hand us buffers we will only render black. */
-        return (dmabuf_present &&
-                glsym_evas_gl_common_eglCreateImage &&
-                glsym_glEGLImageTargetTexture2DOES) ? 1 : 0;
+        {
+           /* Say no when this display cannot import, so a compositor can
+            * fall back rather than be handed buffers it would only ever
+            * render black. */
+           Outbuf *ob = gl_generic_any_output_get(engine);
+
+           if ((!ob) || (!glsym_evas_gl_common_dmabuf_supported)) return 0;
+           return glsym_evas_gl_common_dmabuf_supported(ob->egl_disp);
+        }
 #endif
       default:
         ERR("Native surface type %d not supported!", type);
@@ -2450,8 +2309,10 @@ eng_image_native_shutdown(void *engine EINA_UNUSED, Evas_Native_Surface_Type typ
       case EVAS_NATIVE_SURFACE_X11:
       case EVAS_NATIVE_SURFACE_OPENGL:
       case EVAS_NATIVE_SURFACE_EVASGL:
-#ifdef GL_GLES
+#if defined(GL_GLES) && defined(HAVE_WAYLAND)
       case EVAS_NATIVE_SURFACE_WL:
+#endif
+#ifdef GL_GLES
       case EVAS_NATIVE_SURFACE_WL_DMABUF:
 #endif
         return;
@@ -2475,9 +2336,6 @@ eng_image_native_set(void *engine, void *image, void *native)
   unsigned int fbo = 0;
   void *buffer = NULL;
   Outbuf *ob;
-#ifdef GL_GLES
-  void *dmaid, *dmabuf_res = NULL;
-#endif
 #ifdef GL_GLES
 # ifdef HAVE_WAYLAND
   void *wlid, *wl_buf = NULL;
@@ -2496,6 +2354,16 @@ eng_image_native_set(void *engine, void *image, void *native)
                                                     NULL, 1,
                                                     EVAS_COLORSPACE_ARGB8888);
          }
+#ifdef GL_GLES
+       else if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF) &&
+                (!ns->data.wl_dmabuf.resource) &&
+                (glsym_evas_gl_common_dmabuf_test_image_new))
+         {
+            return glsym_evas_gl_common_dmabuf_test_image_new(gl_context,
+                                                             (Evas_Native_Surface *)ns,
+                                                             ob->egl_disp);
+         }
+#endif
        else
          return NULL;
     }
@@ -2546,12 +2414,6 @@ eng_image_native_set(void *engine, void *image, void *native)
                    return im;
               }
          }
-       else if (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF)
-         {
-#ifdef GL_GLES
-            dmabuf_res = ns->data.wl_dmabuf.resource;
-#endif
-         }
        else if (ns->type == EVAS_NATIVE_SURFACE_WL)
           {
 #ifdef GL_GLES
@@ -2641,17 +2503,11 @@ eng_image_native_set(void *engine, void *image, void *native)
   else if (ns->type == EVAS_NATIVE_SURFACE_WL_DMABUF)
      {
 #ifdef GL_GLES
-        dmaid = dmabuf_res;
-        im2 = eina_hash_find(gl_context->shared->native_wl_hash, &dmaid);
-        if (im2 == im) return im;
-        if (im2)
+        if (glsym_evas_gl_common_dmabuf_native_lookup)
           {
-             if ((n = im2->native.data))
-               {
-                  glsym_evas_gl_common_image_ref(im2);
-                  glsym_evas_gl_common_image_free(im);
-                  return im2;
-               }
+             im2 = glsym_evas_gl_common_dmabuf_native_lookup(gl_context, im,
+                                                            (Evas_Native_Surface *)ns);
+             if (im2) return im2;
           }
 #endif
      }
@@ -3101,33 +2957,14 @@ eng_image_native_set(void *engine, void *image, void *native)
 #ifdef GL_GLES
         if (native)
           {
-             struct dmabuf_attributes *a = ns->data.wl_dmabuf.attr;
-
-             if ((!a) || (a->version != EVAS_DMABUF_ATTRIBUTE_VERSION))
+             if ((!glsym_evas_gl_common_dmabuf_native_attach) ||
+                 (!glsym_evas_gl_common_dmabuf_native_attach(gl_context, im,
+                                                             (Evas_Native_Surface *)ns,
+                                                             ob->egl_disp)))
                {
                   glsym_evas_gl_common_image_free(im);
                   return NULL;
                }
-             if ((n = calloc(1, sizeof(Native))))
-               {
-                  memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
-                  memcpy(&n->ns_data.wl_surface_dmabuf.attr, a, sizeof(*a));
-                  dmaid = dmabuf_res;
-                  eina_hash_add(gl_context->shared->native_wl_hash, &dmaid, im);
-
-                  n->ns_data.wl_surface_dmabuf.resource = dmabuf_res;
-                  im->native.yinvert = 1;
-                  im->native.loose = 0;
-                  im->native.disp = ob->egl_disp;
-                  im->native.shared = gl_context->shared;
-                  im->native.data = ""
-                  im->native.func.bind = _native_bind_cb;
-                  im->native.func.unbind = _native_unbind_cb;
-                  im->native.func.free = _native_free_cb;
-                  im->native.target = GL_TEXTURE_2D;
-                  im->native.mipmap = 0;
-                  glsym_evas_gl_common_image_native_enable(im);
-               }
           }
 #endif
      }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to