On 3/4/26 11:49, Alex Bennée wrote:
> Dmitry Osipenko <[email protected]> writes:
> 
>> From: Pierre-Eric Pelloux-Prayer <[email protected]>
>>
>> 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).
>>
>> Reviewed-by: Akihiko Odaki <[email protected]>
>> Acked-by: Michael S. Tsirkin <[email protected]>
>> Tested-by: Alex Bennée <[email protected]>
>> Signed-off-by: Pierre-Eric Pelloux-Prayer 
>> <[email protected]>
>> Reviewed-by: Yiwei Zhang <[email protected]>
>> Signed-off-by: Dmitry Osipenko <[email protected]>
>> ---
>>  include/ui/sdl2.h |  7 +++++
>>  meson.build       |  6 ++---
>>  ui/sdl2-gl.c      | 66 +++++++++++++++++++++++++++++++++++++++++++++++
>>  ui/sdl2.c         | 42 ++++++++++++++++++++++++++++++
>>  4 files changed, 117 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
>> index dbe6e3d9739b..9daf5ecffae7 100644
>> --- a/include/ui/sdl2.h
>> +++ b/include/ui/sdl2.h
>> @@ -45,6 +45,7 @@ struct sdl2_console {
>>      bool gui_keysym;
>>      SDL_GLContext winctx;
>>      QKbdState *kbd;
>> +    bool has_dmabuf;
>>  #ifdef CONFIG_OPENGL
>>      QemuGLShader *gls;
>>      egl_fb guest_fb;
>> @@ -96,5 +97,11 @@ 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);
>> +void sdl2_gl_console_init(struct sdl2_console *scon);
>>  
>>  #endif /* SDL2_H */
>> diff --git a/meson.build b/meson.build
>> index 3cd1d8dbc669..0ce84d45e6f3 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -1937,10 +1937,8 @@ if get_option('gtk') \
>>    endif
>>  endif
>>  
>> -x11 = not_found
>> -if gtkx11.found()
>> -  x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
>> -endif
>> +x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
>> +
>>  png = not_found
>>  if get_option('png').allowed() and have_system
>>     png = dependency('libpng', version: '>=1.6.34', required: 
>> get_option('png'),
>> diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
>> index fbac3edbc09d..697ba2169c34 100644
>> --- a/ui/sdl2-gl.c
>> +++ b/ui/sdl2-gl.c
>> @@ -26,6 +26,8 @@
>>   */
>>  
>>  #include "qemu/osdep.h"
>> +#include "qemu/main-loop.h"
>> +#include "qemu/error-report.h"
>>  #include "ui/console.h"
>>  #include "ui/input.h"
>>  #include "ui/sdl2.h"
>> @@ -250,3 +252,67 @@ void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
>>  
>>      SDL_GL_SwapWindow(scon->real_window);
>>  }
>> +
>> +void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl,
>> +                            QemuDmaBuf *dmabuf)
>> +{
>> +    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
>> +    const int *fds;
>> +
>> +    assert(scon->opengl);
>> +    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
>> +
>> +    egl_dmabuf_import_texture(dmabuf);
>> +    if (!qemu_dmabuf_get_texture(dmabuf)) {
>> +        fds = qemu_dmabuf_get_fds(dmabuf, NULL);
>> +        error_report("%s: failed fd=%d", __func__, fds ? fds[0] : -1);
>> +        return;
>> +    }
>> +
>> +    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)
>> +{
>> +    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
>> +
>> +    return scon->has_dmabuf;
>> +}
>> +
>> +void sdl2_gl_console_init(struct sdl2_console *scon)
>> +{
>> +    bool hidden = scon->hidden;
>> +
>> +    scon->hidden = true;
>> +    scon->surface = qemu_create_displaysurface(1, 1);
>> +    sdl2_window_create(scon);
>> +
>> +    /*
>> +     * QEMU checks whether console supports dma-buf before switching
>> +     * to the console.  To break this chicken-egg problem we pre-check
>> +     * dma-buf availability beforehand using a dummy SDL window.
>> +     */
>> +    scon->has_dmabuf = qemu_egl_has_dmabuf();
>> +
>> +    sdl2_window_destroy(scon);
>> +    qemu_free_displaysurface(scon->surface);
>> +
>> +    scon->surface = NULL;
>> +    scon->hidden = hidden;
>> +}
>> diff --git a/ui/sdl2.c b/ui/sdl2.c
>> index 032dc14bc398..3bb2676f847b 100644
>> --- a/ui/sdl2.c
>> +++ b/ui/sdl2.c
>> @@ -35,6 +35,10 @@
>>  #include "qemu/log.h"
>>  #include "qemu-main.h"
>>  
>> +#ifdef CONFIG_X11
>> +#include <X11/Xlib.h>
>> +#endif
>> +
>>  static int sdl2_num_outputs;
>>  static struct sdl2_console *sdl2_console;
>>  
>> @@ -120,6 +124,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();
>> +
> 
> This fails on MacOS for some reason:
> 
>   o libsystem.a.p/ui_sdl2.c.o -c ../ui/sdl2.c
>   ../ui/sdl2.c:128:5: error: use of undeclared identifier 'qemu_egl_display'
>     128 |     qemu_egl_display = eglGetCurrentDisplay();
>         |     ^
>   ../ui/sdl2.c:128:24: error: call to undeclared function 
> 'eglGetCurrentDisplay'; ISO C99 and later do not support implicit function 
> declarations [-Wimplicit-function-declaration]
>     128 |     qemu_egl_display = eglGetCurrentDisplay();
>         |                        ^
>   2 errors generated.
> 
> See: https://gitlab.com/stsquad/qemu/-/jobs/13340079105
> 
> Not sure what the include differences are because --enable-sdl builds
> fine on Linux.

Please try with this change and let me know if you could squash it or I
need to send a patch:

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 3bb2676f847b..2603b0c2bdd8 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -125,7 +125,9 @@ void sdl2_window_create(struct sdl2_console *scon)
         scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
     }

+#ifdef CONFIG_OPENGL
     qemu_egl_display = eglGetCurrentDisplay();
+#endif

     sdl_update_caption(scon);
 }

-- 
Best regards,
Dmitry

Reply via email to