On 2024/10/07 8:23, Dmitry Osipenko wrote:
From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-pra...@amd.com>

If EGL is used, we can rely on dmabuf to import textures without
doing copies.

To get this working on X11, we use the existing SDL hint:
SDL_HINT_VIDEO_X11_FORCE_EGL (because dmabuf can't be used with GLX).

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-pra...@amd.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipe...@collabora.com>
---
  include/ui/sdl2.h |  5 +++++
  ui/sdl2-gl.c      | 39 +++++++++++++++++++++++++++++++++++++++
  ui/sdl2.c         |  8 ++++++++
  3 files changed, 52 insertions(+)

diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index dbe6e3d9739b..b14552f5cd71 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -96,5 +96,10 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
                               void *d3d_tex2d);
  void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
                             uint32_t x, uint32_t y, uint32_t w, uint32_t h);
+void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl,
+                            QemuDmaBuf *dmabuf);
+void sdl2_gl_release_dmabuf(DisplayChangeListener *dcl,
+                            QemuDmaBuf *dmabuf);
+bool sdl2_gl_has_dmabuf(DisplayChangeListener *dcl);
#endif /* SDL2_H */
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index b1fe96d6af22..24aa9108682e 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -26,6 +26,7 @@
   */
#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
  #include "ui/console.h"
  #include "ui/input.h"
  #include "ui/sdl2.h"
@@ -227,6 +228,44 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
                           backing_id, false);
  }
+void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl,
+                            QemuDmaBuf *dmabuf)
+{
+    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
+
+    assert(scon->opengl);
+    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
+
+    egl_dmabuf_import_texture(dmabuf);
+    if (!qemu_dmabuf_get_texture(dmabuf)) {
+        fprintf(stderr, "sdl2_gl_scanout_dmabuf failed fd=%d\n",
+                qemu_dmabuf_get_fd(dmabuf));

Use error_report(). Use __func__ to print the function name.

+    }
+
+    sdl2_gl_scanout_texture(dcl, qemu_dmabuf_get_texture(dmabuf), false,
+                            qemu_dmabuf_get_width(dmabuf),
+                            qemu_dmabuf_get_height(dmabuf),
+                            0, 0,
+                            qemu_dmabuf_get_width(dmabuf),
+                            qemu_dmabuf_get_height(dmabuf),
+                            NULL);
+
+    if (qemu_dmabuf_get_allow_fences(dmabuf)) {
+        scon->guest_fb.dmabuf = dmabuf;
+    }
+}
+
+void sdl2_gl_release_dmabuf(DisplayChangeListener *dcl,
+                            QemuDmaBuf *dmabuf)
+{
+    egl_dmabuf_release_texture(dmabuf);
+}
+
+bool sdl2_gl_has_dmabuf(DisplayChangeListener *dcl)
+{
+    return qemu_egl_has_dmabuf();
+}
+
  void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
                             uint32_t x, uint32_t y, uint32_t w, uint32_t h)
  {
diff --git a/ui/sdl2.c b/ui/sdl2.c
index bd4f5a9da14a..8c7b01c5e62f 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -120,6 +120,9 @@ void sdl2_window_create(struct sdl2_console *scon)
          /* The SDL renderer is only used by sdl2-2D, when OpenGL is disabled 
*/
          scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
      }
+
+    qemu_egl_display = eglGetCurrentDisplay();
+
      sdl_update_caption(scon);
  }
@@ -820,6 +823,10 @@ static const DisplayChangeListenerOps dcl_gl_ops = {
      .dpy_gl_scanout_disable  = sdl2_gl_scanout_disable,
      .dpy_gl_scanout_texture  = sdl2_gl_scanout_texture,
      .dpy_gl_update           = sdl2_gl_scanout_flush,
+
+    .dpy_gl_scanout_dmabuf   = sdl2_gl_scanout_dmabuf,
+    .dpy_gl_release_dmabuf   = sdl2_gl_release_dmabuf,
+    .dpy_has_dmabuf          = sdl2_gl_has_dmabuf,
  };
static bool
@@ -877,6 +884,7 @@ static void sdl2_display_init(DisplayState *ds, 
DisplayOptions *o)
      SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0");
  #endif
      SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
+    SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1");

I think it needs to handle cases where X11 is not used or only GLX is available.

      SDL_EnableScreenSaver();
      memset(&info, 0, sizeof(info));
      SDL_VERSION(&info.version);


Reply via email to