ui: split the GL context in a different object
This will allow to have one GL context but a variable number of listeners. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
7cc712e986
commit
5e79d516e8
@ -179,6 +179,7 @@ typedef struct QemuDmaBuf {
|
|||||||
} QemuDmaBuf;
|
} QemuDmaBuf;
|
||||||
|
|
||||||
typedef struct DisplayState DisplayState;
|
typedef struct DisplayState DisplayState;
|
||||||
|
typedef struct DisplayGLCtx DisplayGLCtx;
|
||||||
|
|
||||||
typedef struct DisplayChangeListenerOps {
|
typedef struct DisplayChangeListenerOps {
|
||||||
const char *dpy_name;
|
const char *dpy_name;
|
||||||
@ -213,16 +214,6 @@ typedef struct DisplayChangeListenerOps {
|
|||||||
void (*dpy_cursor_define)(DisplayChangeListener *dcl,
|
void (*dpy_cursor_define)(DisplayChangeListener *dcl,
|
||||||
QEMUCursor *cursor);
|
QEMUCursor *cursor);
|
||||||
|
|
||||||
/* required if GL */
|
|
||||||
QEMUGLContext (*dpy_gl_ctx_create)(DisplayChangeListener *dcl,
|
|
||||||
QEMUGLParams *params);
|
|
||||||
/* required if GL */
|
|
||||||
void (*dpy_gl_ctx_destroy)(DisplayChangeListener *dcl,
|
|
||||||
QEMUGLContext ctx);
|
|
||||||
/* required if GL */
|
|
||||||
int (*dpy_gl_ctx_make_current)(DisplayChangeListener *dcl,
|
|
||||||
QEMUGLContext ctx);
|
|
||||||
|
|
||||||
/* required if GL */
|
/* required if GL */
|
||||||
void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl);
|
void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl);
|
||||||
/* required if GL */
|
/* required if GL */
|
||||||
@ -263,6 +254,26 @@ struct DisplayChangeListener {
|
|||||||
QLIST_ENTRY(DisplayChangeListener) next;
|
QLIST_ENTRY(DisplayChangeListener) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
QEMUGLContext (*dpy_gl_ctx_create)(DisplayGLCtx *dgc,
|
||||||
|
QEMUGLParams *params);
|
||||||
|
void (*dpy_gl_ctx_destroy)(DisplayGLCtx *dgc,
|
||||||
|
QEMUGLContext ctx);
|
||||||
|
int (*dpy_gl_ctx_make_current)(DisplayGLCtx *dgc,
|
||||||
|
QEMUGLContext ctx);
|
||||||
|
} DisplayGLCtxOps;
|
||||||
|
|
||||||
|
struct DisplayGLCtx {
|
||||||
|
const DisplayGLCtxOps *ops;
|
||||||
|
};
|
||||||
|
|
||||||
DisplayState *init_displaystate(void);
|
DisplayState *init_displaystate(void);
|
||||||
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
||||||
pixman_format_code_t format,
|
pixman_format_code_t format,
|
||||||
@ -409,8 +420,7 @@ void graphic_hw_gl_block(QemuConsole *con, bool block);
|
|||||||
|
|
||||||
void qemu_console_early_init(void);
|
void qemu_console_early_init(void);
|
||||||
|
|
||||||
void qemu_console_set_display_gl_ctx(QemuConsole *con,
|
void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *ctx);
|
||||||
DisplayChangeListener *dcl);
|
|
||||||
|
|
||||||
QemuConsole *qemu_console_lookup_by_index(unsigned int index);
|
QemuConsole *qemu_console_lookup_by_index(unsigned int index);
|
||||||
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
|
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
#include "ui/egl-helpers.h"
|
#include "ui/egl-helpers.h"
|
||||||
|
|
||||||
QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params);
|
QEMUGLParams *params);
|
||||||
void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx);
|
void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx);
|
||||||
int qemu_egl_make_context_current(DisplayChangeListener *dcl,
|
int qemu_egl_make_context_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx);
|
QEMUGLContext ctx);
|
||||||
|
|
||||||
#endif /* EGL_CONTEXT_H */
|
#endif /* EGL_CONTEXT_H */
|
||||||
|
@ -35,6 +35,7 @@ typedef struct GtkDisplayState GtkDisplayState;
|
|||||||
|
|
||||||
typedef struct VirtualGfxConsole {
|
typedef struct VirtualGfxConsole {
|
||||||
GtkWidget *drawing_area;
|
GtkWidget *drawing_area;
|
||||||
|
DisplayGLCtx dgc;
|
||||||
DisplayChangeListener dcl;
|
DisplayChangeListener dcl;
|
||||||
QKbdState *kbd;
|
QKbdState *kbd;
|
||||||
DisplaySurface *ds;
|
DisplaySurface *ds;
|
||||||
@ -165,7 +166,7 @@ void gd_egl_update(DisplayChangeListener *dcl,
|
|||||||
void gd_egl_refresh(DisplayChangeListener *dcl);
|
void gd_egl_refresh(DisplayChangeListener *dcl);
|
||||||
void gd_egl_switch(DisplayChangeListener *dcl,
|
void gd_egl_switch(DisplayChangeListener *dcl,
|
||||||
DisplaySurface *surface);
|
DisplaySurface *surface);
|
||||||
QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params);
|
QEMUGLParams *params);
|
||||||
void gd_egl_scanout_disable(DisplayChangeListener *dcl);
|
void gd_egl_scanout_disable(DisplayChangeListener *dcl);
|
||||||
void gd_egl_scanout_texture(DisplayChangeListener *dcl,
|
void gd_egl_scanout_texture(DisplayChangeListener *dcl,
|
||||||
@ -187,7 +188,7 @@ void gd_egl_flush(DisplayChangeListener *dcl,
|
|||||||
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
||||||
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||||
void gtk_egl_init(DisplayGLMode mode);
|
void gtk_egl_init(DisplayGLMode mode);
|
||||||
int gd_egl_make_current(DisplayChangeListener *dcl,
|
int gd_egl_make_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx);
|
QEMUGLContext ctx);
|
||||||
|
|
||||||
/* ui/gtk-gl-area.c */
|
/* ui/gtk-gl-area.c */
|
||||||
@ -198,9 +199,9 @@ void gd_gl_area_update(DisplayChangeListener *dcl,
|
|||||||
void gd_gl_area_refresh(DisplayChangeListener *dcl);
|
void gd_gl_area_refresh(DisplayChangeListener *dcl);
|
||||||
void gd_gl_area_switch(DisplayChangeListener *dcl,
|
void gd_gl_area_switch(DisplayChangeListener *dcl,
|
||||||
DisplaySurface *surface);
|
DisplaySurface *surface);
|
||||||
QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params);
|
QEMUGLParams *params);
|
||||||
void gd_gl_area_destroy_context(DisplayChangeListener *dcl,
|
void gd_gl_area_destroy_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx);
|
QEMUGLContext ctx);
|
||||||
void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,
|
void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,
|
||||||
QemuDmaBuf *dmabuf);
|
QemuDmaBuf *dmabuf);
|
||||||
@ -215,7 +216,7 @@ void gd_gl_area_scanout_disable(DisplayChangeListener *dcl);
|
|||||||
void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
||||||
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||||
void gtk_gl_area_init(void);
|
void gtk_gl_area_init(void);
|
||||||
int gd_gl_area_make_current(DisplayChangeListener *dcl,
|
int gd_gl_area_make_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx);
|
QEMUGLContext ctx);
|
||||||
|
|
||||||
/* gtk-clipboard.c */
|
/* gtk-clipboard.c */
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sdl2_console {
|
struct sdl2_console {
|
||||||
|
DisplayGLCtx dgc;
|
||||||
DisplayChangeListener dcl;
|
DisplayChangeListener dcl;
|
||||||
DisplaySurface *surface;
|
DisplaySurface *surface;
|
||||||
DisplayOptions *opts;
|
DisplayOptions *opts;
|
||||||
@ -65,10 +66,10 @@ void sdl2_gl_switch(DisplayChangeListener *dcl,
|
|||||||
void sdl2_gl_refresh(DisplayChangeListener *dcl);
|
void sdl2_gl_refresh(DisplayChangeListener *dcl);
|
||||||
void sdl2_gl_redraw(struct sdl2_console *scon);
|
void sdl2_gl_redraw(struct sdl2_console *scon);
|
||||||
|
|
||||||
QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params);
|
QEMUGLParams *params);
|
||||||
void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx);
|
void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx);
|
||||||
int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
|
int sdl2_gl_make_context_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx);
|
QEMUGLContext ctx);
|
||||||
|
|
||||||
void sdl2_gl_scanout_disable(DisplayChangeListener *dcl);
|
void sdl2_gl_scanout_disable(DisplayChangeListener *dcl);
|
||||||
|
@ -86,6 +86,7 @@ typedef struct SimpleSpiceCursor SimpleSpiceCursor;
|
|||||||
|
|
||||||
struct SimpleSpiceDisplay {
|
struct SimpleSpiceDisplay {
|
||||||
DisplaySurface *ds;
|
DisplaySurface *ds;
|
||||||
|
DisplayGLCtx dgc;
|
||||||
DisplayChangeListener dcl;
|
DisplayChangeListener dcl;
|
||||||
void *buf;
|
void *buf;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
|
26
ui/console.c
26
ui/console.c
@ -78,7 +78,7 @@ struct QemuConsole {
|
|||||||
DisplayState *ds;
|
DisplayState *ds;
|
||||||
DisplaySurface *surface;
|
DisplaySurface *surface;
|
||||||
int dcls;
|
int dcls;
|
||||||
DisplayChangeListener *gl;
|
DisplayGLCtx *gl;
|
||||||
int gl_block;
|
int gl_block;
|
||||||
QEMUTimer *gl_unblock_timer;
|
QEMUTimer *gl_unblock_timer;
|
||||||
int window_id;
|
int window_id;
|
||||||
@ -1458,17 +1458,24 @@ static bool dpy_compatible_with(QemuConsole *con,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_console_set_display_gl_ctx(QemuConsole *con,
|
void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl)
|
||||||
DisplayChangeListener *dcl)
|
|
||||||
{
|
{
|
||||||
/* display has opengl support */
|
/* display has opengl support */
|
||||||
assert(dcl->con);
|
assert(con);
|
||||||
if (dcl->con->gl) {
|
if (con->gl) {
|
||||||
fprintf(stderr, "can't register two opengl displays (%s, %s)\n",
|
error_report("The console already has an OpenGL context.");
|
||||||
dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
dcl->con->gl = dcl;
|
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)
|
void register_displaychangelistener(DisplayChangeListener *dcl)
|
||||||
@ -1480,8 +1487,7 @@ void register_displaychangelistener(DisplayChangeListener *dcl)
|
|||||||
|
|
||||||
assert(!dcl->ds);
|
assert(!dcl->ds);
|
||||||
|
|
||||||
if (dcl->con && dcl->con->gl &&
|
if (dcl->con && !dpy_gl_compatible_with(dcl->con, dcl)) {
|
||||||
dcl->con->gl != dcl) {
|
|
||||||
error_report("Display %s is incompatible with the GL context",
|
error_report("Display %s is incompatible with the GL context",
|
||||||
dcl->ops->dpy_name);
|
dcl->ops->dpy_name);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "ui/egl-context.h"
|
#include "ui/egl-context.h"
|
||||||
|
|
||||||
QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params)
|
QEMUGLParams *params)
|
||||||
{
|
{
|
||||||
EGLContext ctx;
|
EGLContext ctx;
|
||||||
@ -24,12 +24,12 @@ QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
|
void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
eglDestroyContext(qemu_egl_display, ctx);
|
eglDestroyContext(qemu_egl_display, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_egl_make_context_current(DisplayChangeListener *dcl,
|
int qemu_egl_make_context_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx)
|
QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
return eglMakeCurrent(qemu_egl_display,
|
return eglMakeCurrent(qemu_egl_display,
|
||||||
|
@ -38,12 +38,12 @@ static void egl_gfx_switch(DisplayChangeListener *dcl,
|
|||||||
edpy->ds = new_surface;
|
edpy->ds = new_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUGLContext egl_create_context(DisplayChangeListener *dcl,
|
static QEMUGLContext egl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params)
|
QEMUGLParams *params)
|
||||||
{
|
{
|
||||||
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||||
qemu_egl_rn_ctx);
|
qemu_egl_rn_ctx);
|
||||||
return qemu_egl_create_context(dcl, params);
|
return qemu_egl_create_context(dgc, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void egl_scanout_disable(DisplayChangeListener *dcl)
|
static void egl_scanout_disable(DisplayChangeListener *dcl)
|
||||||
@ -157,10 +157,6 @@ static const DisplayChangeListenerOps egl_ops = {
|
|||||||
.dpy_gfx_update = egl_gfx_update,
|
.dpy_gfx_update = egl_gfx_update,
|
||||||
.dpy_gfx_switch = egl_gfx_switch,
|
.dpy_gfx_switch = egl_gfx_switch,
|
||||||
|
|
||||||
.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,
|
|
||||||
|
|
||||||
.dpy_gl_scanout_disable = egl_scanout_disable,
|
.dpy_gl_scanout_disable = egl_scanout_disable,
|
||||||
.dpy_gl_scanout_texture = egl_scanout_texture,
|
.dpy_gl_scanout_texture = egl_scanout_texture,
|
||||||
.dpy_gl_scanout_dmabuf = egl_scanout_dmabuf,
|
.dpy_gl_scanout_dmabuf = egl_scanout_dmabuf,
|
||||||
@ -170,6 +166,13 @@ static const DisplayChangeListenerOps egl_ops = {
|
|||||||
.dpy_gl_update = egl_scanout_flush,
|
.dpy_gl_update = egl_scanout_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DisplayGLCtxOps eglctx_ops = {
|
||||||
|
.compatible_dcl = &egl_ops,
|
||||||
|
.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,
|
||||||
|
};
|
||||||
|
|
||||||
static void early_egl_headless_init(DisplayOptions *opts)
|
static void early_egl_headless_init(DisplayOptions *opts)
|
||||||
{
|
{
|
||||||
display_opengl = 1;
|
display_opengl = 1;
|
||||||
@ -188,6 +191,8 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (idx = 0;; idx++) {
|
for (idx = 0;; idx++) {
|
||||||
|
DisplayGLCtx *ctx;
|
||||||
|
|
||||||
con = qemu_console_lookup_by_index(idx);
|
con = qemu_console_lookup_by_index(idx);
|
||||||
if (!con || !qemu_console_is_graphic(con)) {
|
if (!con || !qemu_console_is_graphic(con)) {
|
||||||
break;
|
break;
|
||||||
@ -197,7 +202,9 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts)
|
|||||||
edpy->dcl.con = con;
|
edpy->dcl.con = con;
|
||||||
edpy->dcl.ops = &egl_ops;
|
edpy->dcl.ops = &egl_ops;
|
||||||
edpy->gls = qemu_gl_init_shader();
|
edpy->gls = qemu_gl_init_shader();
|
||||||
qemu_console_set_display_gl_ctx(con, &edpy->dcl);
|
ctx = g_new0(DisplayGLCtx, 1);
|
||||||
|
ctx->ops = &eglctx_ops;
|
||||||
|
qemu_console_set_display_gl_ctx(con, ctx);
|
||||||
register_displaychangelistener(&edpy->dcl);
|
register_displaychangelistener(&edpy->dcl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
ui/gtk-egl.c
10
ui/gtk-egl.c
@ -197,14 +197,14 @@ void gd_egl_switch(DisplayChangeListener *dcl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params)
|
QEMUGLParams *params)
|
||||||
{
|
{
|
||||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);
|
||||||
|
|
||||||
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
|
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
|
||||||
vc->gfx.esurface, vc->gfx.ectx);
|
vc->gfx.esurface, vc->gfx.ectx);
|
||||||
return qemu_egl_create_context(dcl, params);
|
return qemu_egl_create_context(dgc, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gd_egl_scanout_disable(DisplayChangeListener *dcl)
|
void gd_egl_scanout_disable(DisplayChangeListener *dcl)
|
||||||
@ -360,10 +360,10 @@ void gtk_egl_init(DisplayGLMode mode)
|
|||||||
display_opengl = 1;
|
display_opengl = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gd_egl_make_current(DisplayChangeListener *dcl,
|
int gd_egl_make_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx)
|
QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);
|
||||||
|
|
||||||
return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
|
return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
|
||||||
vc->gfx.esurface, ctx);
|
vc->gfx.esurface, ctx);
|
||||||
|
@ -170,10 +170,10 @@ void gd_gl_area_switch(DisplayChangeListener *dcl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params)
|
QEMUGLParams *params)
|
||||||
{
|
{
|
||||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);
|
||||||
GdkWindow *window;
|
GdkWindow *window;
|
||||||
GdkGLContext *ctx;
|
GdkGLContext *ctx;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
@ -199,7 +199,7 @@ QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
|
void gd_gl_area_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ void gtk_gl_area_init(void)
|
|||||||
display_opengl = 1;
|
display_opengl = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gd_gl_area_make_current(DisplayChangeListener *dcl,
|
int gd_gl_area_make_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx)
|
QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
gdk_gl_context_make_current(ctx);
|
gdk_gl_context_make_current(ctx);
|
||||||
|
24
ui/gtk.c
24
ui/gtk.c
@ -606,9 +606,6 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
|
|||||||
.dpy_mouse_set = gd_mouse_set,
|
.dpy_mouse_set = gd_mouse_set,
|
||||||
.dpy_cursor_define = gd_cursor_define,
|
.dpy_cursor_define = gd_cursor_define,
|
||||||
|
|
||||||
.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,
|
|
||||||
.dpy_gl_scanout_texture = gd_gl_area_scanout_texture,
|
.dpy_gl_scanout_texture = gd_gl_area_scanout_texture,
|
||||||
.dpy_gl_scanout_disable = gd_gl_area_scanout_disable,
|
.dpy_gl_scanout_disable = gd_gl_area_scanout_disable,
|
||||||
.dpy_gl_update = gd_gl_area_scanout_flush,
|
.dpy_gl_update = gd_gl_area_scanout_flush,
|
||||||
@ -617,8 +614,14 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
|
|||||||
.dpy_has_dmabuf = gd_has_dmabuf,
|
.dpy_has_dmabuf = gd_has_dmabuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_X11
|
static const DisplayGLCtxOps gl_area_ctx_ops = {
|
||||||
|
.compatible_dcl = &dcl_gl_area_ops,
|
||||||
|
.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,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_X11
|
||||||
static const DisplayChangeListenerOps dcl_egl_ops = {
|
static const DisplayChangeListenerOps dcl_egl_ops = {
|
||||||
.dpy_name = "gtk-egl",
|
.dpy_name = "gtk-egl",
|
||||||
.dpy_gfx_update = gd_egl_update,
|
.dpy_gfx_update = gd_egl_update,
|
||||||
@ -628,9 +631,6 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
|
|||||||
.dpy_mouse_set = gd_mouse_set,
|
.dpy_mouse_set = gd_mouse_set,
|
||||||
.dpy_cursor_define = gd_cursor_define,
|
.dpy_cursor_define = gd_cursor_define,
|
||||||
|
|
||||||
.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,
|
|
||||||
.dpy_gl_scanout_disable = gd_egl_scanout_disable,
|
.dpy_gl_scanout_disable = gd_egl_scanout_disable,
|
||||||
.dpy_gl_scanout_texture = gd_egl_scanout_texture,
|
.dpy_gl_scanout_texture = gd_egl_scanout_texture,
|
||||||
.dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,
|
.dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,
|
||||||
@ -641,6 +641,12 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
|
|||||||
.dpy_has_dmabuf = gd_has_dmabuf,
|
.dpy_has_dmabuf = gd_has_dmabuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DisplayGLCtxOps egl_ctx_ops = {
|
||||||
|
.compatible_dcl = &dcl_egl_ops,
|
||||||
|
.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,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_OPENGL */
|
#endif /* CONFIG_OPENGL */
|
||||||
@ -2034,6 +2040,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
|||||||
g_signal_connect(vc->gfx.drawing_area, "realize",
|
g_signal_connect(vc->gfx.drawing_area, "realize",
|
||||||
G_CALLBACK(gl_area_realize), vc);
|
G_CALLBACK(gl_area_realize), vc);
|
||||||
vc->gfx.dcl.ops = &dcl_gl_area_ops;
|
vc->gfx.dcl.ops = &dcl_gl_area_ops;
|
||||||
|
vc->gfx.dgc.ops = &gl_area_ctx_ops;
|
||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_X11
|
#ifdef CONFIG_X11
|
||||||
vc->gfx.drawing_area = gtk_drawing_area_new();
|
vc->gfx.drawing_area = gtk_drawing_area_new();
|
||||||
@ -2048,6 +2055,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
|||||||
gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
|
gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
vc->gfx.dcl.ops = &dcl_egl_ops;
|
vc->gfx.dcl.ops = &dcl_egl_ops;
|
||||||
|
vc->gfx.dgc.ops = &egl_ctx_ops;
|
||||||
vc->gfx.has_dmabuf = qemu_egl_has_dmabuf();
|
vc->gfx.has_dmabuf = qemu_egl_has_dmabuf();
|
||||||
#else
|
#else
|
||||||
abort();
|
abort();
|
||||||
@ -2083,7 +2091,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
|||||||
vc->gfx.dcl.con = con;
|
vc->gfx.dcl.con = con;
|
||||||
|
|
||||||
if (display_opengl) {
|
if (display_opengl) {
|
||||||
qemu_console_set_display_gl_ctx(con, &vc->gfx.dcl);
|
qemu_console_set_display_gl_ctx(con, &vc->gfx.dgc);
|
||||||
}
|
}
|
||||||
register_displaychangelistener(&vc->gfx.dcl);
|
register_displaychangelistener(&vc->gfx.dcl);
|
||||||
|
|
||||||
|
10
ui/sdl2-gl.c
10
ui/sdl2-gl.c
@ -132,10 +132,10 @@ void sdl2_gl_redraw(struct sdl2_console *scon)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
|
QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params)
|
QEMUGLParams *params)
|
||||||
{
|
{
|
||||||
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
|
struct sdl2_console *scon = container_of(dgc, struct sdl2_console, dgc);
|
||||||
SDL_GLContext ctx;
|
SDL_GLContext ctx;
|
||||||
|
|
||||||
assert(scon->opengl);
|
assert(scon->opengl);
|
||||||
@ -167,17 +167,17 @@ QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
|
|||||||
return (QEMUGLContext)ctx;
|
return (QEMUGLContext)ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
|
void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
SDL_GLContext sdlctx = (SDL_GLContext)ctx;
|
SDL_GLContext sdlctx = (SDL_GLContext)ctx;
|
||||||
|
|
||||||
SDL_GL_DeleteContext(sdlctx);
|
SDL_GL_DeleteContext(sdlctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
|
int sdl2_gl_make_context_current(DisplayGLCtx *dgc,
|
||||||
QEMUGLContext ctx)
|
QEMUGLContext ctx)
|
||||||
{
|
{
|
||||||
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
|
struct sdl2_console *scon = container_of(dgc, struct sdl2_console, dgc);
|
||||||
SDL_GLContext sdlctx = (SDL_GLContext)ctx;
|
SDL_GLContext sdlctx = (SDL_GLContext)ctx;
|
||||||
|
|
||||||
assert(scon->opengl);
|
assert(scon->opengl);
|
||||||
|
13
ui/sdl2.c
13
ui/sdl2.c
@ -778,13 +778,17 @@ static const DisplayChangeListenerOps dcl_gl_ops = {
|
|||||||
.dpy_mouse_set = sdl_mouse_warp,
|
.dpy_mouse_set = sdl_mouse_warp,
|
||||||
.dpy_cursor_define = sdl_mouse_define,
|
.dpy_cursor_define = sdl_mouse_define,
|
||||||
|
|
||||||
.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,
|
|
||||||
.dpy_gl_scanout_disable = sdl2_gl_scanout_disable,
|
.dpy_gl_scanout_disable = sdl2_gl_scanout_disable,
|
||||||
.dpy_gl_scanout_texture = sdl2_gl_scanout_texture,
|
.dpy_gl_scanout_texture = sdl2_gl_scanout_texture,
|
||||||
.dpy_gl_update = sdl2_gl_scanout_flush,
|
.dpy_gl_update = sdl2_gl_scanout_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DisplayGLCtxOps gl_ctx_ops = {
|
||||||
|
.compatible_dcl = &dcl_gl_ops,
|
||||||
|
.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,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void sdl2_display_early_init(DisplayOptions *o)
|
static void sdl2_display_early_init(DisplayOptions *o)
|
||||||
@ -860,6 +864,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
|
|||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
sdl2_console[i].opengl = display_opengl;
|
sdl2_console[i].opengl = display_opengl;
|
||||||
sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;
|
sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;
|
||||||
|
sdl2_console[i].dgc.ops = display_opengl ? &gl_ctx_ops : NULL;
|
||||||
#else
|
#else
|
||||||
sdl2_console[i].opengl = 0;
|
sdl2_console[i].opengl = 0;
|
||||||
sdl2_console[i].dcl.ops = &dcl_2d_ops;
|
sdl2_console[i].dcl.ops = &dcl_2d_ops;
|
||||||
@ -867,7 +872,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
|
|||||||
sdl2_console[i].dcl.con = con;
|
sdl2_console[i].dcl.con = con;
|
||||||
sdl2_console[i].kbd = qkbd_state_init(con);
|
sdl2_console[i].kbd = qkbd_state_init(con);
|
||||||
if (display_opengl) {
|
if (display_opengl) {
|
||||||
qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dcl);
|
qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dgc);
|
||||||
}
|
}
|
||||||
register_displaychangelistener(&sdl2_console[i].dcl);
|
register_displaychangelistener(&sdl2_console[i].dcl);
|
||||||
|
|
||||||
|
@ -908,12 +908,12 @@ static void spice_gl_switch(DisplayChangeListener *dcl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
|
static QEMUGLContext qemu_spice_gl_create_context(DisplayGLCtx *dgc,
|
||||||
QEMUGLParams *params)
|
QEMUGLParams *params)
|
||||||
{
|
{
|
||||||
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||||
qemu_egl_rn_ctx);
|
qemu_egl_rn_ctx);
|
||||||
return qemu_egl_create_context(dcl, params);
|
return qemu_egl_create_context(dgc, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)
|
static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)
|
||||||
@ -1105,10 +1105,6 @@ static const DisplayChangeListenerOps display_listener_gl_ops = {
|
|||||||
.dpy_mouse_set = display_mouse_set,
|
.dpy_mouse_set = display_mouse_set,
|
||||||
.dpy_cursor_define = display_mouse_define,
|
.dpy_cursor_define = display_mouse_define,
|
||||||
|
|
||||||
.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,
|
|
||||||
|
|
||||||
.dpy_gl_scanout_disable = qemu_spice_gl_scanout_disable,
|
.dpy_gl_scanout_disable = qemu_spice_gl_scanout_disable,
|
||||||
.dpy_gl_scanout_texture = qemu_spice_gl_scanout_texture,
|
.dpy_gl_scanout_texture = qemu_spice_gl_scanout_texture,
|
||||||
.dpy_gl_scanout_dmabuf = qemu_spice_gl_scanout_dmabuf,
|
.dpy_gl_scanout_dmabuf = qemu_spice_gl_scanout_dmabuf,
|
||||||
@ -1118,6 +1114,13 @@ static const DisplayChangeListenerOps display_listener_gl_ops = {
|
|||||||
.dpy_gl_update = qemu_spice_gl_update,
|
.dpy_gl_update = qemu_spice_gl_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DisplayGLCtxOps gl_ctx_ops = {
|
||||||
|
.compatible_dcl = &display_listener_gl_ops,
|
||||||
|
.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,
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* HAVE_SPICE_GL */
|
#endif /* HAVE_SPICE_GL */
|
||||||
|
|
||||||
static void qemu_spice_display_init_one(QemuConsole *con)
|
static void qemu_spice_display_init_one(QemuConsole *con)
|
||||||
@ -1130,6 +1133,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)
|
|||||||
#ifdef HAVE_SPICE_GL
|
#ifdef HAVE_SPICE_GL
|
||||||
if (spice_opengl) {
|
if (spice_opengl) {
|
||||||
ssd->dcl.ops = &display_listener_gl_ops;
|
ssd->dcl.ops = &display_listener_gl_ops;
|
||||||
|
ssd->dgc.ops = &gl_ctx_ops;
|
||||||
ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
|
ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
|
||||||
ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
|
ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
|
||||||
qemu_spice_gl_block_timer, ssd);
|
qemu_spice_gl_block_timer, ssd);
|
||||||
@ -1156,7 +1160,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)
|
|||||||
qemu_spice_create_host_memslot(ssd);
|
qemu_spice_create_host_memslot(ssd);
|
||||||
|
|
||||||
if (spice_opengl) {
|
if (spice_opengl) {
|
||||||
qemu_console_set_display_gl_ctx(con, &ssd->dcl);
|
qemu_console_set_display_gl_ctx(con, &ssd->dgc);
|
||||||
}
|
}
|
||||||
register_displaychangelistener(&ssd->dcl);
|
register_displaychangelistener(&ssd->dcl);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user