qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PULL 00/12] dbus console fixes
@ 2022-03-14 12:59 marcandre.lureau
  2022-03-14 12:59 ` [PULL 01/12] ui/console: move check for compatible GL context marcandre.lureau
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

The following changes since commit 1416688c53be6535be755b44c15fb2eb9defd20f:

  Merge remote-tracking branch 'remotes/mcayland/tags/q800-updates-for-7.0-20220309' into staging (2022-03-10 13:16:37 +0000)

are available in the Git repository at:

  git@gitlab.com:marcandre.lureau/qemu.git tags/dbus-pull-request

for you to fetch changes up to c923967ca32600aa4e8ab817565ebf5415b4e195:

  ui/console: call gfx_switch() even if the current scanout is GL (2022-03-14 15:16:29 +0400)

----------------------------------------------------------------
GL & D-Bus display related fixes

Hi,

Here are pending fixes related to D-Bus and GL, most of them reported thanks to
Akihiko Odaki.

----------------------------------------------------------------

Marc-André Lureau (12):
  ui/console: move check for compatible GL context
  ui/console: move dcl compatiblity check to a callback
  ui/console: egl-headless is compatible with non-gl listeners
  ui/dbus: associate the DBusDisplayConsole listener with the given
    console
  ui/console: move console compatibility check to dcl_display_console()
  ui/shader: fix potential leak of shader on error
  ui/shader: free associated programs
  ui/console: add a dpy_gfx_switch callback helper
  ui/console: optionally update after gfx switch
  ui/dbus: fix texture sharing
  ui/dbus: do not send 2d scanout until gfx_update
  ui/console: call gfx_switch() even if the current scanout is GL

 include/ui/console.h |  19 +++++---
 ui/dbus.h            |   3 ++
 ui/console.c         | 102 ++++++++++++++++++++++++++-----------------
 ui/dbus-console.c    |  27 ++++++------
 ui/dbus-listener.c   |  48 +++++++++-----------
 ui/dbus.c            |  35 ++++++++++++++-
 ui/egl-headless.c    |  17 +++++++-
 ui/gtk.c             |  18 +++++++-
 ui/sdl2.c            |   9 +++-
 ui/shader.c          |   9 +++-
 ui/spice-display.c   |   9 +++-
 11 files changed, 200 insertions(+), 96 deletions(-)

-- 
2.35.1.273.ge6ebfd0e8cbb




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PULL 01/12] ui/console: move check for compatible GL context
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 02/12] ui/console: move dcl compatiblity check to a callback marcandre.lureau
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Move GL context compatibility check in dpy_compatible_with(), and use
recommended error reporting.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index 365a2c14b809..57e431d9e609 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1482,6 +1482,12 @@ static bool dpy_compatible_with(QemuConsole *con,
 
     flags = con->hw_ops->get_flags ? con->hw_ops->get_flags(con->hw) : 0;
 
+    if (console_has_gl(con) && con->gl->ops->compatible_dcl != dcl->ops) {
+        error_setg(errp, "Display %s is incompatible with the GL context",
+                   dcl->ops->dpy_name);
+        return false;
+    }
+
     if (flags & GRAPHIC_FLAGS_GL &&
         !console_has_gl(con)) {
         error_setg(errp, "The console requires a GL context.");
@@ -1509,27 +1515,12 @@ void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl)
     con->gl = gl;
 }
 
-static bool dpy_gl_compatible_with(QemuConsole *con, DisplayChangeListener *dcl)
-{
-    if (!con->gl) {
-        return true;
-    }
-
-    return con->gl->ops->compatible_dcl == dcl->ops;
-}
-
 void register_displaychangelistener(DisplayChangeListener *dcl)
 {
     QemuConsole *con;
 
     assert(!dcl->ds);
 
-    if (dcl->con && !dpy_gl_compatible_with(dcl->con, dcl)) {
-        error_report("Display %s is incompatible with the GL context",
-                     dcl->ops->dpy_name);
-        exit(1);
-    }
-
     if (dcl->con) {
         dpy_compatible_with(dcl->con, dcl, &error_fatal);
     }
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 02/12] ui/console: move dcl compatiblity check to a callback
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
  2022-03-14 12:59 ` [PULL 01/12] ui/console: move check for compatible GL context marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 03/12] ui/console: egl-headless is compatible with non-gl listeners marcandre.lureau
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

As expected from the "compatible_dcl" comment, a simple comparison of
ops isn't enough. The following patch will fix a regression introduced
by this limited check by extending the compatibility callback for
egl-headless.

