From nobody Mon Apr 13 12:33:49 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1772826760; cv=none; d=zohomail.com; s=zohoarc; b=YI1JXYKEILrMOqSzvVgm+lA4f9XbP+rgZsWTRtHrxvIa1lZ4LEfJ+HBjwWw47DokOj5f48PRSIEDjKhlm6wlxeoI4s4peDT3A4P/YvV4ELKi5hQEajg53f+WjJSJozffA5RIbY97Sw0Fon+eC3j0Dswsly0HXrwQ9vV/9JWZhZI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772826760; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zgbYRpk8ljdnbZv89/v2Xx4zmhiXOdG5XIL02YG2oOc=; b=A7WS+aJB9XydtjQOG98uw6R/tsHxCAvB9xV1cudC/2qklmlIpVk0feWRCC4urL0PHEMNd5/TtLq/XqG9Y1K1F1aFX0cUjpzKAZUXuNA3oOCUFV1+DgxEc/bJRA/P2/NOhU1qecl6jKetOFbT83F/B4L8ocR1Omq+pqAXONWuSfc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772826760396486.3381784765063; Fri, 6 Mar 2026 11:52:40 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vybDC-0004sR-1H; Fri, 06 Mar 2026 14:51:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vybCO-0004Ci-UA for qemu-devel@nongnu.org; Fri, 06 Mar 2026 14:51:02 -0500 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vybCL-0000QU-9f for qemu-devel@nongnu.org; Fri, 06 Mar 2026 14:51:00 -0500 Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-4837584120eso74144715e9.1 for ; Fri, 06 Mar 2026 11:50:56 -0800 (PST) Received: from draig.lan ([185.124.0.126]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-485246ece8bsm36441285e9.4.2026.03.06.11.50.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Mar 2026 11:50:53 -0800 (PST) Received: from draig.lan (localhost [IPv6:::1]) by draig.lan (Postfix) with ESMTP id A9953689D7; Fri, 06 Mar 2026 19:50:49 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1772826655; x=1773431455; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zgbYRpk8ljdnbZv89/v2Xx4zmhiXOdG5XIL02YG2oOc=; b=r2HBE0Jof+O1EhMAIrae3wmzXNtc2X9ClcZF7k4i9bXGchFOvKLm493cBNBvCiU1zn GNU4W3BYDdXUHQZrFXDk2Fzoz/raMHr3VtBbLziMySB1nEqbDXqmlxi6anqzSQ2J35L5 EqnoJ32Gf9Apl54rLandKkEwf2hCDid6tjmXAov7KBF+a8NQivR68U1nBbWu+O3BRIZO Cf8LTGjSVGN6uEahfXEDBhINk9QhEvR3p9hfF7jvUn9jGmK76AbfwlU9RhCFfuRS/lmQ vpByJU2hXScCaDixW34FODkpNQbhmUdeLHMeE0vf3XnG1tOMMzqdoNWJIs9ttOzZCP4l RzGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772826655; x=1773431455; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=zgbYRpk8ljdnbZv89/v2Xx4zmhiXOdG5XIL02YG2oOc=; b=F7ItaHIpP3RUtoFQ5E/WV9aVjehgrcqdxGnSPoiY0TtOgPpsqG5kX6XvRUMOW13SfE Ug6V4kEiIXiygXivlNdyihjEJnGIuZMy1aswDkFTQLrWf7oW1r9T9Qk63+LkyEtR9rlE 16AXYT+7AFGosCI1rZjIFV+e54fSxjVCJ0E3dIEb59eCT6S6VQ1PzGMhZuz3JwyaIJ8x VpGIdsTY1AjhnHFHfYUhH6gjT0crZRG4slwjuyYIRVGVaxlLTgjxqAzi+FqtQAsRhySH eNbYD6IGj6AGpnufrr7IXOiyRrHlFJC8pHcBvFmsseQlt91Rw+ExEd+BB3ZySqF53q6q j2Aw== X-Gm-Message-State: AOJu0Ywb/WPcT2APypPCXTOPLEN6GGYx65Kx6XsNxTyYwF0nhFH5Hymu uMyK9ur4CenYnseXPMpc9bVHOHThVfWHVei9Ji6NsuTX/keftw4w47u5T864addU8ss= X-Gm-Gg: ATEYQzwWT+6OpexXDJ6ELB2PTAmJI+kg1EAzg5qpyrp+ARVGIzEaklKkblXzbRrfFSf G3BkAGokAXNl+zTH8tRb+Ge7h+x+hkuWN+/9wC2Cy5dB1K/CacIlcNZ4V6bXVVUWiwS3mm/IqKe JL53cp2nG71YYtfB/DDN2JOTGPES081lWkNPI8nFi28Vuy+HaY689q3WvYr5VMl00fSo/Lrgvg/ XwtqyLBRDMQposMcSUyw9n65wu3wMfKjtzU6/xM3w1LqRvY0fgdCu918lvYAPansFGc2DweqyeA yrDewHJ+X6Ux9aS9UbEsVS5s3XAiTNXg2iLthh5kKzjLlPNDNNnDsWDD5kCnHZc0IQW+aV3RCpo /iI+gYf+wOqpya7zqmvgAYtKBjQ2lWAqCCBEwWEyGTBTeFNSmuvijX0phJ4rrvPOPA1rDulRKQt SjvT0SIcPcLD9cABZ5ig/NiSk= X-Received: by 2002:a05:600c:4591:b0:483:6d4a:7e6d with SMTP id 5b1f17b1804b1-48526978644mr51581675e9.30.1772826655452; Fri, 06 Mar 2026 11:50:55 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Cc: Pierre-Eric Pelloux-Prayer , Akihiko Odaki , "Michael S. Tsirkin" , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Yiwei Zhang , Dmitry Osipenko , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PULL 08/20] ui/sdl2: Implement dpy dmabuf functions Date: Fri, 6 Mar 2026 19:50:35 +0000 Message-ID: <20260306195048.2869788-9-alex.bennee@linaro.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260306195048.2869788-1-alex.bennee@linaro.org> References: <20260306195048.2869788-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x333.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1772826762836154100 From: Pierre-Eric Pelloux-Prayer 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 Acked-by: Michael S. Tsirkin Tested-by: Alex Benn=C3=A9e Signed-off-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Yiwei Zhang Signed-off-by: Dmitry Osipenko Message-ID: <20260303151422.977399-7-dmitry.osipenko@collabora.com> [AJB: ifdef CONFIG_OPENGL/CONFIG_GBM for non-linux hosts] Message-ID: <20260304165043.1437519-9-alex.bennee@linaro.org> Signed-off-by: Alex Benn=C3=A9e diff --git a/meson.build b/meson.build index 7b4e5bc72b5..6b1838b159e 100644 --- a/meson.build +++ b/meson.build @@ -1946,10 +1946,8 @@ if get_option('gtk') \ endif endif =20 -x11 =3D not_found -if gtkx11.found() - x11 =3D dependency('x11', method: 'pkg-config', required: gtkx11.found()) -endif +x11 =3D dependency('x11', method: 'pkg-config', required: gtkx11.found()) + png =3D not_found if get_option('png').allowed() and have_system png =3D dependency('libpng', version: '>=3D1.6.34', required: get_optio= n('png'), diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index dbe6e3d9739..9daf5ecffae 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); =20 #endif /* SDL2_H */ diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index fbac3edbc09..bb066cdd885 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -26,6 +26,8 @@ */ =20 #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,69 @@ void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, =20 SDL_GL_SwapWindow(scon->real_window); } + +#ifdef CONFIG_GBM +void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + struct sdl2_console *scon =3D container_of(dcl, struct sdl2_console, d= cl); + 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 =3D qemu_dmabuf_get_fds(dmabuf, NULL); + error_report("%s: failed fd=3D%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 =3D 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 =3D container_of(dcl, struct sdl2_console, d= cl); + + return scon->has_dmabuf; +} +#endif + +void sdl2_gl_console_init(struct sdl2_console *scon) +{ + bool hidden =3D scon->hidden; + + scon->hidden =3D true; + scon->surface =3D 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 =3D qemu_egl_has_dmabuf(); + + sdl2_window_destroy(scon); + qemu_free_displaysurface(scon->surface); + + scon->surface =3D NULL; + scon->hidden =3D hidden; +} diff --git a/ui/sdl2.c b/ui/sdl2.c index 032dc14bc39..aaaede56e0e 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -35,6 +35,10 @@ #include "qemu/log.h" #include "qemu-main.h" =20 +#ifdef CONFIG_X11 +#include +#endif + static int sdl2_num_outputs; static struct sdl2_console *sdl2_console; =20 @@ -120,6 +124,11 @@ void sdl2_window_create(struct sdl2_console *scon) /* The SDL renderer is only used by sdl2-2D, when OpenGL is disabl= ed */ scon->real_renderer =3D SDL_CreateRenderer(scon->real_window, -1, = 0); } + +#ifdef CONFIG_OPENGL + qemu_egl_display =3D eglGetCurrentDisplay(); +#endif + sdl_update_caption(scon); } =20 @@ -808,6 +817,12 @@ static const DisplayChangeListenerOps dcl_gl_ops =3D { .dpy_gl_scanout_disable =3D sdl2_gl_scanout_disable, .dpy_gl_scanout_texture =3D sdl2_gl_scanout_texture, .dpy_gl_update =3D sdl2_gl_scanout_flush, + +#ifdef CONFIG_GBM + .dpy_gl_scanout_dmabuf =3D sdl2_gl_scanout_dmabuf, + .dpy_gl_release_dmabuf =3D sdl2_gl_release_dmabuf, + .dpy_has_dmabuf =3D sdl2_gl_has_dmabuf, +#endif }; =20 static bool @@ -835,6 +850,35 @@ static void sdl2_display_early_init(DisplayOptions *o) } } =20 +static void sdl2_set_hint_x11_force_egl(void) +{ +#if defined(SDL_HINT_VIDEO_X11_FORCE_EGL) && defined(CONFIG_OPENGL) && \ + defined(CONFIG_X11) + Display *x_disp =3D XOpenDisplay(NULL); + EGLDisplay egl_display; + + if (!x_disp) { + return; + } + + /* Prefer EGL over GLX to get dma-buf support. */ + egl_display =3D eglGetDisplay((EGLNativeDisplayType)x_disp); + + if (egl_display !=3D EGL_NO_DISPLAY) { + /* + * Setting X11_FORCE_EGL hint doesn't make SDL to prefer X11 over + * Wayland. SDL will use Wayland driver even if XWayland presents. + * It's always safe to set the hint even if X11 is not used by SDL. + * SDL will work regardless of the hint. + */ + SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1"); + eglTerminate(egl_display); + } + + XCloseDisplay(x_disp); +#endif +} + static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) { uint8_t data =3D 0; @@ -862,6 +906,7 @@ static void sdl2_display_init(DisplayState *ds, Display= Options *o) SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); #endif SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); + sdl2_set_hint_x11_force_egl(); SDL_EnableScreenSaver(); memset(&info, 0, sizeof(info)); SDL_VERSION(&info.version); @@ -906,9 +951,12 @@ static void sdl2_display_init(DisplayState *ds, Displa= yOptions *o) #endif sdl2_console[i].dcl.con =3D con; sdl2_console[i].kbd =3D qkbd_state_init(con); +#ifdef CONFIG_OPENGL if (display_opengl) { qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dgc); + sdl2_gl_console_init(&sdl2_console[i]); } +#endif register_displaychangelistener(&sdl2_console[i].dcl); =20 #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11) --=20 2.47.3