This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch wl/browser-all
in repository enlightenment.
View the commit online.
commit 4ad5cd058934d4d4e4f87fed21efddea0f5ded4d
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 17 15:09:53 2026 -0600
e_comp_wl - offer dmabuf when it can be imported, not per backend
dmabuf was switched off for the X11 backend in 2016 (da23b852e) as "too
hard to get right and nobody will notice its absence". Nobody did, then:
clients drew with the CPU and handed over shm. Browsers render on the GPU
now and reach for dmabuf first, so on the backend a person is most likely
to be developing against, the absence is the difference between
compositing on the GPU and copying every frame through main memory.
But lifting the flag on its own is wrong, and finding out why explains
the original commit. A backend does not know whether import works. Asked
directly, E's Evas_GL api on this machine's X11 canvas has
evasglQueryDmaBufFormats, evasglQueryDmaBufModifiers and
evasglBindWaylandDisplay all NULL, while e_comp_gl_get() still reports
GL - so E would advertise dmabuf, fall back to the two hardcoded formats
in e_pixmap_dmabuf_formats_query because the engine cannot answer, and
then have nothing to turn a client's buffer into. A client that sees the
global uses it in preference to the shm path that would have worked.
Advertising an import path that does not exist is worse than staying
quiet, and that is a fair description of "too hard to get right".
So the decision moves to what knows the answer. linux_dmabuf_setup() now
asks whether an import is possible at all and creates no global if it is
not, and the X11 backend no longer refuses on the backend's behalf. Where
the engine can import, dmabuf appears - including version 4 when the
device is known. Where it cannot, nothing is advertised, which is what
happened before by a less honest route.
No change to the wl_buffer and wl_wl flags: the first is a backend with
no GL at all and the second proxies to a host compositor, and neither
question is the one this predicate answers.
---
src/bin/e_comp_wl.c | 50 ++++++++++++++++++++++++++++++++++-------
src/bin/e_comp_wl.h | 1 +
src/bin/e_comp_wl_dmabuf.c | 12 ++++++++++
src/modules/wl_x11/e_mod_main.c | 23 ++++++++++++++++++-
4 files changed, 77 insertions(+), 9 deletions(-)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 52a5af722..957b4dca9 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -4328,6 +4328,26 @@ e_comp_wl_query_dmabuf_modifiers(int format, int max_modifiers, uint64_t *modifi
#endif
}
+/* Can E take a dmabuf from a client at all?
+ *
+ * The import path turns a client's dmabuf into an EGLImage through these
+ * entries; without them there is nothing to import with, whatever the backend
+ * says. Worth asking rather than assuming, because the answer is no more often
+ * than expected - on a canvas whose EGL never resolved the wayland extensions,
+ * every one of them is NULL while e_comp_gl_get() still reports GL. */
+E_API Eina_Bool
+e_comp_wl_dmabuf_importable(void)
+{
+ if (!e_comp_wl->wl.glapi) return EINA_FALSE;
+ if (!e_comp_wl->wl.glapi->evasglQueryDmaBufFormats) return EINA_FALSE;
+ if (!e_comp_wl->wl.glapi->evasglQueryDmaBufModifiers) return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+/* The DRM node behind the GL engine, read once while our context is current.
+ * Zero means unknown, which is a legitimate answer - see the getter below. */
+static uint64_t e_comp_wl_drm_device = 0;
+
/* The DRM node E imports dmabufs on, as a dev_t widened to a fixed size.
*
* This is what zwp_linux_dmabuf_v1 version 4 calls the main device, and it is
@@ -4340,18 +4360,22 @@ e_comp_wl_query_dmabuf_modifiers(int format, int max_modifiers, uint64_t *modifi
* EGL_EXT_device_query. Every such case must come back false so the caller
* keeps to version 3 instead of advertising feedback it would have to invent.
* A wrong device is worse than no device: the client resolves it and allocates
- * there. */
+ * there.
+ *
+ * Answered from a value read at GL init rather than asked for here, and that
+ * is not an optimisation. evasglQueryDrmDevice reaches the EGLDisplay through
+ * the engine's *current* context, so it only answers while ours is current -
+ * and by the time anything asks, Evas has long since made its own current to
+ * render with. Asking here returned false for exactly that reason. Making ours
+ * current on demand would answer, and would also be yanking the context out
+ * from under the renderer to read a number that cannot change. */
Eina_Bool
e_comp_wl_query_dmabuf_device(uint64_t *device)
{
*device = 0;
-#if EVAS_GL_API_VERSION >= 8
- if (!e_comp_wl->wl.glapi) return EINA_FALSE;
- if (!e_comp_wl->wl.glapi->evasglQueryDrmDevice) return EINA_FALSE;
- return e_comp_wl->wl.glapi->evasglQueryDrmDevice(e_comp_wl->wl.gl, device);
-#else
- return EINA_FALSE;
-#endif
+ if (!e_comp_wl_drm_device) return EINA_FALSE;
+ *device = e_comp_wl_drm_device;
+ return EINA_TRUE;
}
static void
@@ -4369,6 +4393,16 @@ _e_comp_wl_gl_init(void)
e_comp_wl->wl.glapi = evas_gl_context_api_get(e_comp_wl->wl.gl, e_comp_wl->wl.glctx);
if (e_comp_wl->wl.glapi)
{
+#if EVAS_GL_API_VERSION >= 8
+ /* Here, while the context above is still current, is the only place
+ * this question can be asked. */
+ if (e_comp_wl->wl.glapi->evasglQueryDrmDevice)
+ {
+ if (!e_comp_wl->wl.glapi->evasglQueryDrmDevice(e_comp_wl->wl.gl,
+ &e_comp_wl_drm_device))
+ e_comp_wl_drm_device = 0;
+ }
+#endif
if (e_comp_wl->wl.glapi->evasglBindWaylandDisplay)
e_comp->gl = e_comp_wl->wl.glapi->evasglBindWaylandDisplay(e_comp_wl->wl.gl, e_comp_wl->wl.disp);
if (e_comp->gl)
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index c8fe7ddf4..f79a77565 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -599,6 +599,7 @@ E_API void e_comp_wl_notidle(void);
E_API void e_comp_wl_idle_inhibit_add(void);
E_API void e_comp_wl_idle_inhibit_del(void);
E_API Eina_Bool e_comp_wl_idle_inhibited_get(void);
+E_API Eina_Bool e_comp_wl_dmabuf_importable(void);
E_API Eina_Bool e_comp_wl_shortcuts_inhibited_get(void);
E_API void e_comp_wl_screensaver_activate(void);
E_API void e_comp_wl_screensaver_inhibit(Eina_Bool inhibit);
diff --git a/src/bin/e_comp_wl_dmabuf.c b/src/bin/e_comp_wl_dmabuf.c
index 2ffee828e..69fff0a45 100644
--- a/src/bin/e_comp_wl_dmabuf.c
+++ b/src/bin/e_comp_wl_dmabuf.c
@@ -868,6 +868,18 @@ linux_dmabuf_setup(struct wl_display *display)
{
int version = 3;
+ /* Offer dmabuf only if E can take one. Advertising an import path that does
+ * not exist is worse than staying quiet: a client that sees the global uses
+ * it in preference to the shm path that would have worked, and E then has
+ * nothing to turn its buffer into. The format list would be a fiction too -
+ * e_pixmap_dmabuf_formats_query falls back to two hardcoded entries when
+ * the engine cannot answer.
+ *
+ * This is the honest version of what the per-backend dmabuf_disable flags
+ * were reaching for. A backend does not know whether import works; the
+ * engine does. */
+ if (!e_comp_wl_dmabuf_importable()) return 0;
+
/* Version 4 is offered only if both halves of a feedback answer can be
* had: the device E imports on, and a format table to point at. Neither is
* something to guess.
diff --git a/src/modules/wl_x11/e_mod_main.c b/src/modules/wl_x11/e_mod_main.c
index 507f82e92..b055ac9d9 100644
--- a/src/modules/wl_x11/e_mod_main.c
+++ b/src/modules/wl_x11/e_mod_main.c
@@ -76,7 +76,28 @@ e_modapi_init(E_Module *m)
e_comp->pointer = e_pointer_canvas_new(e_comp->ee, EINA_TRUE);
e_comp->pointer->color = EINA_TRUE;
- e_comp_wl->dmabuf_disable = EINA_TRUE;
+ /* dmabuf stays on here.
+ *
+ * It was switched off in 2016 (da23b852e) as "too hard to get right and
+ * nobody will notice its absence". Nobody did, then: clients drew with the
+ * CPU and handed over shm. Browsers render on the GPU now and reach for
+ * dmabuf first, so the absence is the difference between Chromium
+ * compositing on the GPU and copying every frame through main memory - on
+ * the one backend a person is most likely to be running E on while
+ * developing.
+ *
+ * What was hard was almost certainly buffer lifetime rather than import:
+ * an imported dmabuf is a texture the renderer may still be reading when
+ * the client asks for its buffer back. That is what e_pixmap's deferred
+ * release path now exists for. Import itself is gated per buffer by
+ * e_pixmap_dmabuf_test(), so a layout this engine cannot take is refused
+ * one buffer at a time rather than by refusing the protocol.
+ *
+ * Nor is this a promise that dmabuf will appear here. linux_dmabuf_setup()
+ * asks the engine whether an import is possible at all and stays quiet if
+ * it is not, which on a canvas whose EGL never resolved the wayland
+ * extensions is exactly what happens. Removing the flag hands the decision
+ * to the thing that knows the answer. */
return m;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.