For now, this patch simply replaces the the "compatible_dcl" ops pointer
with a "dpy_gl_ctx_is_compatible_ctx" callback.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |  9 ++-------
 ui/console.c         |  3 ++-
 ui/dbus.c            |  9 ++++++++-
 ui/egl-headless.c    |  9 ++++++++-
 ui/gtk.c             | 18 ++++++++++++++++--
 ui/sdl2.c            |  9 ++++++++-
 ui/spice-display.c   |  9 ++++++++-
 7 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index f590819880b5..18a10c0b7db0 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -282,13 +282,8 @@ struct DisplayChangeListener {
 };
 
 typedef struct DisplayGLCtxOps {
-    /*
-     * We only check if the GLCtx is compatible with a DCL via ops. A natural
-     * evolution of this would be a callback to check some runtime requirements
-     * and allow various DCL kinds.
-     */
-    const DisplayChangeListenerOps *compatible_dcl;
-
+    bool (*dpy_gl_ctx_is_compatible_dcl)(DisplayGLCtx *dgc,
+                                         DisplayChangeListener *dcl);
     QEMUGLContext (*dpy_gl_ctx_create)(DisplayGLCtx *dgc,
                                        QEMUGLParams *params);
     void (*dpy_gl_ctx_destroy)(DisplayGLCtx *dgc,
diff --git a/ui/console.c b/ui/console.c
index 57e431d9e609..c9318552871b 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1482,7 +1482,8 @@ static bool dpy_compatible_with(QemuConsole *con,
 
     flags = con->hw_ops->get_flags ? con->hw_ops->get_flags(con->hw) : 0;
 
-    if (console_has_gl(con) && con->gl->ops->compatible_dcl != dcl->ops) {
+    if (console_has_gl(con) &&
+        !con->gl->ops->dpy_gl_ctx_is_compatible_dcl(con->gl, dcl)) {
         error_setg(errp, "Display %s is incompatible with the GL context",
                    dcl->ops->dpy_name);
         return false;
diff --git a/ui/dbus.c b/ui/dbus.c
index 0074424c1fed..f00a44421cf7 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -48,8 +48,15 @@ static QEMUGLContext dbus_create_context(DisplayGLCtx *dgc,
     return qemu_egl_create_context(dgc, params);
 }
 
+static bool
+dbus_is_compatible_dcl(DisplayGLCtx *dgc,
+                       DisplayChangeListener *dcl)
+{
+    return dcl->ops == &dbus_gl_dcl_ops;
+}
+
 static const DisplayGLCtxOps dbus_gl_ops = {
-    .compatible_dcl          = &dbus_gl_dcl_ops,
+    .dpy_gl_ctx_is_compatible_dcl = dbus_is_compatible_dcl,
     .dpy_gl_ctx_create       = dbus_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
     .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index 94082a9da951..9aff115280bc 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -166,8 +166,15 @@ static const DisplayChangeListenerOps egl_ops = {
     .dpy_gl_update           = egl_scanout_flush,
 };
 
+static bool
+egl_is_compatible_dcl(DisplayGLCtx *dgc,
+                      DisplayChangeListener *dcl)
+{
+    return dcl->ops == &egl_ops;
+}
+
 static const DisplayGLCtxOps eglctx_ops = {
-    .compatible_dcl          = &egl_ops,
+    .dpy_gl_ctx_is_compatible_dcl = egl_is_compatible_dcl,
     .dpy_gl_ctx_create       = egl_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
     .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
diff --git a/ui/gtk.c b/ui/gtk.c
index a8567b9ddc8f..1b24a67d7964 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -614,8 +614,15 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
     .dpy_has_dmabuf          = gd_has_dmabuf,
 };
 
+static bool
+gd_gl_area_is_compatible_dcl(DisplayGLCtx *dgc,
+                             DisplayChangeListener *dcl)
+{
+    return dcl->ops == &dcl_gl_area_ops;
+}
+
 static const DisplayGLCtxOps gl_area_ctx_ops = {
-    .compatible_dcl          = &dcl_gl_area_ops,
+    .dpy_gl_ctx_is_compatible_dcl = gd_gl_area_is_compatible_dcl,
     .dpy_gl_ctx_create       = gd_gl_area_create_context,
     .dpy_gl_ctx_destroy      = gd_gl_area_destroy_context,
     .dpy_gl_ctx_make_current = gd_gl_area_make_current,
@@ -641,8 +648,15 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
     .dpy_has_dmabuf          = gd_has_dmabuf,
 };
 
+static bool
+gd_egl_is_compatible_dcl(DisplayGLCtx *dgc,
+                         DisplayChangeListener *dcl)
+{
+    return dcl->ops == &dcl_egl_ops;
+}
+
 static const DisplayGLCtxOps egl_ctx_ops = {
-    .compatible_dcl          = &dcl_egl_ops,
+    .dpy_gl_ctx_is_compatible_dcl = gd_egl_is_compatible_dcl,
     .dpy_gl_ctx_create       = gd_egl_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
     .dpy_gl_ctx_make_current = gd_egl_make_current,
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 46a252d7d9d7..d3741f9b754d 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -788,8 +788,15 @@ static const DisplayChangeListenerOps dcl_gl_ops = {
     .dpy_gl_update           = sdl2_gl_scanout_flush,
 };
 
+static bool
+sdl2_gl_is_compatible_dcl(DisplayGLCtx *dgc,
+                          DisplayChangeListener *dcl)
+{
+    return dcl->ops == &dcl_gl_ops;
+}
+
 static const DisplayGLCtxOps gl_ctx_ops = {
-    .compatible_dcl          = &dcl_gl_ops,
+    .dpy_gl_ctx_is_compatible_dcl = sdl2_gl_is_compatible_dcl,
     .dpy_gl_ctx_create       = sdl2_gl_create_context,
     .dpy_gl_ctx_destroy      = sdl2_gl_destroy_context,
     .dpy_gl_ctx_make_current = sdl2_gl_make_context_current,
diff --git a/ui/spice-display.c b/ui/spice-display.c
index a3078adf91ec..494168e7fe75 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -1125,8 +1125,15 @@ static const DisplayChangeListenerOps display_listener_gl_ops = {
     .dpy_gl_update           = qemu_spice_gl_update,
 };
 
+static bool
+qemu_spice_is_compatible_dcl(DisplayGLCtx *dgc,
+                             DisplayChangeListener *dcl)
+{
+    return dcl->ops == &display_listener_gl_ops;
+}
+
 static const DisplayGLCtxOps gl_ctx_ops = {
-    .compatible_dcl          = &display_listener_gl_ops,
+    .dpy_gl_ctx_is_compatible_dcl = qemu_spice_is_compatible_dcl,
     .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
     .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 03/12] ui/console: egl-headless is compatible with non-gl listeners
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
  2022-03-14 12:59 ` [PULL 01/12] ui/console: move check for compatible GL context marcandre.lureau
  2022-03-14 12:59 ` [PULL 02/12] ui/console: move dcl compatiblity check to a callback marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 04/12] ui/dbus: associate the DBusDisplayConsole listener with the given console marcandre.lureau
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Fix a regression introduced by commit 5e79d516e ("ui: split the GL
context in a different object").

Reported-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/egl-headless.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index 9aff115280bc..7a30fd977765 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -170,6 +170,14 @@ static bool
 egl_is_compatible_dcl(DisplayGLCtx *dgc,
                       DisplayChangeListener *dcl)
 {
+    if (!dcl->ops->dpy_gl_update) {
+        /*
+         * egl-headless is compatible with all 2d listeners, as it blits the GL
+         * updates on the 2d console surface.
+         */
+        return true;
+    }
+
     return dcl->ops == &egl_ops;
 }
 
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 04/12] ui/dbus: associate the DBusDisplayConsole listener with the given console
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (2 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 03/12] ui/console: egl-headless is compatible with non-gl listeners marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 05/12] ui/console: move console compatibility check to dcl_display_console() marcandre.lureau
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

DBusDisplayConsole is specific to a given QemuConsole.

Fixes: commit 142ca628 ("ui: add a D-Bus display backend")
Reported-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/dbus.h         |  3 +++
 ui/dbus-console.c | 27 +++++++++++++--------------
 ui/dbus.c         |  2 +-
 3 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/ui/dbus.h b/ui/dbus.h
index 64c77cab4441..5f5c1f759c9b 100644
--- a/ui/dbus.h
+++ b/ui/dbus.h
@@ -79,6 +79,9 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con);
 int
 dbus_display_console_get_index(DBusDisplayConsole *ddc);
 
+
+extern const DisplayChangeListenerOps dbus_console_dcl_ops;
+
 #define DBUS_DISPLAY_TYPE_LISTENER dbus_display_listener_get_type()
 G_DECLARE_FINAL_TYPE(DBusDisplayListener,
                      dbus_display_listener,
diff --git a/ui/dbus-console.c b/ui/dbus-console.c
index e062f721d761..898a4ac8a5ba 100644
--- a/ui/dbus-console.c
+++ b/ui/dbus-console.c
@@ -36,7 +36,6 @@ struct _DBusDisplayConsole {
     DisplayChangeListener dcl;
 
     DBusDisplay *display;
-    QemuConsole *con;
     GHashTable *listeners;
     QemuDBusDisplay1Console *iface;
 
@@ -118,7 +117,7 @@ dbus_gl_scanout_update(DisplayChangeListener *dcl,
 {
 }
 
-static const DisplayChangeListenerOps dbus_console_dcl_ops = {
+const DisplayChangeListenerOps dbus_console_dcl_ops = {
     .dpy_name                = "dbus-console",
     .dpy_gfx_switch          = dbus_gfx_switch,
     .dpy_gfx_update          = dbus_gfx_update,
@@ -191,7 +190,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc,
         .height = arg_height,
     };
 
-    if (!dpy_ui_info_supported(ddc->con)) {
+    if (!dpy_ui_info_supported(ddc->dcl.con)) {
         g_dbus_method_invocation_return_error(invocation,
                                               DBUS_DISPLAY_ERROR,
                                               DBUS_DISPLAY_ERROR_UNSUPPORTED,
@@ -199,7 +198,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc,
         return DBUS_METHOD_INVOCATION_HANDLED;
     }
 
-    dpy_set_ui_info(ddc->con, &info, false);
+    dpy_set_ui_info(ddc->dcl.con, &info, false);
     qemu_dbus_display1_console_complete_set_uiinfo(ddc->iface, invocation);
     return DBUS_METHOD_INVOCATION_HANDLED;
 }
@@ -335,8 +334,8 @@ dbus_mouse_rel_motion(DBusDisplayConsole *ddc,
         return DBUS_METHOD_INVOCATION_HANDLED;
     }
 
-    qemu_input_queue_rel(ddc->con, INPUT_AXIS_X, dx);
-    qemu_input_queue_rel(ddc->con, INPUT_AXIS_Y, dy);
+    qemu_input_queue_rel(ddc->dcl.con, INPUT_AXIS_X, dx);
+    qemu_input_queue_rel(ddc->dcl.con, INPUT_AXIS_Y, dy);
     qemu_input_event_sync();
 
     qemu_dbus_display1_mouse_complete_rel_motion(ddc->iface_mouse,
@@ -362,8 +361,8 @@ dbus_mouse_set_pos(DBusDisplayConsole *ddc,
         return DBUS_METHOD_INVOCATION_HANDLED;
     }
 
-    width = qemu_console_get_width(ddc->con, 0);
-    height = qemu_console_get_height(ddc->con, 0);
+    width = qemu_console_get_width(ddc->dcl.con, 0);
+    height = qemu_console_get_height(ddc->dcl.con, 0);
     if (x >= width || y >= height) {
         g_dbus_method_invocation_return_error(
             invocation, DBUS_DISPLAY_ERROR,
@@ -371,8 +370,8 @@ dbus_mouse_set_pos(DBusDisplayConsole *ddc,
             "Invalid mouse position");
         return DBUS_METHOD_INVOCATION_HANDLED;
     }
-    qemu_input_queue_abs(ddc->con, INPUT_AXIS_X, x, 0, width);
-    qemu_input_queue_abs(ddc->con, INPUT_AXIS_Y, y, 0, height);
+    qemu_input_queue_abs(ddc->dcl.con, INPUT_AXIS_X, x, 0, width);
+    qemu_input_queue_abs(ddc->dcl.con, INPUT_AXIS_Y, y, 0, height);
     qemu_input_event_sync();
 
     qemu_dbus_display1_mouse_complete_set_abs_position(ddc->iface_mouse,
@@ -388,7 +387,7 @@ dbus_mouse_press(DBusDisplayConsole *ddc,
 {
     trace_dbus_mouse_press(button);
 
-    qemu_input_queue_btn(ddc->con, button, true);
+    qemu_input_queue_btn(ddc->dcl.con, button, true);
     qemu_input_event_sync();
 
     qemu_dbus_display1_mouse_complete_press(ddc->iface_mouse, invocation);
@@ -403,7 +402,7 @@ dbus_mouse_release(DBusDisplayConsole *ddc,
 {
     trace_dbus_mouse_release(button);
 
-    qemu_input_queue_btn(ddc->con, button, false);
+    qemu_input_queue_btn(ddc->dcl.con, button, false);
     qemu_input_event_sync();
 
     qemu_dbus_display1_mouse_complete_release(ddc->iface_mouse, invocation);
@@ -424,7 +423,7 @@ dbus_mouse_mode_change(Notifier *notify, void *data)
 
 int dbus_display_console_get_index(DBusDisplayConsole *ddc)
 {
-    return qemu_console_get_index(ddc->con);
+    return qemu_console_get_index(ddc->dcl.con);
 }
 
 DBusDisplayConsole *
@@ -446,7 +445,7 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con)
                         "g-object-path", path,
                         NULL);
     ddc->display = display;
-    ddc->con = con;
+    ddc->dcl.con = con;
     /* handle errors, and skip non graphics? */
     qemu_console_fill_device_address(
         con, device_addr, sizeof(device_addr), NULL);
diff --git a/ui/dbus.c b/ui/dbus.c
index f00a44421cf7..22c82d2f323a 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -52,7 +52,7 @@ static bool
 dbus_is_compatible_dcl(DisplayGLCtx *dgc,
                        DisplayChangeListener *dcl)
 {
-    return dcl->ops == &dbus_gl_dcl_ops;
+    return dcl->ops == &dbus_gl_dcl_ops || dcl->ops == &dbus_console_dcl_ops;
 }
 
 static const DisplayGLCtxOps dbus_gl_ops = {
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 05/12] ui/console: move console compatibility check to dcl_display_console()
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (3 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 04/12] ui/dbus: associate the DBusDisplayConsole listener with the given console marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 06/12] ui/shader: fix potential leak of shader on error marcandre.lureau
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

The current checks are done at registration time only. However, if a DCL
has no specific console specified, it may be switched dynamically with
console_select() later on.

Let's move the checks when displaychangelistener_display_console() is
called, which includes registration time and remains fatal if the
specified console is incompatible.

Note: we may want to display the compatibility error to the DCL, this is
left for a future improvement.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index c9318552871b..d3ecbb215736 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -148,6 +148,8 @@ static DisplayState *get_alloc_displaystate(void);
 static void text_console_update_cursor_timer(void);
 static void text_console_update_cursor(void *opaque);
 static bool displaychangelistener_has_dmabuf(DisplayChangeListener *dcl);
+static bool console_compatible_with(QemuConsole *con,
+                                    DisplayChangeListener *dcl, Error **errp);
 
 static void gui_update(void *opaque)
 {
@@ -1057,13 +1059,14 @@ static void console_putchar(QemuConsole *s, int ch)
 }
 
 static void displaychangelistener_display_console(DisplayChangeListener *dcl,
-                                                  QemuConsole *con)
+                                                  QemuConsole *con,
+                                                  Error **errp)
 {
     static const char nodev[] =
         "This VM has no graphic display device.";
     static DisplaySurface *dummy;
 
-    if (!con) {
+    if (!con || !console_compatible_with(con, dcl, errp)) {
         if (!dcl->ops->dpy_gfx_switch) {
             return;
         }
@@ -1114,7 +1117,7 @@ void console_select(unsigned int index)
                 if (dcl->con != NULL) {
                     continue;
                 }
-                displaychangelistener_display_console(dcl, s);
+                displaychangelistener_display_console(dcl, s, NULL);
             }
         }
         if (ds->have_text) {
@@ -1475,8 +1478,8 @@ static bool displaychangelistener_has_dmabuf(DisplayChangeListener *dcl)
     return false;
 }
 
-static bool dpy_compatible_with(QemuConsole *con,
-                                DisplayChangeListener *dcl, Error **errp)
+static bool console_compatible_with(QemuConsole *con,
+                                    DisplayChangeListener *dcl, Error **errp)
 {
     int flags;
 
@@ -1522,10 +1525,6 @@ void register_displaychangelistener(DisplayChangeListener *dcl)
 
     assert(!dcl->ds);
 
-    if (dcl->con) {
-        dpy_compatible_with(dcl->con, dcl, &error_fatal);
-    }
-
     trace_displaychangelistener_register(dcl, dcl->ops->dpy_name);
     dcl->ds = get_alloc_displaystate();
     QLIST_INSERT_HEAD(&dcl->ds->listeners, dcl, next);
@@ -1536,7 +1535,7 @@ void register_displaychangelistener(DisplayChangeListener *dcl)
     } else {
         con = active_console;
     }
-    displaychangelistener_display_console(dcl, con);
+    displaychangelistener_display_console(dcl, con, dcl->con ? &error_fatal : NULL);
     text_console_update_cursor(NULL);
 }
 
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 06/12] ui/shader: fix potential leak of shader on error
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (4 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 05/12] ui/console: move console compatibility check to dcl_display_console() marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 07/12] ui/shader: free associated programs marcandre.lureau
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Value of 0 for program and shaders are silently ignored and indicate error.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/shader.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ui/shader.c b/ui/shader.c
index e8b8d321b7c7..4c80fc831f68 100644
--- a/ui/shader.c
+++ b/ui/shader.c
@@ -130,15 +130,17 @@ static GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
 static GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
                                                   const GLchar *frag_src)
 {
-    GLuint vert_shader, frag_shader, program;
+    GLuint vert_shader, frag_shader, program = 0;
 
     vert_shader = qemu_gl_create_compile_shader(GL_VERTEX_SHADER, vert_src);
     frag_shader = qemu_gl_create_compile_shader(GL_FRAGMENT_SHADER, frag_src);
     if (!vert_shader || !frag_shader) {
-        return 0;
+        goto end;
     }
 
     program = qemu_gl_create_link_program(vert_shader, frag_shader);
+
+end:
     glDeleteShader(vert_shader);
     glDeleteShader(frag_shader);
 
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 07/12] ui/shader: free associated programs
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (5 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 06/12] ui/shader: fix potential leak of shader on error marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 08/12] ui/console: add a dpy_gfx_switch callback helper marcandre.lureau
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/shader.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ui/shader.c b/ui/shader.c
index 4c80fc831f68..ab448c41d4c6 100644
--- a/ui/shader.c
+++ b/ui/shader.c
@@ -172,5 +172,8 @@ void qemu_gl_fini_shader(QemuGLShader *gls)
     if (!gls) {
         return;
     }
+    glDeleteProgram(gls->texture_blit_prog);
+    glDeleteProgram(gls->texture_blit_flip_prog);
+    glDeleteProgram(gls->texture_blit_vao);
     g_free(gls);
 }
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 08/12] ui/console: add a dpy_gfx_switch callback helper
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (6 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 07/12] ui/shader: free associated programs marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 09/12] ui/console: optionally update after gfx switch marcandre.lureau
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Slight code improvement.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index d3ecbb215736..102fcf0a5068 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1058,6 +1058,15 @@ static void console_putchar(QemuConsole *s, int ch)
     }
 }
 
+static void displaychangelistener_gfx_switch(DisplayChangeListener *dcl,
+                                             struct DisplaySurface *new_surface)
+{
+    if (dcl->ops->dpy_gfx_switch) {
+        dcl->ops->dpy_gfx_switch(dcl, new_surface);
+    }
+}
+
+
 static void displaychangelistener_display_console(DisplayChangeListener *dcl,
                                                   QemuConsole *con,
                                                   Error **errp)
@@ -1067,13 +1076,10 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
     static DisplaySurface *dummy;
 
     if (!con || !console_compatible_with(con, dcl, errp)) {
-        if (!dcl->ops->dpy_gfx_switch) {
-            return;
-        }
         if (!dummy) {
             dummy = qemu_create_placeholder_surface(640, 480, nodev);
         }
-        dcl->ops->dpy_gfx_switch(dcl, dummy);
+        displaychangelistener_gfx_switch(dcl, dummy);
         return;
     }
 
@@ -1091,9 +1097,8 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
                                          con->scanout.texture.y,
                                          con->scanout.texture.width,
                                          con->scanout.texture.height);
-    } else if (con->scanout.kind == SCANOUT_SURFACE &&
-               dcl->ops->dpy_gfx_switch) {
-        dcl->ops->dpy_gfx_switch(dcl, con->surface);
+    } else if (con->scanout.kind == SCANOUT_SURFACE) {
+        displaychangelistener_gfx_switch(dcl, con->surface);
     }
 
     dcl->ops->dpy_gfx_update(dcl, 0, 0,
@@ -1677,9 +1682,7 @@ void dpy_gfx_replace_surface(QemuConsole *con,
         if (con != (dcl->con ? dcl->con : active_console)) {
             continue;
         }
-        if (dcl->ops->dpy_gfx_switch) {
-            dcl->ops->dpy_gfx_switch(dcl, surface);
-        }
+        displaychangelistener_gfx_switch(dcl, surface);
     }
     qemu_free_displaysurface(old_surface);
 }
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 09/12] ui/console: optionally update after gfx switch
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (7 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 08/12] ui/console: add a dpy_gfx_switch callback helper marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 10/12] ui/dbus: fix texture sharing marcandre.lureau
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

