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.