Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1571490/?format=api
{ "id": 1571490, "url": "http://patchwork.ozlabs.org/api/patches/1571490/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20211221065855.142578-17-marcandre.lureau@redhat.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20211221065855.142578-17-marcandre.lureau@redhat.com>", "list_archive_url": null, "date": "2021-12-21T06:58:35", "name": "[PULL,v2,16/36] ui: split the GL context in a different object", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "633554103403ae325c721b8a0c5e9c719db0a115", "submitter": { "id": 66774, "url": "http://patchwork.ozlabs.org/api/people/66774/?format=api", "name": "Marc-André Lureau", "email": "marcandre.lureau@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20211221065855.142578-17-marcandre.lureau@redhat.com/mbox/", "series": [ { "id": 277865, "url": "http://patchwork.ozlabs.org/api/series/277865/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=277865", "date": "2021-12-21T06:58:19", "name": "[PULL,v2,01/36] ui/vdagent: add CHECK_SPICE_PROTOCOL_VERSION", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/277865/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1571490/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1571490/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "bilbo.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=C1fz0ydq;\n\tdkim-atps=neutral", "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=<UNKNOWN>)", "relay.mimecast.com;\n auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby bilbo.ozlabs.org (Postfix) with ESMTPS id 4JJ7fZ0kYWz9s3q\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Dec 2021 18:40:36 +1100 (AEDT)", "from localhost ([::1]:48134 helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1mzZlA-0004gT-U1\n\tfor incoming@patchwork.ozlabs.org; Tue, 21 Dec 2021 02:40:32 -0500", "from eggs.gnu.org ([209.51.188.92]:58658)\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1mzZAy-0005uh-0t\n for qemu-devel@nongnu.org; Tue, 21 Dec 2021 02:03:08 -0500", "from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:47517)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1mzZAv-00025l-4H\n for qemu-devel@nongnu.org; Tue, 21 Dec 2021 02:03:07 -0500", "from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com\n [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n us-mta-50-XIHM-629MDCEy-zj2PXnxA-1; Tue, 21 Dec 2021 02:03:01 -0500", "from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com\n [10.5.11.11])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0AA31801B31;\n Tue, 21 Dec 2021 07:03:00 +0000 (UTC)", "from localhost (unknown [10.39.208.37])\n by smtp.corp.redhat.com (Postfix) with ESMTP id A0A857EA36;\n Tue, 21 Dec 2021 07:02:57 +0000 (UTC)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1640070184;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=0XmaWU22xZifElMEq63eAPJ22WB/aAoJVypSzIxJk10=;\n b=C1fz0ydqxoHYodzrDtwZDz+t5hf0f5+kq8L5JEy9DzUZkFJ0xNQNHU1+7c0mXXtk87FDSt\n odnXDFERFRJqeAv0at397a+DTDdaYg2pgCWaIe/exfuRC1TsrjJkNKrXSFDWIvIprNqmPm\n QgUTY4vLWjSPbiWo66q6PJPw3sHYT/w=", "X-MC-Unique": "XIHM-629MDCEy-zj2PXnxA-1", "From": "marcandre.lureau@redhat.com", "To": "qemu-devel@nongnu.org", "Subject": "[PULL v2 16/36] ui: split the GL context in a different object", "Date": "Tue, 21 Dec 2021 10:58:35 +0400", "Message-Id": "<20211221065855.142578-17-marcandre.lureau@redhat.com>", "In-Reply-To": "<20211221065855.142578-1-marcandre.lureau@redhat.com>", "References": "<20211221065855.142578-1-marcandre.lureau@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.11", "X-Mimecast-Spam-Score": "0", "X-Mimecast-Originator": "redhat.com", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=170.10.133.124;\n envelope-from=marcandre.lureau@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com", "X-Spam_score_int": "-29", "X-Spam_score": "-3.0", "X-Spam_bar": "---", "X-Spam_report": "(-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.203,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001,\n 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-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "peter.maydell@linaro.org, richard.henderson@linaro.org, =?utf-8?q?Marc-A?=\n\t=?utf-8?q?ndr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "From: Marc-André Lureau <marcandre.lureau@redhat.com>\n\nThis will allow to have one GL context but a variable number of\nlisteners.\n\nSigned-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>\nAcked-by: Gerd Hoffmann <kraxel@redhat.com>\n---\n include/ui/console.h | 34 ++++++++++++++++++++++------------\n include/ui/egl-context.h | 6 +++---\n include/ui/gtk.h | 11 ++++++-----\n include/ui/sdl2.h | 7 ++++---\n include/ui/spice-display.h | 1 +\n ui/console.c | 26 ++++++++++++++++----------\n ui/egl-context.c | 6 +++---\n ui/egl-headless.c | 21 ++++++++++++++-------\n ui/gtk-egl.c | 10 +++++-----\n ui/gtk-gl-area.c | 8 ++++----\n ui/gtk.c | 24 ++++++++++++++++--------\n ui/sdl2-gl.c | 10 +++++-----\n ui/sdl2.c | 13 +++++++++----\n ui/spice-display.c | 18 +++++++++++-------\n 14 files changed, 119 insertions(+), 76 deletions(-)", "diff": "diff --git a/include/ui/console.h b/include/ui/console.h\nindex 3ff51b492e5b..fe08b4dd040f 100644\n--- a/include/ui/console.h\n+++ b/include/ui/console.h\n@@ -179,6 +179,7 @@ typedef struct QemuDmaBuf {\n } QemuDmaBuf;\n \n typedef struct DisplayState DisplayState;\n+typedef struct DisplayGLCtx DisplayGLCtx;\n \n typedef struct DisplayChangeListenerOps {\n const char *dpy_name;\n@@ -213,16 +214,6 @@ typedef struct DisplayChangeListenerOps {\n void (*dpy_cursor_define)(DisplayChangeListener *dcl,\n QEMUCursor *cursor);\n \n- /* required if GL */\n- QEMUGLContext (*dpy_gl_ctx_create)(DisplayChangeListener *dcl,\n- QEMUGLParams *params);\n- /* required if GL */\n- void (*dpy_gl_ctx_destroy)(DisplayChangeListener *dcl,\n- QEMUGLContext ctx);\n- /* required if GL */\n- int (*dpy_gl_ctx_make_current)(DisplayChangeListener *dcl,\n- QEMUGLContext ctx);\n-\n /* required if GL */\n void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl);\n /* required if GL */\n@@ -263,6 +254,26 @@ struct DisplayChangeListener {\n QLIST_ENTRY(DisplayChangeListener) next;\n };\n \n+typedef struct DisplayGLCtxOps {\n+ /*\n+ * We only check if the GLCtx is compatible with a DCL via ops. A natural\n+ * evolution of this would be a callback to check some runtime requirements\n+ * and allow various DCL kinds.\n+ */\n+ const DisplayChangeListenerOps *compatible_dcl;\n+\n+ QEMUGLContext (*dpy_gl_ctx_create)(DisplayGLCtx *dgc,\n+ QEMUGLParams *params);\n+ void (*dpy_gl_ctx_destroy)(DisplayGLCtx *dgc,\n+ QEMUGLContext ctx);\n+ int (*dpy_gl_ctx_make_current)(DisplayGLCtx *dgc,\n+ QEMUGLContext ctx);\n+} DisplayGLCtxOps;\n+\n+struct DisplayGLCtx {\n+ const DisplayGLCtxOps *ops;\n+};\n+\n DisplayState *init_displaystate(void);\n DisplaySurface *qemu_create_displaysurface_from(int width, int height,\n pixman_format_code_t format,\n@@ -409,8 +420,7 @@ void graphic_hw_gl_block(QemuConsole *con, bool block);\n \n void qemu_console_early_init(void);\n \n-void qemu_console_set_display_gl_ctx(QemuConsole *con,\n- DisplayChangeListener *dcl);\n+void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *ctx);\n \n QemuConsole *qemu_console_lookup_by_index(unsigned int index);\n QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);\ndiff --git a/include/ui/egl-context.h b/include/ui/egl-context.h\nindex 9374fe41e32b..c2761d747a4e 100644\n--- a/include/ui/egl-context.h\n+++ b/include/ui/egl-context.h\n@@ -4,10 +4,10 @@\n #include \"ui/console.h\"\n #include \"ui/egl-helpers.h\"\n \n-QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params);\n-void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx);\n-int qemu_egl_make_context_current(DisplayChangeListener *dcl,\n+void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx);\n+int qemu_egl_make_context_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx);\n \n #endif /* EGL_CONTEXT_H */\ndiff --git a/include/ui/gtk.h b/include/ui/gtk.h\nindex 7d22affd381a..101b147d1b98 100644\n--- a/include/ui/gtk.h\n+++ b/include/ui/gtk.h\n@@ -35,6 +35,7 @@ typedef struct GtkDisplayState GtkDisplayState;\n \n typedef struct VirtualGfxConsole {\n GtkWidget *drawing_area;\n+ DisplayGLCtx dgc;\n DisplayChangeListener dcl;\n QKbdState *kbd;\n DisplaySurface *ds;\n@@ -165,7 +166,7 @@ void gd_egl_update(DisplayChangeListener *dcl,\n void gd_egl_refresh(DisplayChangeListener *dcl);\n void gd_egl_switch(DisplayChangeListener *dcl,\n DisplaySurface *surface);\n-QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params);\n void gd_egl_scanout_disable(DisplayChangeListener *dcl);\n void gd_egl_scanout_texture(DisplayChangeListener *dcl,\n@@ -187,7 +188,7 @@ void gd_egl_flush(DisplayChangeListener *dcl,\n void gd_egl_scanout_flush(DisplayChangeListener *dcl,\n uint32_t x, uint32_t y, uint32_t w, uint32_t h);\n void gtk_egl_init(DisplayGLMode mode);\n-int gd_egl_make_current(DisplayChangeListener *dcl,\n+int gd_egl_make_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx);\n \n /* ui/gtk-gl-area.c */\n@@ -198,9 +199,9 @@ void gd_gl_area_update(DisplayChangeListener *dcl,\n void gd_gl_area_refresh(DisplayChangeListener *dcl);\n void gd_gl_area_switch(DisplayChangeListener *dcl,\n DisplaySurface *surface);\n-QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params);\n-void gd_gl_area_destroy_context(DisplayChangeListener *dcl,\n+void gd_gl_area_destroy_context(DisplayGLCtx *dgc,\n QEMUGLContext ctx);\n void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,\n QemuDmaBuf *dmabuf);\n@@ -215,7 +216,7 @@ void gd_gl_area_scanout_disable(DisplayChangeListener *dcl);\n void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,\n uint32_t x, uint32_t y, uint32_t w, uint32_t h);\n void gtk_gl_area_init(void);\n-int gd_gl_area_make_current(DisplayChangeListener *dcl,\n+int gd_gl_area_make_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx);\n \n /* gtk-clipboard.c */\ndiff --git a/include/ui/sdl2.h b/include/ui/sdl2.h\nindex f85c117a78f2..71bcf7ebdaee 100644\n--- a/include/ui/sdl2.h\n+++ b/include/ui/sdl2.h\n@@ -16,6 +16,7 @@\n #endif\n \n struct sdl2_console {\n+ DisplayGLCtx dgc;\n DisplayChangeListener dcl;\n DisplaySurface *surface;\n DisplayOptions *opts;\n@@ -65,10 +66,10 @@ void sdl2_gl_switch(DisplayChangeListener *dcl,\n void sdl2_gl_refresh(DisplayChangeListener *dcl);\n void sdl2_gl_redraw(struct sdl2_console *scon);\n \n-QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params);\n-void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx);\n-int sdl2_gl_make_context_current(DisplayChangeListener *dcl,\n+void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx);\n+int sdl2_gl_make_context_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx);\n \n void sdl2_gl_scanout_disable(DisplayChangeListener *dcl);\ndiff --git a/include/ui/spice-display.h b/include/ui/spice-display.h\nindex ed298d58f06c..a2fbf62c528e 100644\n--- a/include/ui/spice-display.h\n+++ b/include/ui/spice-display.h\n@@ -86,6 +86,7 @@ typedef struct SimpleSpiceCursor SimpleSpiceCursor;\n \n struct SimpleSpiceDisplay {\n DisplaySurface *ds;\n+ DisplayGLCtx dgc;\n DisplayChangeListener dcl;\n void *buf;\n int bufsize;\ndiff --git a/ui/console.c b/ui/console.c\nindex 13c0d001c096..78583df92035 100644\n--- a/ui/console.c\n+++ b/ui/console.c\n@@ -78,7 +78,7 @@ struct QemuConsole {\n DisplayState *ds;\n DisplaySurface *surface;\n int dcls;\n- DisplayChangeListener *gl;\n+ DisplayGLCtx *gl;\n int gl_block;\n QEMUTimer *gl_unblock_timer;\n int window_id;\n@@ -1458,17 +1458,24 @@ static bool dpy_compatible_with(QemuConsole *con,\n return true;\n }\n \n-void qemu_console_set_display_gl_ctx(QemuConsole *con,\n- DisplayChangeListener *dcl)\n+void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl)\n {\n /* display has opengl support */\n- assert(dcl->con);\n- if (dcl->con->gl) {\n- fprintf(stderr, \"can't register two opengl displays (%s, %s)\\n\",\n- dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name);\n+ assert(con);\n+ if (con->gl) {\n+ error_report(\"The console already has an OpenGL context.\");\n exit(1);\n }\n- dcl->con->gl = dcl;\n+ con->gl = gl;\n+}\n+\n+static bool dpy_gl_compatible_with(QemuConsole *con, DisplayChangeListener *dcl)\n+{\n+ if (!con->gl) {\n+ return true;\n+ }\n+\n+ return con->gl->ops->compatible_dcl == dcl->ops;\n }\n \n void register_displaychangelistener(DisplayChangeListener *dcl)\n@@ -1480,8 +1487,7 @@ void register_displaychangelistener(DisplayChangeListener *dcl)\n \n assert(!dcl->ds);\n \n- if (dcl->con && dcl->con->gl &&\n- dcl->con->gl != dcl) {\n+ if (dcl->con && !dpy_gl_compatible_with(dcl->con, dcl)) {\n error_report(\"Display %s is incompatible with the GL context\",\n dcl->ops->dpy_name);\n exit(1);\ndiff --git a/ui/egl-context.c b/ui/egl-context.c\nindex 368ffa49d82f..eb5f520fc4da 100644\n--- a/ui/egl-context.c\n+++ b/ui/egl-context.c\n@@ -1,7 +1,7 @@\n #include \"qemu/osdep.h\"\n #include \"ui/egl-context.h\"\n \n-QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params)\n {\n EGLContext ctx;\n@@ -24,12 +24,12 @@ QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,\n return ctx;\n }\n \n-void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)\n+void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx)\n {\n eglDestroyContext(qemu_egl_display, ctx);\n }\n \n-int qemu_egl_make_context_current(DisplayChangeListener *dcl,\n+int qemu_egl_make_context_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx)\n {\n return eglMakeCurrent(qemu_egl_display,\ndiff --git a/ui/egl-headless.c b/ui/egl-headless.c\nindex 08327c40c6ee..94082a9da951 100644\n--- a/ui/egl-headless.c\n+++ b/ui/egl-headless.c\n@@ -38,12 +38,12 @@ static void egl_gfx_switch(DisplayChangeListener *dcl,\n edpy->ds = new_surface;\n }\n \n-static QEMUGLContext egl_create_context(DisplayChangeListener *dcl,\n+static QEMUGLContext egl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params)\n {\n eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,\n qemu_egl_rn_ctx);\n- return qemu_egl_create_context(dcl, params);\n+ return qemu_egl_create_context(dgc, params);\n }\n \n static void egl_scanout_disable(DisplayChangeListener *dcl)\n@@ -157,10 +157,6 @@ static const DisplayChangeListenerOps egl_ops = {\n .dpy_gfx_update = egl_gfx_update,\n .dpy_gfx_switch = egl_gfx_switch,\n \n- .dpy_gl_ctx_create = egl_create_context,\n- .dpy_gl_ctx_destroy = qemu_egl_destroy_context,\n- .dpy_gl_ctx_make_current = qemu_egl_make_context_current,\n-\n .dpy_gl_scanout_disable = egl_scanout_disable,\n .dpy_gl_scanout_texture = egl_scanout_texture,\n .dpy_gl_scanout_dmabuf = egl_scanout_dmabuf,\n@@ -170,6 +166,13 @@ static const DisplayChangeListenerOps egl_ops = {\n .dpy_gl_update = egl_scanout_flush,\n };\n \n+static const DisplayGLCtxOps eglctx_ops = {\n+ .compatible_dcl = &egl_ops,\n+ .dpy_gl_ctx_create = egl_create_context,\n+ .dpy_gl_ctx_destroy = qemu_egl_destroy_context,\n+ .dpy_gl_ctx_make_current = qemu_egl_make_context_current,\n+};\n+\n static void early_egl_headless_init(DisplayOptions *opts)\n {\n display_opengl = 1;\n@@ -188,6 +191,8 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts)\n }\n \n for (idx = 0;; idx++) {\n+ DisplayGLCtx *ctx;\n+\n con = qemu_console_lookup_by_index(idx);\n if (!con || !qemu_console_is_graphic(con)) {\n break;\n@@ -197,7 +202,9 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts)\n edpy->dcl.con = con;\n edpy->dcl.ops = &egl_ops;\n edpy->gls = qemu_gl_init_shader();\n- qemu_console_set_display_gl_ctx(con, &edpy->dcl);\n+ ctx = g_new0(DisplayGLCtx, 1);\n+ ctx->ops = &eglctx_ops;\n+ qemu_console_set_display_gl_ctx(con, ctx);\n register_displaychangelistener(&edpy->dcl);\n }\n }\ndiff --git a/ui/gtk-egl.c b/ui/gtk-egl.c\nindex e891b61048a8..e3bd4bc27431 100644\n--- a/ui/gtk-egl.c\n+++ b/ui/gtk-egl.c\n@@ -197,14 +197,14 @@ void gd_egl_switch(DisplayChangeListener *dcl,\n }\n }\n \n-QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params)\n {\n- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);\n+ VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);\n \n eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,\n vc->gfx.esurface, vc->gfx.ectx);\n- return qemu_egl_create_context(dcl, params);\n+ return qemu_egl_create_context(dgc, params);\n }\n \n void gd_egl_scanout_disable(DisplayChangeListener *dcl)\n@@ -360,10 +360,10 @@ void gtk_egl_init(DisplayGLMode mode)\n display_opengl = 1;\n }\n \n-int gd_egl_make_current(DisplayChangeListener *dcl,\n+int gd_egl_make_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx)\n {\n- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);\n+ VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);\n \n return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,\n vc->gfx.esurface, ctx);\ndiff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c\nindex f1c7636cba98..fc5a082eb846 100644\n--- a/ui/gtk-gl-area.c\n+++ b/ui/gtk-gl-area.c\n@@ -170,10 +170,10 @@ void gd_gl_area_switch(DisplayChangeListener *dcl,\n }\n }\n \n-QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params)\n {\n- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);\n+ VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);\n GdkWindow *window;\n GdkGLContext *ctx;\n GError *err = NULL;\n@@ -199,7 +199,7 @@ QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,\n return ctx;\n }\n \n-void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)\n+void gd_gl_area_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx)\n {\n /* FIXME */\n }\n@@ -278,7 +278,7 @@ void gtk_gl_area_init(void)\n display_opengl = 1;\n }\n \n-int gd_gl_area_make_current(DisplayChangeListener *dcl,\n+int gd_gl_area_make_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx)\n {\n gdk_gl_context_make_current(ctx);\ndiff --git a/ui/gtk.c b/ui/gtk.c\nindex 077d38145de8..6a1f65d51894 100644\n--- a/ui/gtk.c\n+++ b/ui/gtk.c\n@@ -606,9 +606,6 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {\n .dpy_mouse_set = gd_mouse_set,\n .dpy_cursor_define = gd_cursor_define,\n \n- .dpy_gl_ctx_create = gd_gl_area_create_context,\n- .dpy_gl_ctx_destroy = gd_gl_area_destroy_context,\n- .dpy_gl_ctx_make_current = gd_gl_area_make_current,\n .dpy_gl_scanout_texture = gd_gl_area_scanout_texture,\n .dpy_gl_scanout_disable = gd_gl_area_scanout_disable,\n .dpy_gl_update = gd_gl_area_scanout_flush,\n@@ -617,8 +614,14 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {\n .dpy_has_dmabuf = gd_has_dmabuf,\n };\n \n-#ifdef CONFIG_X11\n+static const DisplayGLCtxOps gl_area_ctx_ops = {\n+ .compatible_dcl = &dcl_gl_area_ops,\n+ .dpy_gl_ctx_create = gd_gl_area_create_context,\n+ .dpy_gl_ctx_destroy = gd_gl_area_destroy_context,\n+ .dpy_gl_ctx_make_current = gd_gl_area_make_current,\n+};\n \n+#ifdef CONFIG_X11\n static const DisplayChangeListenerOps dcl_egl_ops = {\n .dpy_name = \"gtk-egl\",\n .dpy_gfx_update = gd_egl_update,\n@@ -628,9 +631,6 @@ static const DisplayChangeListenerOps dcl_egl_ops = {\n .dpy_mouse_set = gd_mouse_set,\n .dpy_cursor_define = gd_cursor_define,\n \n- .dpy_gl_ctx_create = gd_egl_create_context,\n- .dpy_gl_ctx_destroy = qemu_egl_destroy_context,\n- .dpy_gl_ctx_make_current = gd_egl_make_current,\n .dpy_gl_scanout_disable = gd_egl_scanout_disable,\n .dpy_gl_scanout_texture = gd_egl_scanout_texture,\n .dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,\n@@ -641,6 +641,12 @@ static const DisplayChangeListenerOps dcl_egl_ops = {\n .dpy_has_dmabuf = gd_has_dmabuf,\n };\n \n+static const DisplayGLCtxOps egl_ctx_ops = {\n+ .compatible_dcl = &dcl_egl_ops,\n+ .dpy_gl_ctx_create = gd_egl_create_context,\n+ .dpy_gl_ctx_destroy = qemu_egl_destroy_context,\n+ .dpy_gl_ctx_make_current = gd_egl_make_current,\n+};\n #endif\n \n #endif /* CONFIG_OPENGL */\n@@ -2034,6 +2040,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n g_signal_connect(vc->gfx.drawing_area, \"realize\",\n G_CALLBACK(gl_area_realize), vc);\n vc->gfx.dcl.ops = &dcl_gl_area_ops;\n+ vc->gfx.dgc.ops = &gl_area_ctx_ops;\n } else {\n #ifdef CONFIG_X11\n vc->gfx.drawing_area = gtk_drawing_area_new();\n@@ -2048,6 +2055,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);\n #pragma GCC diagnostic pop\n vc->gfx.dcl.ops = &dcl_egl_ops;\n+ vc->gfx.dgc.ops = &egl_ctx_ops;\n vc->gfx.has_dmabuf = qemu_egl_has_dmabuf();\n #else\n abort();\n@@ -2083,7 +2091,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n vc->gfx.dcl.con = con;\n \n if (display_opengl) {\n- qemu_console_set_display_gl_ctx(con, &vc->gfx.dcl);\n+ qemu_console_set_display_gl_ctx(con, &vc->gfx.dgc);\n }\n register_displaychangelistener(&vc->gfx.dcl);\n \ndiff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c\nindex 5b950fbbea2f..39cab8cde737 100644\n--- a/ui/sdl2-gl.c\n+++ b/ui/sdl2-gl.c\n@@ -132,10 +132,10 @@ void sdl2_gl_redraw(struct sdl2_console *scon)\n }\n }\n \n-QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,\n+QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params)\n {\n- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);\n+ struct sdl2_console *scon = container_of(dgc, struct sdl2_console, dgc);\n SDL_GLContext ctx;\n \n assert(scon->opengl);\n@@ -167,17 +167,17 @@ QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,\n return (QEMUGLContext)ctx;\n }\n \n-void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)\n+void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx)\n {\n SDL_GLContext sdlctx = (SDL_GLContext)ctx;\n \n SDL_GL_DeleteContext(sdlctx);\n }\n \n-int sdl2_gl_make_context_current(DisplayChangeListener *dcl,\n+int sdl2_gl_make_context_current(DisplayGLCtx *dgc,\n QEMUGLContext ctx)\n {\n- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);\n+ struct sdl2_console *scon = container_of(dgc, struct sdl2_console, dgc);\n SDL_GLContext sdlctx = (SDL_GLContext)ctx;\n \n assert(scon->opengl);\ndiff --git a/ui/sdl2.c b/ui/sdl2.c\nindex bb186a381acd..0bd30504cfcc 100644\n--- a/ui/sdl2.c\n+++ b/ui/sdl2.c\n@@ -778,13 +778,17 @@ static const DisplayChangeListenerOps dcl_gl_ops = {\n .dpy_mouse_set = sdl_mouse_warp,\n .dpy_cursor_define = sdl_mouse_define,\n \n- .dpy_gl_ctx_create = sdl2_gl_create_context,\n- .dpy_gl_ctx_destroy = sdl2_gl_destroy_context,\n- .dpy_gl_ctx_make_current = sdl2_gl_make_context_current,\n .dpy_gl_scanout_disable = sdl2_gl_scanout_disable,\n .dpy_gl_scanout_texture = sdl2_gl_scanout_texture,\n .dpy_gl_update = sdl2_gl_scanout_flush,\n };\n+\n+static const DisplayGLCtxOps gl_ctx_ops = {\n+ .compatible_dcl = &dcl_gl_ops,\n+ .dpy_gl_ctx_create = sdl2_gl_create_context,\n+ .dpy_gl_ctx_destroy = sdl2_gl_destroy_context,\n+ .dpy_gl_ctx_make_current = sdl2_gl_make_context_current,\n+};\n #endif\n \n static void sdl2_display_early_init(DisplayOptions *o)\n@@ -860,6 +864,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)\n #ifdef CONFIG_OPENGL\n sdl2_console[i].opengl = display_opengl;\n sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;\n+ sdl2_console[i].dgc.ops = display_opengl ? &gl_ctx_ops : NULL;\n #else\n sdl2_console[i].opengl = 0;\n sdl2_console[i].dcl.ops = &dcl_2d_ops;\n@@ -867,7 +872,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)\n sdl2_console[i].dcl.con = con;\n sdl2_console[i].kbd = qkbd_state_init(con);\n if (display_opengl) {\n- qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dcl);\n+ qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dgc);\n }\n register_displaychangelistener(&sdl2_console[i].dcl);\n \ndiff --git a/ui/spice-display.c b/ui/spice-display.c\nindex ec501f129f07..798e0f6167e7 100644\n--- a/ui/spice-display.c\n+++ b/ui/spice-display.c\n@@ -908,12 +908,12 @@ static void spice_gl_switch(DisplayChangeListener *dcl,\n }\n }\n \n-static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,\n+static QEMUGLContext qemu_spice_gl_create_context(DisplayGLCtx *dgc,\n QEMUGLParams *params)\n {\n eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,\n qemu_egl_rn_ctx);\n- return qemu_egl_create_context(dcl, params);\n+ return qemu_egl_create_context(dgc, params);\n }\n \n static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)\n@@ -1105,10 +1105,6 @@ static const DisplayChangeListenerOps display_listener_gl_ops = {\n .dpy_mouse_set = display_mouse_set,\n .dpy_cursor_define = display_mouse_define,\n \n- .dpy_gl_ctx_create = qemu_spice_gl_create_context,\n- .dpy_gl_ctx_destroy = qemu_egl_destroy_context,\n- .dpy_gl_ctx_make_current = qemu_egl_make_context_current,\n-\n .dpy_gl_scanout_disable = qemu_spice_gl_scanout_disable,\n .dpy_gl_scanout_texture = qemu_spice_gl_scanout_texture,\n .dpy_gl_scanout_dmabuf = qemu_spice_gl_scanout_dmabuf,\n@@ -1118,6 +1114,13 @@ static const DisplayChangeListenerOps display_listener_gl_ops = {\n .dpy_gl_update = qemu_spice_gl_update,\n };\n \n+static const DisplayGLCtxOps gl_ctx_ops = {\n+ .compatible_dcl = &display_listener_gl_ops,\n+ .dpy_gl_ctx_create = qemu_spice_gl_create_context,\n+ .dpy_gl_ctx_destroy = qemu_egl_destroy_context,\n+ .dpy_gl_ctx_make_current = qemu_egl_make_context_current,\n+};\n+\n #endif /* HAVE_SPICE_GL */\n \n static void qemu_spice_display_init_one(QemuConsole *con)\n@@ -1130,6 +1133,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)\n #ifdef HAVE_SPICE_GL\n if (spice_opengl) {\n ssd->dcl.ops = &display_listener_gl_ops;\n+ ssd->dgc.ops = &gl_ctx_ops;\n ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);\n ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,\n qemu_spice_gl_block_timer, ssd);\n@@ -1156,7 +1160,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)\n qemu_spice_create_host_memslot(ssd);\n \n if (spice_opengl) {\n- qemu_console_set_display_gl_ctx(con, &ssd->dcl);\n+ qemu_console_set_display_gl_ctx(con, &ssd->dgc);\n }\n register_displaychangelistener(&ssd->dcl);\n }\n", "prefixes": [ "PULL", "v2", "16/36" ] }