When switching to the dummy surface, we should also call gfx_update.
But when using GL, we shouldn't call it.

By making it an argument to displaychangelistener_gfx_switch(), it will
be explicit, and cannot be forgotten that easily.

Fixes: commit ebced091 ("console: save current scanout details")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index 102fcf0a5068..06ba82db61c9 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1059,11 +1059,18 @@ static void console_putchar(QemuConsole *s, int ch)
 }
 
 static void displaychangelistener_gfx_switch(DisplayChangeListener *dcl,
-                                             struct DisplaySurface *new_surface)
+                                             struct DisplaySurface *new_surface,
+                                             bool update)
 {
     if (dcl->ops->dpy_gfx_switch) {
         dcl->ops->dpy_gfx_switch(dcl, new_surface);
     }
+
+    if (update && dcl->ops->dpy_gfx_update) {
+        dcl->ops->dpy_gfx_update(dcl, 0, 0,
+                                 surface_width(new_surface),
+                                 surface_height(new_surface));
+    }
 }
 
 
@@ -1079,7 +1086,7 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
         if (!dummy) {
             dummy = qemu_create_placeholder_surface(640, 480, nodev);
         }
-        displaychangelistener_gfx_switch(dcl, dummy);
+        displaychangelistener_gfx_switch(dcl, dummy, TRUE);
         return;
     }
 
