From: Akihiko Odaki <akihiko.odaki@gmail.com>
To: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: qemu Developers <qemu-devel@nongnu.org>,
Akihiko Odaki <akihiko.odaki@gmail.com>,
Gerd Hoffmann <kraxel@redhat.com>
Subject: Fwd: [PATCH v2 12/12] ui/dbus: fix texture sharing
Date: Thu, 17 Feb 2022 21:42:38 +0900 [thread overview]
Message-ID: <CAMVc7JW0e5cPGQB986mW2HL-dAn1-u3f7me2=o4n13ka=1Tvjw@mail.gmail.com> (raw)
In-Reply-To: <CAMVc7JWYPZv9yWg0OQfoHQrwaZkb++crxePYQWKTD+af--NLGA@mail.gmail.com>
I mistakenly dropped CC (again). My apologies.
---------- Forwarded message ---------
From: Akihiko Odaki <akihiko.odaki@gmail.com>
Date: Thu, Feb 17, 2022 at 9:38 PM
Subject: Re: [PATCH v2 12/12] ui/dbus: fix texture sharing
To: Marc-André Lureau <marcandre.lureau@redhat.com>
On Thu, Feb 17, 2022 at 9:02 PM <marcandre.lureau@redhat.com> wrote:
>
> 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 egl-headless & VNC
> listeners for example, or other future combinations.
egl-headless only needs one DisplayChangeListener per console since
its output is propagated by ui/console. The vnc protocol is for remote
access and therefore cannot have OpenGL textures. The functionality is
unique to dbus.
>
> Reported-by: Akihiko Odaki <akihiko.odaki@gmail.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/ui/console.h | 10 ++++++++++
> ui/console.c | 26 ++++++++++++++++++++++++++
> ui/dbus-listener.c | 11 -----------
> ui/dbus.c | 24 ++++++++++++++++++++++++
> 4 files changed, 60 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 102fcf0a5068..b9188559fb12 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -1066,6 +1066,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,
> @@ -1078,6 +1099,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);
> return;
> @@ -1098,6 +1120,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);
> }
>
> @@ -1634,6 +1657,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;
> @@ -1678,12 +1702,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);
> }
> + 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..8e2e4c9cad28 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,7 @@ dbus_display_init(Object *o)
> g_autoptr(GDBusObjectSkeleton) vm = NULL;
>
> dd->glctx.ops = &dbus_gl_ops;
> + 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 +149,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.34.1.428.gdcc0cd074f0c
>
next prev parent reply other threads:[~2022-02-17 12:58 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-17 11:58 [PATCH v2 00/12] GL & D-Bus display related fixes marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 01/12] ui/console: fix crash when using gl context with non-gl listeners marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 02/12] ui/console: fix texture leak when calling surface_gl_create_texture() marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 03/12] ui: do not create a surface when resizing a GL scanout marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 04/12] ui/console: move check for compatible GL context marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 05/12] ui/console: move dcl compatiblity check to a callback marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 06/12] ui/console: egl-headless is compatible with non-gl listeners marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 07/12] ui/dbus: associate the DBusDisplayConsole listener with the given console marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 08/12] ui/console: move console compatibility check to dcl_display_console() marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 09/12] ui/shader: fix potential leak of shader on error marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 10/12] ui/shader: free associated programs marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 11/12] ui/console: add a dpy_gfx_switch callback helper marcandre.lureau
2022-02-17 11:58 ` [PATCH v2 12/12] ui/dbus: fix texture sharing marcandre.lureau
[not found] ` <CAMVc7JWYPZv9yWg0OQfoHQrwaZkb++crxePYQWKTD+af--NLGA@mail.gmail.com>
2022-02-17 12:42 ` Akihiko Odaki [this message]
2022-02-17 12:58 ` [PATCH v2 00/12] GL & D-Bus display related fixes Akihiko Odaki
2022-02-17 16:12 ` Marc-André Lureau
2022-02-17 16:11 ` Akihiko Odaki
2022-02-17 17:07 ` Marc-André Lureau
2022-02-17 17:25 ` Akihiko Odaki
2022-02-17 17:36 ` Marc-André Lureau
2022-02-17 17:43 ` Akihiko Odaki
2022-03-07 11:56 ` Marc-André Lureau
2022-03-06 4:31 ` Akihiko Odaki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMVc7JW0e5cPGQB986mW2HL-dAn1-u3f7me2=o4n13ka=1Tvjw@mail.gmail.com' \
--to=akihiko.odaki@gmail.com \
--cc=kraxel@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).