* [Qemu-devel] [PATCH 1/4] gtk: make GtkGlArea usage a runtime option
2018-02-27 11:39 [Qemu-devel] [PATCH 0/4] gtk: add support for dmabufs Gerd Hoffmann
@ 2018-02-27 11:39 ` Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 2/4] gtk: use GtkGlArea on wayland only Gerd Hoffmann
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2018-02-27 11:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Compile in both gtk-egl and gtk-gl-area, then allow to choose at runtime
instead of compile time which opengl variant we want use.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/gtk.h | 2 ++
ui/gtk.c | 53 +++++++++++++++++++++++++++++------------------------
ui/Makefile.objs | 3 +--
3 files changed, 32 insertions(+), 26 deletions(-)
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 849c896eef..f6dafc5961 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -90,6 +90,8 @@ typedef struct VirtualConsole {
};
} VirtualConsole;
+extern bool gtk_use_gl_area;
+
/* ui/gtk.c */
void gd_update_windowsize(VirtualConsole *vc);
diff --git a/ui/gtk.c b/ui/gtk.c
index ab646b70e1..137667dd2d 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -243,6 +243,8 @@ typedef struct VCChardev {
#define TYPE_CHARDEV_VC "chardev-vc"
#define VC_CHARDEV(obj) OBJECT_CHECK(VCChardev, (obj), TYPE_CHARDEV_VC)
+bool gtk_use_gl_area;
+
static void gd_grab_pointer(VirtualConsole *vc, const char *reason);
static void gd_ungrab_pointer(GtkDisplayState *s);
static void gd_grab_keyboard(VirtualConsole *vc, const char *reason);
@@ -453,7 +455,7 @@ static void gd_update_full_redraw(VirtualConsole *vc)
int ww, wh;
gdk_drawable_get_size(gtk_widget_get_window(area), &ww, &wh);
#if defined(CONFIG_GTK_GL)
- if (vc->gfx.gls) {
+ if (vc->gfx.gls && gtk_use_gl_area) {
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
return;
}
@@ -725,7 +727,7 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
.dpy_gl_update = gd_gl_area_scanout_flush,
};
-#else
+#endif /* CONFIG_GTK_GL */
static const DisplayChangeListenerOps dcl_egl_ops = {
.dpy_name = "gtk-egl",
@@ -745,7 +747,6 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
.dpy_gl_update = gd_egl_scanout_flush,
};
-#endif /* CONFIG_GTK_GL */
#endif /* CONFIG_OPENGL */
/** QEMU Events **/
@@ -844,13 +845,13 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
#if defined(CONFIG_OPENGL)
if (vc->gfx.gls) {
-#if defined(CONFIG_GTK_GL)
- /* invoke render callback please */
- return FALSE;
-#else
- gd_egl_draw(vc);
- return TRUE;
-#endif
+ if (gtk_use_gl_area) {
+ /* invoke render callback please */
+ return FALSE;
+ } else {
+ gd_egl_draw(vc);
+ return TRUE;
+ }
}
#endif
@@ -1993,7 +1994,7 @@ static void gd_connect_vc_gfx_signals(VirtualConsole *vc)
g_signal_connect(vc->gfx.drawing_area, "draw",
G_CALLBACK(gd_draw_event), vc);
#if defined(CONFIG_GTK_GL)
- if (display_opengl) {
+ if (gtk_use_gl_area) {
/* wire up GtkGlArea events */
g_signal_connect(vc->gfx.drawing_area, "render",
G_CALLBACK(gd_render_event), vc);
@@ -2116,26 +2117,29 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
#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.
- */
+ if (gtk_use_gl_area) {
+ vc->gfx.drawing_area = gtk_gl_area_new();
+ vc->gfx.dcl.ops = &dcl_gl_area_ops;
+ } else
+#endif /* CONFIG_GTK_GL */
+ {
+ 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);
+ 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 */
+ vc->gfx.dcl.ops = &dcl_egl_ops;
+ }
} else
#endif
{
@@ -2437,6 +2441,7 @@ void early_gtk_display_init(DisplayOptions *opts)
if (opts->has_gl && opts->gl) {
#if defined(CONFIG_OPENGL)
#if defined(CONFIG_GTK_GL)
+ gtk_use_gl_area = true;
gtk_gl_area_init();
#else
gtk_egl_init();
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index ced7d91a63..3a2e9b9c67 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -39,10 +39,9 @@ common-obj-y += egl-context.o
common-obj-$(CONFIG_OPENGL_DMABUF) += egl-headless.o
ifeq ($(CONFIG_GTK_GL),y)
common-obj-$(CONFIG_GTK) += gtk-gl-area.o
-else
+endif
common-obj-$(CONFIG_GTK) += gtk-egl.o
endif
-endif
gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
--
2.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 2/4] gtk: use GtkGlArea on wayland only
2018-02-27 11:39 [Qemu-devel] [PATCH 0/4] gtk: add support for dmabufs Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 1/4] gtk: make GtkGlArea usage a runtime option Gerd Hoffmann
@ 2018-02-27 11:39 ` Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 3/4] gtk-egl: add scanout_dmabuf support Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 4/4] gtk-egl: add cursor_dmabuf support Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2018-02-27 11:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
For dma-buf support we need a egl context. The gtk x11 backend uses glx
contexts though. We can't use the GtkGlArea widget on x11 because of
that, so use our own gtk-egl code instead. wayland continues to use
the GtkGlArea widget.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/gtk.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/ui/gtk.c b/ui/gtk.c
index 137667dd2d..d1101406d5 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -2440,12 +2440,15 @@ void early_gtk_display_init(DisplayOptions *opts)
assert(opts->type == DISPLAY_TYPE_GTK);
if (opts->has_gl && opts->gl) {
#if defined(CONFIG_OPENGL)
-#if defined(CONFIG_GTK_GL)
- gtk_use_gl_area = true;
- gtk_gl_area_init();
-#else
- gtk_egl_init();
+#if defined(CONFIG_GTK_GL) && defined(GDK_WINDOWING_WAYLAND)
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
+ gtk_use_gl_area = true;
+ gtk_gl_area_init();
+ }
#endif
+ {
+ gtk_egl_init();
+ }
#endif
}
--
2.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 3/4] gtk-egl: add scanout_dmabuf support
2018-02-27 11:39 [Qemu-devel] [PATCH 0/4] gtk: add support for dmabufs Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 1/4] gtk: make GtkGlArea usage a runtime option Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 2/4] gtk: use GtkGlArea on wayland only Gerd Hoffmann
@ 2018-02-27 11:39 ` Gerd Hoffmann
2018-02-27 11:39 ` [Qemu-devel] [PATCH 4/4] gtk-egl: add cursor_dmabuf support Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2018-02-27 11:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add support for dmabuf scanouts to gtk-egl.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/gtk.h | 4 ++++
ui/gtk-egl.c | 23 +++++++++++++++++++++++
ui/gtk.c | 2 ++
3 files changed, 29 insertions(+)
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index f6dafc5961..84c992c227 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -113,6 +113,10 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl,
uint32_t backing_height,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
+void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf);
+void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf);
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void gtk_egl_init(void);
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index eb86c26a1d..2c83c22d04 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -194,6 +194,29 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl,
backing_id, false);
}
+void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf)
+{
+#ifdef CONFIG_OPENGL_DMABUF
+ egl_dmabuf_import_texture(dmabuf);
+ if (!dmabuf->texture) {
+ return;
+ }
+
+ gd_egl_scanout_texture(dcl, dmabuf->texture,
+ false, dmabuf->width, dmabuf->height,
+ 0, 0, dmabuf->width, dmabuf->height);
+#endif
+}
+
+void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf)
+{
+#ifdef CONFIG_OPENGL_DMABUF
+ egl_dmabuf_release_texture(dmabuf);
+#endif
+}
+
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
diff --git a/ui/gtk.c b/ui/gtk.c
index d1101406d5..3edb9b2dde 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -744,6 +744,8 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
.dpy_gl_ctx_get_current = qemu_egl_get_current_context,
.dpy_gl_scanout_disable = gd_egl_scanout_disable,
.dpy_gl_scanout_texture = gd_egl_scanout_texture,
+ .dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,
+ .dpy_gl_release_dmabuf = gd_egl_release_dmabuf,
.dpy_gl_update = gd_egl_scanout_flush,
};
--
2.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 4/4] gtk-egl: add cursor_dmabuf support
2018-02-27 11:39 [Qemu-devel] [PATCH 0/4] gtk: add support for dmabufs Gerd Hoffmann
` (2 preceding siblings ...)
2018-02-27 11:39 ` [Qemu-devel] [PATCH 3/4] gtk-egl: add scanout_dmabuf support Gerd Hoffmann
@ 2018-02-27 11:39 ` Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2018-02-27 11:39 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add support for cursor dmabufs to gtk-egl. Just blend in the cursor
(if we have one) when rendering the dmabuf.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/gtk.h | 8 ++++++++
ui/gtk-egl.c | 40 +++++++++++++++++++++++++++++++++++++++-
ui/gtk.c | 2 ++
3 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 84c992c227..2922fc64b2 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -54,6 +54,9 @@ typedef struct VirtualGfxConsole {
int x, y, w, h;
egl_fb guest_fb;
egl_fb win_fb;
+ egl_fb cursor_fb;
+ int cursor_x;
+ int cursor_y;
bool y0_top;
bool scanout_mode;
#endif
@@ -115,6 +118,11 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl,
uint32_t w, uint32_t h);
void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
QemuDmaBuf *dmabuf);
+void gd_egl_cursor_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf, bool have_hot,
+ uint32_t hot_x, uint32_t hot_y);
+void gd_egl_cursor_position(DisplayChangeListener *dcl,
+ uint32_t pos_x, uint32_t pos_y);
void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
QemuDmaBuf *dmabuf);
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 2c83c22d04..9390c6762e 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -19,6 +19,7 @@
#include "ui/console.h"
#include "ui/gtk.h"
#include "ui/egl-helpers.h"
+#include "ui/shader.h"
#include "sysemu/sysemu.h"
@@ -209,6 +210,35 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
#endif
}
+void gd_egl_cursor_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf, bool have_hot,
+ uint32_t hot_x, uint32_t hot_y)
+{
+#ifdef CONFIG_OPENGL_DMABUF
+ VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+
+ if (dmabuf) {
+ egl_dmabuf_import_texture(dmabuf);
+ if (!dmabuf->texture) {
+ return;
+ }
+ egl_fb_setup_for_tex(&vc->gfx.cursor_fb, dmabuf->width, dmabuf->height,
+ dmabuf->texture, false);
+ } else {
+ egl_fb_destroy(&vc->gfx.cursor_fb);
+ }
+#endif
+}
+
+void gd_egl_cursor_position(DisplayChangeListener *dcl,
+ uint32_t pos_x, uint32_t pos_y)
+{
+ VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+
+ vc->gfx.cursor_x = pos_x;
+ vc->gfx.cursor_y = pos_y;
+}
+
void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
QemuDmaBuf *dmabuf)
{
@@ -237,7 +267,15 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
window = gtk_widget_get_window(vc->gfx.drawing_area);
gdk_drawable_get_size(window, &ww, &wh);
egl_fb_setup_default(&vc->gfx.win_fb, ww, wh);
- egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
+ if (vc->gfx.cursor_fb.texture) {
+ egl_texture_blit(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.guest_fb,
+ vc->gfx.y0_top);
+ egl_texture_blend(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.cursor_fb,
+ vc->gfx.y0_top,
+ vc->gfx.cursor_x, vc->gfx.cursor_y);
+ } else {
+ egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
+ }
eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
}
diff --git a/ui/gtk.c b/ui/gtk.c
index 3edb9b2dde..6e18d4b4ab 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -745,6 +745,8 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
.dpy_gl_scanout_disable = gd_egl_scanout_disable,
.dpy_gl_scanout_texture = gd_egl_scanout_texture,
.dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,
+ .dpy_gl_cursor_dmabuf = gd_egl_cursor_dmabuf,
+ .dpy_gl_cursor_position = gd_egl_cursor_position,
.dpy_gl_release_dmabuf = gd_egl_release_dmabuf,
.dpy_gl_update = gd_egl_scanout_flush,
};
--
2.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread