Dmitry Osipenko <[email protected]> writes:

> 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);
>  }

There is one remaining build failure for win64:

  ../ui/sdl2-gl.c: In function 'sdl2_gl_scanout_dmabuf':
  ../ui/sdl2-gl.c:265:5: error: implicit declaration of function 
'egl_dmabuf_import_texture'; did you mean 'qemu_dmabuf_set_texture'? 
[-Wimplicit-function-declaration]
    265 |     egl_dmabuf_import_texture(dmabuf);
        |     ^~~~~~~~~~~~~~~~~~~~~~~~~
        |     qemu_dmabuf_set_texture
  ../ui/sdl2-gl.c:265:5: error: nested extern declaration of 
'egl_dmabuf_import_texture' [-Werror=nested-externs]
  ../ui/sdl2-gl.c: In function 'sdl2_gl_release_dmabuf':
  ../ui/sdl2-gl.c:288:5: error: implicit declaration of function 
'egl_dmabuf_release_texture'; did you mean 'qemu_dmabuf_set_texture'? 
[-Wimplicit-function-declaration]
    288 |     egl_dmabuf_release_texture(dmabuf);
        |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
        |     qemu_dmabuf_set_texture
  ../ui/sdl2-gl.c:288:5: error: nested extern declaration of 
'egl_dmabuf_release_texture' [-Werror=nested-externs]
  cc1: all warnings being treated as errors

See: https://gitlab.com/stsquad/qemu/-/jobs/13340078806

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro

Reply via email to