@@ -1098,12 +1105,8 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
                                          con->scanout.texture.width,
                                          con->scanout.texture.height);
     } else if (con->scanout.kind == SCANOUT_SURFACE) {
-        displaychangelistener_gfx_switch(dcl, con->surface);
+        displaychangelistener_gfx_switch(dcl, con->surface, TRUE);
     }
-
-    dcl->ops->dpy_gfx_update(dcl, 0, 0,
-                             qemu_console_get_width(con, 0),
-                             qemu_console_get_height(con, 0));
 }
 
 void console_select(unsigned int index)
@@ -1682,7 +1685,7 @@ void dpy_gfx_replace_surface(QemuConsole *con,
         if (con != (dcl->con ? dcl->con : active_console)) {
             continue;
         }
-        displaychangelistener_gfx_switch(dcl, surface);
+        displaychangelistener_gfx_switch(dcl, surface, FALSE);
     }
     qemu_free_displaysurface(old_surface);
 }
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 10/12] ui/dbus: fix texture sharing
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (8 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 09/12] ui/console: optionally update after gfx switch marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 11/12] ui/dbus: do not send 2d scanout until gfx_update marcandre.lureau
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

The DBus listener naively create, update and destroy textures without
taking into account other listeners. The texture were shared, but
texture update was unnecessarily duplicated.

Teach DisplayGLCtx to do optionally shared texture handling. This is
only implemented for DBus display at this point, however the same
infrastructure could potentially be used for other future combinations.

Reported-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h | 10 ++++++++++
 ui/console.c         | 26 ++++++++++++++++++++++++++
 ui/dbus-listener.c   | 11 -----------
 ui/dbus.c            | 26 ++++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index 18a10c0b7db0..0f84861933e1 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -290,10 +290,20 @@ typedef struct DisplayGLCtxOps {
                                QEMUGLContext ctx);
     int (*dpy_gl_ctx_make_current)(DisplayGLCtx *dgc,
                                    QEMUGLContext ctx);
+    void (*dpy_gl_ctx_create_texture)(DisplayGLCtx *dgc,
+                                      DisplaySurface *surface);
+    void (*dpy_gl_ctx_destroy_texture)(DisplayGLCtx *dgc,
+                                      DisplaySurface *surface);
+    void (*dpy_gl_ctx_update_texture)(DisplayGLCtx *dgc,
+                                      DisplaySurface *surface,
+                                      int x, int y, int w, int h);
 } DisplayGLCtxOps;
 
 struct DisplayGLCtx {
     const DisplayGLCtxOps *ops;
+#ifdef CONFIG_OPENGL
+    QemuGLShader *gls; /* optional shared shader */
+#endif
 };
 
 DisplayState *init_displaystate(void);
