gtk/opengl: add opengl context and scanout support (GtkGLArea)
This allows virtio-gpu to render in 3d mode. Uses native opengl support which is present in gtk versions 3.16 and newer. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
4782aeb79f
commit
925a040002
8
configure
vendored
8
configure
vendored
@ -328,6 +328,7 @@ glusterfs_zerofill="no"
|
|||||||
archipelago="no"
|
archipelago="no"
|
||||||
gtk=""
|
gtk=""
|
||||||
gtkabi=""
|
gtkabi=""
|
||||||
|
gtk_gl="no"
|
||||||
gnutls=""
|
gnutls=""
|
||||||
gnutls_hash=""
|
gnutls_hash=""
|
||||||
vte=""
|
vte=""
|
||||||
@ -3236,6 +3237,9 @@ if test "$opengl" != "no" ; then
|
|||||||
opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
|
opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
|
||||||
opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
|
opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
|
||||||
opengl=yes
|
opengl=yes
|
||||||
|
if test "$gtk" = "yes" && $pkg_config --exists "$gtkpackage >= 3.16"; then
|
||||||
|
gtk_gl="yes"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
if test "$opengl" = "yes" ; then
|
if test "$opengl" = "yes" ; then
|
||||||
feature_not_found "opengl" "Please install opengl (mesa) devel pkgs: $opengl_pkgs"
|
feature_not_found "opengl" "Please install opengl (mesa) devel pkgs: $opengl_pkgs"
|
||||||
@ -4602,6 +4606,7 @@ fi
|
|||||||
echo "pixman $pixman"
|
echo "pixman $pixman"
|
||||||
echo "SDL support $sdl"
|
echo "SDL support $sdl"
|
||||||
echo "GTK support $gtk"
|
echo "GTK support $gtk"
|
||||||
|
echo "GTK GL support $gtk_gl"
|
||||||
echo "GNUTLS support $gnutls"
|
echo "GNUTLS support $gnutls"
|
||||||
echo "GNUTLS hash $gnutls_hash"
|
echo "GNUTLS hash $gnutls_hash"
|
||||||
echo "GNUTLS gcrypt $gnutls_gcrypt"
|
echo "GNUTLS gcrypt $gnutls_gcrypt"
|
||||||
@ -4961,6 +4966,9 @@ if test "$gtk" = "yes" ; then
|
|||||||
echo "CONFIG_GTK=y" >> $config_host_mak
|
echo "CONFIG_GTK=y" >> $config_host_mak
|
||||||
echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak
|
echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak
|
||||||
echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak
|
echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak
|
||||||
|
if test "$gtk_gl" = "yes" ; then
|
||||||
|
echo "CONFIG_GTK_GL=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if test "$gnutls" = "yes" ; then
|
if test "$gnutls" = "yes" ; then
|
||||||
echo "CONFIG_GNUTLS=y" >> $config_host_mak
|
echo "CONFIG_GNUTLS=y" >> $config_host_mak
|
||||||
|
@ -108,4 +108,27 @@ void gtk_egl_init(void);
|
|||||||
int gd_egl_make_current(DisplayChangeListener *dcl,
|
int gd_egl_make_current(DisplayChangeListener *dcl,
|
||||||
QEMUGLContext ctx);
|
QEMUGLContext ctx);
|
||||||
|
|
||||||
|
/* ui/gtk-gl-area.c */
|
||||||
|
void gd_gl_area_init(VirtualConsole *vc);
|
||||||
|
void gd_gl_area_draw(VirtualConsole *vc);
|
||||||
|
void gd_gl_area_update(DisplayChangeListener *dcl,
|
||||||
|
int x, int y, int w, int h);
|
||||||
|
void gd_gl_area_refresh(DisplayChangeListener *dcl);
|
||||||
|
void gd_gl_area_switch(DisplayChangeListener *dcl,
|
||||||
|
DisplaySurface *surface);
|
||||||
|
QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
|
||||||
|
QEMUGLParams *params);
|
||||||
|
void gd_gl_area_destroy_context(DisplayChangeListener *dcl,
|
||||||
|
QEMUGLContext ctx);
|
||||||
|
void gd_gl_area_scanout(DisplayChangeListener *dcl,
|
||||||
|
uint32_t backing_id, bool backing_y_0_top,
|
||||||
|
uint32_t x, uint32_t y,
|
||||||
|
uint32_t w, uint32_t h);
|
||||||
|
void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
||||||
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||||
|
void gtk_gl_area_init(void);
|
||||||
|
QEMUGLContext gd_gl_area_get_current_context(DisplayChangeListener *dcl);
|
||||||
|
int gd_gl_area_make_current(DisplayChangeListener *dcl,
|
||||||
|
QEMUGLContext ctx);
|
||||||
|
|
||||||
#endif /* UI_GTK_H */
|
#endif /* UI_GTK_H */
|
||||||
|
@ -32,11 +32,16 @@ common-obj-y += shader.o
|
|||||||
common-obj-y += console-gl.o
|
common-obj-y += console-gl.o
|
||||||
common-obj-y += egl-helpers.o
|
common-obj-y += egl-helpers.o
|
||||||
common-obj-y += egl-context.o
|
common-obj-y += egl-context.o
|
||||||
|
ifeq ($(CONFIG_GTK_GL),y)
|
||||||
|
common-obj-$(CONFIG_GTK) += gtk-gl-area.o
|
||||||
|
else
|
||||||
common-obj-$(CONFIG_GTK) += gtk-egl.o
|
common-obj-$(CONFIG_GTK) += gtk-egl.o
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
|
gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
|
||||||
gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
|
gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
|
||||||
|
gtk-gl-area.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
|
||||||
shader.o-cflags += $(OPENGL_CFLAGS)
|
shader.o-cflags += $(OPENGL_CFLAGS)
|
||||||
console-gl.o-cflags += $(OPENGL_CFLAGS)
|
console-gl.o-cflags += $(OPENGL_CFLAGS)
|
||||||
egl-helpers.o-cflags += $(OPENGL_CFLAGS)
|
egl-helpers.o-cflags += $(OPENGL_CFLAGS)
|
||||||
|
223
ui/gtk-gl-area.c
Normal file
223
ui/gtk-gl-area.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* GTK UI -- glarea opengl code.
|
||||||
|
*
|
||||||
|
* Requires 3.16+ (GtkGLArea widget).
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||||
|
* See the COPYING file in the top-level directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include "ui/console.h"
|
||||||
|
#include "ui/gtk.h"
|
||||||
|
#include "ui/egl-helpers.h"
|
||||||
|
|
||||||
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
|
static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
|
||||||
|
{
|
||||||
|
if (vc->gfx.scanout_mode == scanout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vc->gfx.scanout_mode = scanout;
|
||||||
|
if (!vc->gfx.scanout_mode) {
|
||||||
|
if (vc->gfx.fbo_id) {
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_COLOR_ATTACHMENT0_EXT,
|
||||||
|
GL_TEXTURE_2D, 0, 0);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
glDeleteFramebuffers(1, &vc->gfx.fbo_id);
|
||||||
|
vc->gfx.fbo_id = 0;
|
||||||
|
}
|
||||||
|
if (vc->gfx.surface) {
|
||||||
|
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
|
||||||
|
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DisplayState Callbacks (opengl version) **/
|
||||||
|
|
||||||
|
void gd_gl_area_draw(VirtualConsole *vc)
|
||||||
|
{
|
||||||
|
int ww, wh, y1, y2;
|
||||||
|
|
||||||
|
if (!vc->gfx.gls) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
|
||||||
|
wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
|
||||||
|
|
||||||
|
if (vc->gfx.scanout_mode) {
|
||||||
|
if (!vc->gfx.fbo_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
|
||||||
|
/* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
|
||||||
|
|
||||||
|
glViewport(0, 0, ww, wh);
|
||||||
|
y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
|
||||||
|
y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
|
||||||
|
glBlitFramebuffer(0, y1, vc->gfx.w, y2,
|
||||||
|
0, 0, ww, wh,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
} else {
|
||||||
|
if (!vc->gfx.ds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
|
||||||
|
surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
|
||||||
|
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_gl_area_update(DisplayChangeListener *dcl,
|
||||||
|
int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
|
||||||
|
if (!vc->gfx.gls || !vc->gfx.ds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
|
||||||
|
vc->gfx.glupdates++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_gl_area_refresh(DisplayChangeListener *dcl)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
|
||||||
|
if (!vc->gfx.gls) {
|
||||||
|
if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
vc->gfx.gls = console_gl_init_context();
|
||||||
|
if (vc->gfx.ds) {
|
||||||
|
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphic_hw_update(dcl->con);
|
||||||
|
|
||||||
|
if (vc->gfx.glupdates) {
|
||||||
|
vc->gfx.glupdates = 0;
|
||||||
|
gtk_gl_area_set_scanout_mode(vc, false);
|
||||||
|
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_gl_area_switch(DisplayChangeListener *dcl,
|
||||||
|
DisplaySurface *surface)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
bool resized = true;
|
||||||
|
|
||||||
|
trace_gd_switch(vc->label, surface_width(surface), surface_height(surface));
|
||||||
|
|
||||||
|
if (vc->gfx.ds &&
|
||||||
|
surface_width(vc->gfx.ds) == surface_width(surface) &&
|
||||||
|
surface_height(vc->gfx.ds) == surface_height(surface)) {
|
||||||
|
resized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vc->gfx.gls) {
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
|
||||||
|
surface_gl_create_texture(vc->gfx.gls, surface);
|
||||||
|
}
|
||||||
|
vc->gfx.ds = surface;
|
||||||
|
|
||||||
|
if (resized) {
|
||||||
|
gd_update_windowsize(vc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
|
||||||
|
QEMUGLParams *params)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
GdkWindow *window;
|
||||||
|
GdkGLContext *ctx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
window = gtk_widget_get_window(vc->gfx.drawing_area);
|
||||||
|
ctx = gdk_window_create_gl_context(window, &err);
|
||||||
|
gdk_gl_context_set_required_version(ctx,
|
||||||
|
params->major_ver,
|
||||||
|
params->minor_ver);
|
||||||
|
gdk_gl_context_realize(ctx, &err);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_gl_area_scanout(DisplayChangeListener *dcl,
|
||||||
|
uint32_t backing_id, bool backing_y_0_top,
|
||||||
|
uint32_t x, uint32_t y,
|
||||||
|
uint32_t w, uint32_t h)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
|
||||||
|
vc->gfx.x = x;
|
||||||
|
vc->gfx.y = y;
|
||||||
|
vc->gfx.w = w;
|
||||||
|
vc->gfx.h = h;
|
||||||
|
vc->gfx.tex_id = backing_id;
|
||||||
|
vc->gfx.y0_top = backing_y_0_top;
|
||||||
|
|
||||||
|
gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
|
||||||
|
if (vc->gfx.tex_id == 0 || vc->gfx.w == 0 || vc->gfx.h == 0) {
|
||||||
|
gtk_gl_area_set_scanout_mode(vc, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_gl_area_set_scanout_mode(vc, true);
|
||||||
|
if (!vc->gfx.fbo_id) {
|
||||||
|
glGenFramebuffers(1, &vc->gfx.fbo_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||||
|
GL_TEXTURE_2D, vc->gfx.tex_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
||||||
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
|
||||||
|
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtk_gl_area_init(void)
|
||||||
|
{
|
||||||
|
display_opengl = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QEMUGLContext gd_gl_area_get_current_context(DisplayChangeListener *dcl)
|
||||||
|
{
|
||||||
|
return gdk_gl_context_get_current();
|
||||||
|
}
|
||||||
|
|
||||||
|
int gd_gl_area_make_current(DisplayChangeListener *dcl,
|
||||||
|
QEMUGLContext ctx)
|
||||||
|
{
|
||||||
|
gdk_gl_context_make_current(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
142
ui/gtk.c
142
ui/gtk.c
@ -367,6 +367,12 @@ static void gd_update_full_redraw(VirtualConsole *vc)
|
|||||||
GtkWidget *area = vc->gfx.drawing_area;
|
GtkWidget *area = vc->gfx.drawing_area;
|
||||||
int ww, wh;
|
int ww, wh;
|
||||||
gdk_drawable_get_size(gtk_widget_get_window(area), &ww, &wh);
|
gdk_drawable_get_size(gtk_widget_get_window(area), &ww, &wh);
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
if (vc->gfx.gls) {
|
||||||
|
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
gtk_widget_queue_draw_area(area, 0, 0, ww, wh);
|
gtk_widget_queue_draw_area(area, 0, 0, ww, wh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,6 +613,27 @@ static const DisplayChangeListenerOps dcl_ops = {
|
|||||||
|
|
||||||
/** DisplayState Callbacks (opengl version) **/
|
/** DisplayState Callbacks (opengl version) **/
|
||||||
|
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
|
||||||
|
static const DisplayChangeListenerOps dcl_gl_area_ops = {
|
||||||
|
.dpy_name = "gtk-egl",
|
||||||
|
.dpy_gfx_update = gd_gl_area_update,
|
||||||
|
.dpy_gfx_switch = gd_gl_area_switch,
|
||||||
|
.dpy_gfx_check_format = console_gl_check_format,
|
||||||
|
.dpy_refresh = gd_gl_area_refresh,
|
||||||
|
.dpy_mouse_set = gd_mouse_set,
|
||||||
|
.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_ctx_get_current = gd_gl_area_get_current_context,
|
||||||
|
.dpy_gl_scanout = gd_gl_area_scanout,
|
||||||
|
.dpy_gl_update = gd_gl_area_scanout_flush,
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
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,
|
||||||
@ -624,7 +651,8 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
|
|||||||
.dpy_gl_update = gd_egl_scanout_flush,
|
.dpy_gl_update = gd_egl_scanout_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif /* CONFIG_GTK_GL */
|
||||||
|
#endif /* CONFIG_OPENGL */
|
||||||
|
|
||||||
/** QEMU Events **/
|
/** QEMU Events **/
|
||||||
|
|
||||||
@ -674,6 +702,39 @@ static gboolean gd_window_close(GtkWidget *widget, GdkEvent *event,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gd_set_ui_info(VirtualConsole *vc, gint width, gint height)
|
||||||
|
{
|
||||||
|
QemuUIInfo info;
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.width = width;
|
||||||
|
info.height = height;
|
||||||
|
dpy_set_ui_info(vc->gfx.dcl.con, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
|
||||||
|
static gboolean gd_render_event(GtkGLArea *area, GdkGLContext *context,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = opaque;
|
||||||
|
|
||||||
|
if (vc->gfx.gls) {
|
||||||
|
gd_gl_area_draw(vc);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gd_resize_event(GtkGLArea *area,
|
||||||
|
gint width, gint height, gpointer *opaque)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = (void *)opaque;
|
||||||
|
|
||||||
|
gd_set_ui_info(vc, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
|
static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
|
||||||
{
|
{
|
||||||
VirtualConsole *vc = opaque;
|
VirtualConsole *vc = opaque;
|
||||||
@ -684,8 +745,13 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
|
|||||||
|
|
||||||
#if defined(CONFIG_OPENGL)
|
#if defined(CONFIG_OPENGL)
|
||||||
if (vc->gfx.gls) {
|
if (vc->gfx.gls) {
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
/* invoke render callback please */
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
gd_egl_draw(vc);
|
gd_egl_draw(vc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1473,12 +1539,8 @@ static gboolean gd_configure(GtkWidget *widget,
|
|||||||
GdkEventConfigure *cfg, gpointer opaque)
|
GdkEventConfigure *cfg, gpointer opaque)
|
||||||
{
|
{
|
||||||
VirtualConsole *vc = opaque;
|
VirtualConsole *vc = opaque;
|
||||||
QemuUIInfo info;
|
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
gd_set_ui_info(vc, cfg->width, cfg->height);
|
||||||
info.width = cfg->width;
|
|
||||||
info.height = cfg->height;
|
|
||||||
dpy_set_ui_info(vc->gfx.dcl.con, &info);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1635,6 +1697,15 @@ static void gd_connect_vc_gfx_signals(VirtualConsole *vc)
|
|||||||
#if GTK_CHECK_VERSION(3, 0, 0)
|
#if GTK_CHECK_VERSION(3, 0, 0)
|
||||||
g_signal_connect(vc->gfx.drawing_area, "draw",
|
g_signal_connect(vc->gfx.drawing_area, "draw",
|
||||||
G_CALLBACK(gd_draw_event), vc);
|
G_CALLBACK(gd_draw_event), vc);
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
if (display_opengl) {
|
||||||
|
/* wire up GtkGlArea events */
|
||||||
|
g_signal_connect(vc->gfx.drawing_area, "render",
|
||||||
|
G_CALLBACK(gd_render_event), vc);
|
||||||
|
g_signal_connect(vc->gfx.drawing_area, "resize",
|
||||||
|
G_CALLBACK(gd_resize_event), vc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
g_signal_connect(vc->gfx.drawing_area, "expose-event",
|
g_signal_connect(vc->gfx.drawing_area, "expose-event",
|
||||||
G_CALLBACK(gd_expose_event), vc);
|
G_CALLBACK(gd_expose_event), vc);
|
||||||
@ -1743,7 +1814,37 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
|||||||
vc->gfx.scale_x = 1.0;
|
vc->gfx.scale_x = 1.0;
|
||||||
vc->gfx.scale_y = 1.0;
|
vc->gfx.scale_y = 1.0;
|
||||||
|
|
||||||
vc->gfx.drawing_area = gtk_drawing_area_new();
|
#if defined(CONFIG_OPENGL)
|
||||||
|
if (display_opengl) {
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
vc->gfx.drawing_area = gtk_gl_area_new();
|
||||||
|
vc->gfx.dcl.ops = &dcl_gl_area_ops;
|
||||||
|
#else
|
||||||
|
vc->gfx.drawing_area = gtk_drawing_area_new();
|
||||||
|
/*
|
||||||
|
* gtk_widget_set_double_buffered() was deprecated in 3.14.
|
||||||
|
* It is required for opengl rendering on X11 though. A
|
||||||
|
* proper replacement (native opengl support) is only
|
||||||
|
* available in 3.16+. Silence the warning if possible.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#endif
|
||||||
|
gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
|
||||||
|
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
vc->gfx.dcl.ops = &dcl_egl_ops;
|
||||||
|
#endif /* CONFIG_GTK_GL */
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
vc->gfx.drawing_area = gtk_drawing_area_new();
|
||||||
|
vc->gfx.dcl.ops = &dcl_ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gtk_widget_add_events(vc->gfx.drawing_area,
|
gtk_widget_add_events(vc->gfx.drawing_area,
|
||||||
GDK_POINTER_MOTION_MASK |
|
GDK_POINTER_MOTION_MASK |
|
||||||
GDK_BUTTON_PRESS_MASK |
|
GDK_BUTTON_PRESS_MASK |
|
||||||
@ -1761,29 +1862,6 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
|||||||
gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
|
gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
|
||||||
vc->tab_item, gtk_label_new(vc->label));
|
vc->tab_item, gtk_label_new(vc->label));
|
||||||
|
|
||||||
#if defined(CONFIG_OPENGL)
|
|
||||||
if (display_opengl) {
|
|
||||||
/*
|
|
||||||
* gtk_widget_set_double_buffered() was deprecated in 3.14.
|
|
||||||
* It is required for opengl rendering on X11 though. A
|
|
||||||
* proper replacement (native opengl support) is only
|
|
||||||
* available in 3.16+. Silence the warning if possible.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
#endif
|
|
||||||
gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
|
|
||||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
vc->gfx.dcl.ops = &dcl_egl_ops;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
vc->gfx.dcl.ops = &dcl_ops;
|
|
||||||
}
|
|
||||||
|
|
||||||
vc->gfx.dcl.con = con;
|
vc->gfx.dcl.con = con;
|
||||||
register_displaychangelistener(&vc->gfx.dcl);
|
register_displaychangelistener(&vc->gfx.dcl);
|
||||||
|
|
||||||
@ -2066,7 +2144,11 @@ void early_gtk_display_init(int opengl)
|
|||||||
break;
|
break;
|
||||||
case 1: /* on */
|
case 1: /* on */
|
||||||
#if defined(CONFIG_OPENGL)
|
#if defined(CONFIG_OPENGL)
|
||||||
|
#if defined(CONFIG_GTK_GL)
|
||||||
|
gtk_gl_area_init();
|
||||||
|
#else
|
||||||
gtk_egl_init();
|
gtk_egl_init();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user