diff --git a/ui/console.c b/ui/console.c
index 06ba82db61c9..5bfecea4549e 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1073,6 +1073,27 @@ static void displaychangelistener_gfx_switch(DisplayChangeListener *dcl,
     }
 }
 
+static void dpy_gfx_create_texture(QemuConsole *con, DisplaySurface *surface)
+{
+    if (con->gl && con->gl->ops->dpy_gl_ctx_create_texture) {
+        con->gl->ops->dpy_gl_ctx_create_texture(con->gl, surface);
+    }
+}
+
+static void dpy_gfx_destroy_texture(QemuConsole *con, DisplaySurface *surface)
+{
+    if (con->gl && con->gl->ops->dpy_gl_ctx_destroy_texture) {
+        con->gl->ops->dpy_gl_ctx_destroy_texture(con->gl, surface);
+    }
+}
+
+static void dpy_gfx_update_texture(QemuConsole *con, DisplaySurface *surface,
+                                   int x, int y, int w, int h)
+{
+    if (con->gl && con->gl->ops->dpy_gl_ctx_update_texture) {
+        con->gl->ops->dpy_gl_ctx_update_texture(con->gl, surface, x, y, w, h);
+    }
+}
 
 static void displaychangelistener_display_console(DisplayChangeListener *dcl,
                                                   QemuConsole *con,
@@ -1085,6 +1106,7 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
     if (!con || !console_compatible_with(con, dcl, errp)) {
         if (!dummy) {
             dummy = qemu_create_placeholder_surface(640, 480, nodev);
+            dpy_gfx_create_texture(con, dummy);
         }
         displaychangelistener_gfx_switch(dcl, dummy, TRUE);
         return;
@@ -1105,6 +1127,7 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
                                          con->scanout.texture.width,
                                          con->scanout.texture.height);
     } else if (con->scanout.kind == SCANOUT_SURFACE) {
+        dpy_gfx_create_texture(con, con->surface);
         displaychangelistener_gfx_switch(dcl, con->surface, TRUE);
     }
 }
@@ -1637,6 +1660,7 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
     if (!qemu_console_is_visible(con)) {
         return;
     }
+    dpy_gfx_update_texture(con, con->surface, x, y, w, h);
     QLIST_FOREACH(dcl, &s->listeners, next) {
         if (con != (dcl->con ? dcl->con : active_console)) {
             continue;
@@ -1681,12 +1705,14 @@ void dpy_gfx_replace_surface(QemuConsole *con,
 
     con->scanout.kind = SCANOUT_SURFACE;
     con->surface = surface;
+    dpy_gfx_create_texture(con, surface);
     QLIST_FOREACH(dcl, &s->listeners, next) {
         if (con != (dcl->con ? dcl->con : active_console)) {
             continue;
         }
         displaychangelistener_gfx_switch(dcl, surface, FALSE);
     }
+    dpy_gfx_destroy_texture(con, old_surface);
     qemu_free_displaysurface(old_surface);
 }
 
diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c
index 81c119b13a2c..a287edd2fc15 100644
--- a/ui/dbus-listener.c
+++ b/ui/dbus-listener.c
@@ -42,7 +42,6 @@ struct _DBusDisplayListener {
 
     DisplayChangeListener dcl;
     DisplaySurface *ds;
-    QemuGLShader *gls;
     int gl_updates;
 };
 
@@ -240,10 +239,6 @@ static void dbus_gl_gfx_update(DisplayChangeListener *dcl,
 {
     DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
 
-    if (ddl->ds) {
-        surface_gl_update_texture(ddl->gls, ddl->ds, x, y, w, h);
-    }
-
     ddl->gl_updates++;
 }
 
@@ -285,15 +280,11 @@ static void dbus_gl_gfx_switch(DisplayChangeListener *dcl,
 {
     DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
 
-    if (ddl->ds) {
-        surface_gl_destroy_texture(ddl->gls, ddl->ds);
-    }
     ddl->ds = new_surface;
     if (ddl->ds) {
         int width = surface_width(ddl->ds);
         int height = surface_height(ddl->ds);
 
-        surface_gl_create_texture(ddl->gls, ddl->ds);
         /* TODO: lazy send dmabuf (there are unnecessary sent otherwise) */
         dbus_scanout_texture(&ddl->dcl, ddl->ds->texture, false,
                              width, height, 0, 0, width, height);
@@ -403,7 +394,6 @@ dbus_display_listener_dispose(GObject *object)
     g_clear_object(&ddl->conn);
     g_clear_pointer(&ddl->bus_name, g_free);
     g_clear_object(&ddl->proxy);
-    g_clear_pointer(&ddl->gls, qemu_gl_fini_shader);
 
     G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object);
 }
@@ -414,7 +404,6 @@ dbus_display_listener_constructed(GObject *object)
     DBusDisplayListener *ddl = DBUS_DISPLAY_LISTENER(object);
 
     if (display_opengl) {
-        ddl->gls = qemu_gl_init_shader();
         ddl->dcl.ops = &dbus_gl_dcl_ops;
     } else {
         ddl->dcl.ops = &dbus_dcl_ops;
diff --git a/ui/dbus.c b/ui/dbus.c
index 22c82d2f323a..7a87612379e8 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -55,11 +55,33 @@ dbus_is_compatible_dcl(DisplayGLCtx *dgc,
     return dcl->ops == &dbus_gl_dcl_ops || dcl->ops == &dbus_console_dcl_ops;
 }
 
+static void
+dbus_create_texture(DisplayGLCtx *ctx, DisplaySurface *surface)
+{
+    surface_gl_create_texture(ctx->gls, surface);
+}
+
+static void
+dbus_destroy_texture(DisplayGLCtx *ctx, DisplaySurface *surface)
+{
+    surface_gl_destroy_texture(ctx->gls, surface);
+}
+
+static void
+dbus_update_texture(DisplayGLCtx *ctx, DisplaySurface *surface,
+                    int x, int y, int w, int h)
+{
+    surface_gl_update_texture(ctx->gls, surface, x, y, w, h);
+}
+
 static const DisplayGLCtxOps dbus_gl_ops = {
     .dpy_gl_ctx_is_compatible_dcl = dbus_is_compatible_dcl,
     .dpy_gl_ctx_create       = dbus_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
     .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
+    .dpy_gl_ctx_create_texture = dbus_create_texture,
+    .dpy_gl_ctx_destroy_texture = dbus_destroy_texture,
+    .dpy_gl_ctx_update_texture = dbus_update_texture,
 };
 
 static NotifierList dbus_display_notifiers =
@@ -90,6 +112,9 @@ dbus_display_init(Object *o)
     g_autoptr(GDBusObjectSkeleton) vm = NULL;
 
     dd->glctx.ops = &dbus_gl_ops;
+    if (display_opengl) {
+        dd->glctx.gls = qemu_gl_init_shader();
+    }
     dd->iface = qemu_dbus_display1_vm_skeleton_new();
     dd->consoles = g_ptr_array_new_with_free_func(g_object_unref);
 
@@ -126,6 +151,7 @@ dbus_display_finalize(Object *o)
     g_clear_object(&dd->iface);
     g_free(dd->dbus_addr);
     g_free(dd->audiodev);
+    g_clear_pointer(&dd->glctx.gls, qemu_gl_fini_shader);
     dbus_display = NULL;
 }
 
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 11/12] ui/dbus: do not send 2d scanout until gfx_update
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (9 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 10/12] ui/dbus: fix texture sharing marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 12:59 ` [PULL 12/12] ui/console: call gfx_switch() even if the current scanout is GL marcandre.lureau
  2022-03-14 14:39 ` [PULL 00/12] dbus console fixes Peter Maydell
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

gfx_switch() is called to set the new_surface, not necessarily to
display it. It should be displayed after gfx_update(). Send the whole
scanout only in this case.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/dbus-listener.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c
index a287edd2fc15..f9fc8eda519a 100644
--- a/ui/dbus-listener.c
+++ b/ui/dbus-listener.c
@@ -255,6 +255,26 @@ static void dbus_gfx_update(DisplayChangeListener *dcl,
 
     trace_dbus_update(x, y, w, h);
 
+    if (x == 0 && y == 0 && w == surface_width(ddl->ds) && h == surface_height(ddl->ds)) {
+        v_data = g_variant_new_from_data(
+            G_VARIANT_TYPE("ay"),
+            surface_data(ddl->ds),
+            surface_stride(ddl->ds) * surface_height(ddl->ds),
+            TRUE,
+            (GDestroyNotify)pixman_image_unref,
+            pixman_image_ref(ddl->ds->image));
+        qemu_dbus_display1_listener_call_scanout(
+            ddl->proxy,
+            surface_width(ddl->ds),
+            surface_height(ddl->ds),
+            surface_stride(ddl->ds),
+            surface_format(ddl->ds),
+            v_data,
+            G_DBUS_CALL_FLAGS_NONE,
+            DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL);
+        return;
+    }
+
     /* make a copy, since gvariant only handles linear data */
     img = pixman_image_create_bits(surface_format(ddl->ds),
                                    w, h, NULL, stride);
@@ -295,29 +315,12 @@ static void dbus_gfx_switch(DisplayChangeListener *dcl,
                             struct DisplaySurface *new_surface)
 {
     DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
-    GVariant *v_data = NULL;
 
     ddl->ds = new_surface;
     if (!ddl->ds) {
         /* why not call disable instead? */
         return;
     }
-
-    v_data = g_variant_new_from_data(
-        G_VARIANT_TYPE("ay"),
-        surface_data(ddl->ds),
-        surface_stride(ddl->ds) * surface_height(ddl->ds),
-        TRUE,
-        (GDestroyNotify)pixman_image_unref,
-        pixman_image_ref(ddl->ds->image));
-    qemu_dbus_display1_listener_call_scanout(ddl->proxy,
-        surface_width(ddl->ds),
-        surface_height(ddl->ds),
-        surface_stride(ddl->ds),
-        surface_format(ddl->ds),
-        v_data,
-        G_DBUS_CALL_FLAGS_NONE,
-        DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL);
 }
 
 static void dbus_mouse_set(DisplayChangeListener *dcl,
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 12/12] ui/console: call gfx_switch() even if the current scanout is GL
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (10 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 11/12] ui/dbus: do not send 2d scanout until gfx_update marcandre.lureau
@ 2022-03-14 12:59 ` marcandre.lureau
  2022-03-14 14:39 ` [PULL 00/12] dbus console fixes Peter Maydell
  12 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2022-03-14 12:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, kraxel, Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

egl-headless depends on the backing surface to be set before texture are
set and updated. Display it (update=true) iff the current scanout kind
is SURFACE.

Reported-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index 5bfecea4549e..16a0b0909ba2 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1112,6 +1112,10 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
         return;
     }
 
+    dpy_gfx_create_texture(con, con->surface);
+    displaychangelistener_gfx_switch(dcl, con->surface,
+                                     con->scanout.kind == SCANOUT_SURFACE);
+
     if (con->scanout.kind == SCANOUT_DMABUF &&
         displaychangelistener_has_dmabuf(dcl)) {
         dcl->ops->dpy_gl_scanout_dmabuf(dcl, con->scanout.dmabuf);
@@ -1126,9 +1130,6 @@ static void displaychangelistener_display_console(DisplayChangeListener *dcl,
                                          con->scanout.texture.y,
                                          con->scanout.texture.width,
                                          con->scanout.texture.height);
-    } else if (con->scanout.kind == SCANOUT_SURFACE) {
-        dpy_gfx_create_texture(con, con->surface);
-        displaychangelistener_gfx_switch(dcl, con->surface, TRUE);
     }
 }
 
-- 
2.35.1.273.ge6ebfd0e8cbb



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PULL 00/12] dbus console fixes
  2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
                   ` (11 preceding siblings ...)
  2022-03-14 12:59 ` [PULL 12/12] ui/console: call gfx_switch() even if the current scanout is GL marcandre.lureau
@ 2022-03-14 14:39 ` Peter Maydell
  12 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2022-03-14 14:39 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: qemu-devel, kraxel

On Mon, 14 Mar 2022 at 12:59, <marcandre.lureau@redhat.com> wrote:
>
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> The following changes since commit 1416688c53be6535be755b44c15fb2eb9defd20f:
>
>   Merge remote-tracking branch 'remotes/mcayland/tags/q800-updates-for-7.0-20220309' into staging (2022-03-10 13:16:37 +0000)
>
> are available in the Git repository at:
>
>   git@gitlab.com:marcandre.lureau/qemu.git tags/dbus-pull-request
>
> for you to fetch changes up to c923967ca32600aa4e8ab817565ebf5415b4e195:
>
>   ui/console: call gfx_switch() even if the current scanout is GL (2022-03-14 15:16:29 +0400)
>
> ----------------------------------------------------------------
> GL & D-Bus display related fixes
>
> Hi,
>
> Here are pending fixes related to D-Bus and GL, most of them reported thanks to
> Akihiko Odaki.
>
> ----------------------------------------------------------------

This causes failures on the CI jobs that run check-acceptance, eg:

https://gitlab.com/qemu-project/qemu/-/jobs/2200046502
https://gitlab.com/qemu-project/qemu/-/jobs/2200046505
https://gitlab.com/qemu-project/qemu/-/jobs/2200046522

on the same pair of tests each time:

(171/183) tests/avocado/vnc.py:Vnc.test_change_password_requires_a_password:
ERROR: ConnectError: Failed to establish session: EOFError\n Exit
code: -11\n Command: ./qemu-system-x86_64 -display none -vga none
-chardev socket,id=mon,path=/var/tmp/avo_qemu_sock_fuvyei1z/qemu-1849-7fcdc8bae828-monitor.sock
-mon chardev=mon,mode=control -nodef... (0.48 s)
(172/183) tests/avocado/vnc.py:Vnc.test_change_password: ERROR:
ConnectError: Failed to establish session: EOFError\n Exit code: -11\n
Command: ./qemu-system-x86_64 -display none -vga none -chardev
socket,id=mon,path=/var/tmp/avo_qemu_sock_vk5oz22m/qemu-1855-7fcdc8babba8-monitor.sock
-mon chardev=mon,mode=control -nodef... (0.16 s)

thanks
-- PMM


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-03-14 14:54 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-14 12:59 [PULL 00/12] dbus console fixes marcandre.lureau
2022-03-14 12:59 ` [PULL 01/12] ui/console: move check for compatible GL context marcandre.lureau
2022-03-14 12:59 ` [PULL 02/12] ui/console: move dcl compatiblity check to a callback marcandre.lureau
2022-03-14 12:59 ` [PULL 03/12] ui/console: egl-headless is compatible with non-gl listeners marcandre.lureau
2022-03-14 12:59 ` [PULL 04/12] ui/dbus: associate the DBusDisplayConsole listener with the given console marcandre.lureau
2022-03-14 12:59 ` [PULL 05/12] ui/console: move console compatibility check to dcl_display_console() marcandre.lureau
2022-03-14 12:59 ` [PULL 06/12] ui/shader: fix potential leak of shader on error marcandre.lureau
2022-03-14 12:59 ` [PULL 07/12] ui/shader: free associated programs marcandre.lureau
2022-03-14 12:59 ` [PULL 08/12] ui/console: add a dpy_gfx_switch callback helper marcandre.lureau
2022-03-14 12:59 ` [PULL 09/12] ui/console: optionally update after gfx switch marcandre.lureau
2022-03-14 12:59 ` [PULL 10/12] ui/dbus: fix texture sharing marcandre.lureau
2022-03-14 12:59 ` [PULL 11/12] ui/dbus: do not send 2d scanout until gfx_update marcandre.lureau
2022-03-14 12:59 ` [PULL 12/12] ui/console: call gfx_switch() even if the current scanout is GL marcandre.lureau
2022-03-14 14:39 ` [PULL 00/12] dbus console fixes Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).