All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] gtk: add opengl support
@ 2015-05-19 14:29 Gerd Hoffmann
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 1/4] ui: use libexpoxy Gerd Hoffmann
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-19 14:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

opengl support continued.  This series brings some little fixups, adds
egl helper functions and implements opengl support for the gtk ui using
that.

please review,
  Gerd

Gerd Hoffmann (4):
  ui: use libexpoxy
  ui: shader.h protect against double inclusion
  ui: add egl-helpers
  gtk: add opengl support, using egl

 configure                |   2 +-
 include/ui/console.h     |   5 +-
 include/ui/egl-helpers.h |  16 ++++++
 include/ui/gtk.h         |  23 ++++++++
 include/ui/shader.h      |  10 ++--
 ui/Makefile.objs         |   6 ++
 ui/egl-helpers.c         | 143 +++++++++++++++++++++++++++++++++++++++++++++++
 ui/gtk-egl.c             | 141 ++++++++++++++++++++++++++++++++++++++++++++++
 ui/gtk.c                 |  77 ++++++++++++++++++++-----
 vl.c                     |  11 +++-
 10 files changed, 410 insertions(+), 24 deletions(-)
 create mode 100644 include/ui/egl-helpers.h
 create mode 100644 ui/egl-helpers.c
 create mode 100644 ui/gtk-egl.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 1/4] ui: use libexpoxy
  2015-05-19 14:29 [Qemu-devel] [PATCH 0/4] gtk: add opengl support Gerd Hoffmann
@ 2015-05-19 14:29 ` Gerd Hoffmann
  2015-05-20 10:47   ` Max Reitz
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 2/4] ui: shader.h protect against double inclusion Gerd Hoffmann
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-19 14:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

libepoxy does the opengl extension handling for us.

It also is helpful for trouble-shooting as it prints nice error messages
instead of silently failing or segfaulting in case we do something
wrong, like using gl commands not supported by the current context.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 configure            | 2 +-
 include/ui/console.h | 3 +--
 include/ui/shader.h  | 5 +----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/configure b/configure
index 1f0f485..df1048a 100755
--- a/configure
+++ b/configure
@@ -3153,7 +3153,7 @@ else
 fi
 
 if test "$opengl" != "no" ; then
-  opengl_pkgs="gl glesv2"
+  opengl_pkgs="gl glesv2 epoxy"
   if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then
     opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
     opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
diff --git a/include/ui/console.h b/include/ui/console.h
index e8b3a9e..383dec2 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -10,8 +10,7 @@
 #include "qapi/error.h"
 
 #ifdef CONFIG_OPENGL
-# include <GLES2/gl2.h>
-# include <GLES2/gl2ext.h>
+# include <epoxy/gl.h>
 #endif
 
 /* keyboard/mouse support */
diff --git a/include/ui/shader.h b/include/ui/shader.h
index 1ff926c..992cde6 100644
--- a/include/ui/shader.h
+++ b/include/ui/shader.h
@@ -1,7 +1,4 @@
-#ifdef CONFIG_OPENGL
-# include <GLES2/gl2.h>
-# include <GLES2/gl2ext.h>
-#endif
+#include <epoxy/gl.h>
 
 void qemu_gl_run_texture_blit(GLint texture_blit_prog);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 2/4] ui: shader.h protect against double inclusion
  2015-05-19 14:29 [Qemu-devel] [PATCH 0/4] gtk: add opengl support Gerd Hoffmann
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 1/4] ui: use libexpoxy Gerd Hoffmann
@ 2015-05-19 14:29 ` Gerd Hoffmann
  2015-05-20 10:58   ` Max Reitz
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 3/4] ui: add egl-helpers Gerd Hoffmann
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl Gerd Hoffmann
  3 siblings, 1 reply; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-19 14:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/shader.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/ui/shader.h b/include/ui/shader.h
index 992cde6..8509596 100644
--- a/include/ui/shader.h
+++ b/include/ui/shader.h
@@ -1,3 +1,6 @@
+#ifndef QEMU_SHADER_H
+#define QEMU_SHADER_H
+
 #include <epoxy/gl.h>
 
 void qemu_gl_run_texture_blit(GLint texture_blit_prog);
@@ -6,3 +9,5 @@ GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src);
 GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag);
 GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
                                            const GLchar *frag_src);
+
+#endif /* QEMU_SHADER_H */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 3/4] ui: add egl-helpers
  2015-05-19 14:29 [Qemu-devel] [PATCH 0/4] gtk: add opengl support Gerd Hoffmann
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 1/4] ui: use libexpoxy Gerd Hoffmann
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 2/4] ui: shader.h protect against double inclusion Gerd Hoffmann
@ 2015-05-19 14:29 ` Gerd Hoffmann
  2015-05-20 12:15   ` Max Reitz
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl Gerd Hoffmann
  3 siblings, 1 reply; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-19 14:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add helper functions to initialize OpenGL using egl.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 configure                |   2 +-
 include/ui/egl-helpers.h |  16 ++++++
 ui/Makefile.objs         |   3 +
 ui/egl-helpers.c         | 143 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 include/ui/egl-helpers.h
 create mode 100644 ui/egl-helpers.c

diff --git a/configure b/configure
index df1048a..e0e6b54 100755
--- a/configure
+++ b/configure
@@ -3153,7 +3153,7 @@ else
 fi
 
 if test "$opengl" != "no" ; then
-  opengl_pkgs="gl glesv2 epoxy"
+  opengl_pkgs="gl glesv2 epoxy egl"
   if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then
     opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
     opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
new file mode 100644
index 0000000..5ad5dc3
--- /dev/null
+++ b/include/ui/egl-helpers.h
@@ -0,0 +1,16 @@
+#ifndef EGL_HELPERS_H
+#define EGL_HELPERS_H
+
+#include <epoxy/gl.h>
+#include <epoxy/egl.h>
+
+extern EGLDisplay *qemu_egl_display;
+extern EGLConfig qemu_egl_config;
+
+EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
+
+int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug);
+EGLContext qemu_egl_init_ctx(void);
+bool qemu_egl_has_ext(const char *haystack, const char *needle);
+
+#endif /* EGL_HELPERS_H */
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 029a42a..5c46870 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -30,11 +30,14 @@ sdl.mo-cflags := $(SDL_CFLAGS)
 ifeq ($(CONFIG_OPENGL),y)
 common-obj-y += shader.o
 common-obj-y += console-gl.o
+common-obj-y += egl-helpers.o
 endif
 
 gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
 shader.o-cflags += $(OPENGL_CFLAGS)
 console-gl.o-cflags += $(OPENGL_CFLAGS)
+egl-helpers.o-cflags += $(OPENGL_CFLAGS)
 
 shader.o-libs += $(OPENGL_LIBS)
 console-gl.o-libs += $(OPENGL_LIBS)
+egl-helpers.o-libs += $(OPENGL_LIBS)
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
new file mode 100644
index 0000000..4dcca38
--- /dev/null
+++ b/ui/egl-helpers.c
@@ -0,0 +1,143 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <glob.h>
+
+#include "ui/egl-helpers.h"
+
+EGLDisplay *qemu_egl_display;
+EGLConfig qemu_egl_config;
+
+/* ---------------------------------------------------------------------- */
+
+static int egl_debug;
+
+#define egl_dbg(_x ...)                          \
+    do {                                         \
+        if (egl_debug) {                         \
+            fprintf(stderr, "egl: " _x);         \
+        }                                        \
+    } while (0);
+
+/* ---------------------------------------------------------------------- */
+
+EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
+{
+    EGLSurface esurface;
+    EGLBoolean b;
+
+    egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
+            (unsigned long) win);
+    esurface = eglCreateWindowSurface(qemu_egl_display,
+                                      qemu_egl_config,
+                                      (EGLNativeWindowType)win, NULL);
+    if (!esurface) {
+        fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
+        return NULL;
+    }
+
+    b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
+    if (!b) {
+        fprintf(stderr, "egl: eglMakeCurrent failed\n");
+        return NULL;
+    }
+
+    return esurface;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
+{
+    static const EGLint conf_att_gl[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+        EGL_RED_SIZE,   1,
+        EGL_GREEN_SIZE, 1,
+        EGL_BLUE_SIZE,  1,
+        EGL_ALPHA_SIZE, 0,
+        EGL_NONE,
+    };
+    static const EGLint conf_att_gles[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE,   1,
+        EGL_GREEN_SIZE, 1,
+        EGL_BLUE_SIZE,  1,
+        EGL_ALPHA_SIZE, 0,
+        EGL_NONE,
+    };
+    EGLint major, minor;
+    EGLBoolean b;
+    EGLint n;
+
+    if (debug) {
+        egl_debug = 1;
+        setenv("EGL_LOG_LEVEL", "debug", true);
+        setenv("LIBGL_DEBUG", "verbose", true);
+    }
+
+    egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
+    qemu_egl_display = eglGetDisplay(dpy);
+    if (!qemu_egl_display) {
+        fprintf(stderr, "egl: eglGetDisplay failed\n");
+        return -1;
+    }
+
+    egl_dbg("eglInitialize ...\n");
+    b = eglInitialize(qemu_egl_display, &major, &minor);
+    if (!b) {
+        fprintf(stderr, "egl: eglInitialize failed\n");
+        return -1;
+    }
+
+    egl_dbg("eglBindAPI ...\n");
+    b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
+    if (!b) {
+        fprintf(stderr, "egl: eglBindAPI failed\n");
+        return -1;
+    }
+
+    egl_dbg("eglChooseConfig ...\n");
+    b = eglChooseConfig(qemu_egl_display,
+                        gles ? conf_att_gles : conf_att_gl,
+                        &qemu_egl_config, 1, &n);
+    if (!b || n != 1) {
+        fprintf(stderr, "egl: eglChooseConfig failed\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+EGLContext qemu_egl_init_ctx(void)
+{
+    static const EGLint ctx_att[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+
+    EGLContext ectx;
+    EGLBoolean b;
+
+    egl_dbg("eglCreateContext ...\n");
+    ectx = eglCreateContext(qemu_egl_display, qemu_egl_config,
+                            EGL_NO_CONTEXT, ctx_att);
+    if (!ectx) {
+        fprintf(stderr, "egl: eglCreateContext failed\n");
+        return NULL;
+    }
+
+    b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
+    if (!b) {
+        fprintf(stderr, "egl: eglMakeCurrent failed\n");
+        return NULL;
+    }
+
+    return ectx;
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl
  2015-05-19 14:29 [Qemu-devel] [PATCH 0/4] gtk: add opengl support Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 3/4] ui: add egl-helpers Gerd Hoffmann
@ 2015-05-19 14:29 ` Gerd Hoffmann
  2015-05-20 13:29   ` Max Reitz
  3 siblings, 1 reply; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-19 14:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Gerd Hoffmann

This adds opengl rendering support to the gtk ui, using egl.
It's off by default for now, use 'qemu -display gtk,gl=on'
to play with this.

Note that gtk got native opengl support with release 3.16.
There most likely will be a separate implementation for 3.16+,
using the native gtk opengl support.  This patch covers older
versions (and for the time being 3.16 too, hopefully without
rendering quirks).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |   2 +-
 include/ui/gtk.h     |  23 +++++++++
 ui/Makefile.objs     |   3 ++
 ui/gtk-egl.c         | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/gtk.c             |  77 ++++++++++++++++++++++------
 vl.c                 |  11 +++-
 6 files changed, 240 insertions(+), 17 deletions(-)
 create mode 100644 ui/gtk-egl.c

diff --git a/include/ui/console.h b/include/ui/console.h
index 383dec2..6f7550e 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -393,7 +393,7 @@ void curses_display_init(DisplayState *ds, int full_screen);
 int index_from_key(const char *key);
 
 /* gtk.c */
-void early_gtk_display_init(void);
+void early_gtk_display_init(int opengl);
 void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
 
 #endif
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index b750845..ee6dffd 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -22,6 +22,10 @@
 #include <X11/XKBlib.h>
 #endif
 
+#if defined(CONFIG_OPENGL)
+#include "ui/egl-helpers.h"
+#endif
+
 /* Compatibility define to let us build on both Gtk2 and Gtk3 */
 #if GTK_CHECK_VERSION(3, 0, 0)
 static inline void gdk_drawable_get_size(GdkWindow *w, gint *ww, gint *wh)
@@ -41,6 +45,12 @@ typedef struct VirtualGfxConsole {
     cairo_surface_t *surface;
     double scale_x;
     double scale_y;
+#if defined(CONFIG_OPENGL)
+    ConsoleGLState *gls;
+    EGLContext ectx;
+    EGLSurface esurface;
+    int glupdates;
+#endif
 } VirtualGfxConsole;
 
 #if defined(CONFIG_VTE)
@@ -73,4 +83,17 @@ typedef struct VirtualConsole {
     };
 } VirtualConsole;
 
+/* ui/gtk.c */
+void gd_update_windowsize(VirtualConsole *vc);
+
+/* ui/gtk-egl.c */
+void gd_egl_init(VirtualConsole *vc);
+void gd_egl_draw(VirtualConsole *vc);
+void gd_egl_update(DisplayChangeListener *dcl,
+                   int x, int y, int w, int h);
+void gd_egl_refresh(DisplayChangeListener *dcl);
+void gd_egl_switch(DisplayChangeListener *dcl,
+                   DisplaySurface *surface);
+void gtk_egl_init(void);
+
 #endif /* UI_GTK_H */
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index 5c46870..023914c 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -31,13 +31,16 @@ ifeq ($(CONFIG_OPENGL),y)
 common-obj-y += shader.o
 common-obj-y += console-gl.o
 common-obj-y += egl-helpers.o
+common-obj-$(CONFIG_GTK) += gtk-egl.o
 endif
 
 gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
+gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
 shader.o-cflags += $(OPENGL_CFLAGS)
 console-gl.o-cflags += $(OPENGL_CFLAGS)
 egl-helpers.o-cflags += $(OPENGL_CFLAGS)
 
+gtk-egl.o-libs += $(OPENGL_LIBS)
 shader.o-libs += $(OPENGL_LIBS)
 console-gl.o-libs += $(OPENGL_LIBS)
 egl-helpers.o-libs += $(OPENGL_LIBS)
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
new file mode 100644
index 0000000..15b41f2
--- /dev/null
+++ b/ui/gtk-egl.c
@@ -0,0 +1,141 @@
+/*
+ * GTK UI -- egl opengl code.
+ *
+ * Note that gtk 3.16+ (released 2015-03-23) has a GtkGLArea widget,
+ * which is GtkDrawingArea like widget with opengl rendering support.
+ *
+ * This code handles opengl support on older gtk versions, using egl
+ * to get a opengl context for the X11 window.
+ *
+ * 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"
+
+/** DisplayState Callbacks (opengl version) **/
+
+void gd_egl_init(VirtualConsole *vc)
+{
+    GdkWindow *gdk_window = gtk_widget_get_window(vc->gfx.drawing_area);
+    if (!gdk_window) {
+        return;
+    }
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    Window x11_window = gdk_x11_window_get_xid(gdk_window);
+#else
+    Window x11_window = gdk_x11_drawable_get_xid(gdk_window);
+#endif
+    if (!x11_window) {
+        return;
+    }
+
+    vc->gfx.ectx = qemu_egl_init_ctx();
+    vc->gfx.esurface = qemu_egl_init_surface_x11(vc->gfx.ectx, x11_window);
+
+    assert(vc->gfx.esurface);
+}
+
+void gd_egl_draw(VirtualConsole *vc)
+{
+    GdkWindow *window;
+    int ww, wh;
+
+    if (!vc->gfx.gls || !vc->gfx.ds) {
+        return;
+    }
+
+    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
+                   vc->gfx.esurface, vc->gfx.ectx);
+
+    window = gtk_widget_get_window(vc->gfx.drawing_area);
+    gdk_drawable_get_size(window, &ww, &wh);
+    surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
+    surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
+
+    eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
+}
+
+void gd_egl_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;
+    }
+
+    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
+                   vc->gfx.esurface, vc->gfx.ectx);
+    surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
+    vc->gfx.glupdates++;
+}
+
+void gd_egl_refresh(DisplayChangeListener *dcl)
+{
+    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+
+    if (!vc->gfx.esurface) {
+        gd_egl_init(vc);
+        if (!vc->gfx.esurface) {
+            return;
+        }
+        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;
+        gd_egl_draw(vc);
+    }
+}
+
+void gd_egl_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;
+    }
+
+    surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
+    vc->gfx.ds = surface;
+    if (vc->gfx.gls) {
+        surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
+    }
+
+    if (resized) {
+        gd_update_windowsize(vc);
+    }
+}
+
+void gtk_egl_init(void)
+{
+    GdkDisplay *gdk_display = gdk_display_get_default();
+    Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
+
+    if (qemu_egl_init_dpy(x11_display, false, false) < 0) {
+        return;
+    }
+
+    display_opengl = 1;
+}
diff --git a/ui/gtk.c b/ui/gtk.c
index c58028f..bf66014 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -339,7 +339,7 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
     gtk_window_set_geometry_hints(geo_window, geo_widget, &geo, mask);
 }
 
-static void gd_update_windowsize(VirtualConsole *vc)
+void gd_update_windowsize(VirtualConsole *vc)
 {
     GtkDisplayState *s = vc->s;
 
@@ -581,6 +581,33 @@ static void gd_switch(DisplayChangeListener *dcl,
     }
 }
 
+static const DisplayChangeListenerOps dcl_ops = {
+    .dpy_name             = "gtk",
+    .dpy_gfx_update       = gd_update,
+    .dpy_gfx_switch       = gd_switch,
+    .dpy_gfx_check_format = qemu_pixman_check_format,
+    .dpy_refresh          = gd_refresh,
+    .dpy_mouse_set        = gd_mouse_set,
+    .dpy_cursor_define    = gd_cursor_define,
+};
+
+
+#if defined(CONFIG_OPENGL)
+
+/** DisplayState Callbacks (opengl version) **/
+
+static const DisplayChangeListenerOps dcl_egl_ops = {
+    .dpy_name             = "gtk-egl",
+    .dpy_gfx_update       = gd_egl_update,
+    .dpy_gfx_switch       = gd_egl_switch,
+    .dpy_gfx_check_format = console_gl_check_format,
+    .dpy_refresh          = gd_egl_refresh,
+    .dpy_mouse_set        = gd_mouse_set,
+    .dpy_cursor_define    = gd_cursor_define,
+};
+
+#endif
+
 /** QEMU Events **/
 
 static void gd_change_runstate(void *opaque, int running, RunState state)
@@ -637,6 +664,13 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
     int ww, wh;
     int fbw, fbh;
 
+#if defined(CONFIG_OPENGL)
+    if (vc->gfx.gls) {
+        gd_egl_draw(vc);
+        return TRUE;
+    }
+#endif
+
     if (!gtk_widget_get_realized(widget)) {
         return FALSE;
     }
@@ -1676,16 +1710,6 @@ static GtkWidget *gd_create_menu_machine(GtkDisplayState *s)
     return machine_menu;
 }
 
-static const DisplayChangeListenerOps dcl_ops = {
-    .dpy_name             = "gtk",
-    .dpy_gfx_update       = gd_update,
-    .dpy_gfx_switch       = gd_switch,
-    .dpy_gfx_check_format = qemu_pixman_check_format,
-    .dpy_refresh          = gd_refresh,
-    .dpy_mouse_set        = gd_mouse_set,
-    .dpy_cursor_define    = gd_cursor_define,
-};
-
 static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
                               QemuConsole *con, int idx,
                               GSList *group, GtkWidget *view_menu)
@@ -1713,7 +1737,16 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
     gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
                              vc->tab_item, gtk_label_new(vc->label));
 
-    vc->gfx.dcl.ops = &dcl_ops;
+#if defined(CONFIG_OPENGL)
+    if (display_opengl) {
+        gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
+        vc->gfx.dcl.ops = &dcl_egl_ops;
+    } else
+#endif
+    {
+        vc->gfx.dcl.ops = &dcl_ops;
+    }
+
     vc->gfx.dcl.con = con;
     register_displaychangelistener(&vc->gfx.dcl);
 
@@ -1876,8 +1909,6 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
     GtkDisplayState *s = g_malloc0(sizeof(*s));
     char *filename;
 
-    gtk_init(NULL, NULL);
-
     s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 #if GTK_CHECK_VERSION(3, 2, 0)
     s->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -1954,8 +1985,24 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
     gd_set_keycode_type(s);
 }
 
-void early_gtk_display_init(void)
+void early_gtk_display_init(int opengl)
 {
+    gtk_init(NULL, NULL);
+
+    switch (opengl) {
+    case -1: /* default */
+    case 0:  /* off */
+        break;
+    case 1: /* on */
+#if defined(CONFIG_OPENGL)
+        gtk_egl_init();
+#endif
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+
 #if defined(CONFIG_VTE)
     register_vc_handler(gd_vc_handler);
 #endif
diff --git a/vl.c b/vl.c
index 15bccc4..26b1e7e 100644
--- a/vl.c
+++ b/vl.c
@@ -2047,6 +2047,15 @@ static DisplayType select_display(const char *p)
                 } else {
                     goto invalid_gtk_args;
                 }
+            } else if (strstart(opts, ",gl=", &nextopt)) {
+                opts = nextopt;
+                if (strstart(opts, "on", &nextopt)) {
+                    request_opengl = 1;
+                } else if (strstart(opts, "off", &nextopt)) {
+                    request_opengl = 0;
+                } else {
+                    goto invalid_gtk_args;
+                }
             } else {
             invalid_gtk_args:
                 fprintf(stderr, "Invalid GTK option string: %s\n", p);
@@ -4012,7 +4021,7 @@ int main(int argc, char **argv, char **envp)
 
 #if defined(CONFIG_GTK)
     if (display_type == DT_GTK) {
-        early_gtk_display_init();
+        early_gtk_display_init(request_opengl);
     }
 #endif
 #if defined(CONFIG_SDL)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] ui: use libexpoxy
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 1/4] ui: use libexpoxy Gerd Hoffmann
@ 2015-05-20 10:47   ` Max Reitz
  0 siblings, 0 replies; 12+ messages in thread
From: Max Reitz @ 2015-05-20 10:47 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

On 19.05.2015 16:29, Gerd Hoffmann wrote:
> libepoxy does the opengl extension handling for us.
>
> It also is helpful for trouble-shooting as it prints nice error messages
> instead of silently failing or segfaulting in case we do something
> wrong, like using gl commands not supported by the current context.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   configure            | 2 +-
>   include/ui/console.h | 3 +--
>   include/ui/shader.h  | 5 +----
>   3 files changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/configure b/configure
> index 1f0f485..df1048a 100755
> --- a/configure
> +++ b/configure
> @@ -3153,7 +3153,7 @@ else
>   fi
>   
>   if test "$opengl" != "no" ; then
> -  opengl_pkgs="gl glesv2"
> +  opengl_pkgs="gl glesv2 epoxy"
>     if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then
>       opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
>       opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"

If the package isn't found, the remedy message ("Install GL devel (e.g. 
MESA)") isn't too helpful now .

Whether you change that or not:

Reviewed-by: Max Reitz <mreitz@redhat.com>

> diff --git a/include/ui/console.h b/include/ui/console.h
> index e8b3a9e..383dec2 100644
> --- a/include/ui/console.h
> +++ b/include/ui/console.h
> @@ -10,8 +10,7 @@
>   #include "qapi/error.h"
>   
>   #ifdef CONFIG_OPENGL
> -# include <GLES2/gl2.h>
> -# include <GLES2/gl2ext.h>
> +# include <epoxy/gl.h>
>   #endif
>   
>   /* keyboard/mouse support */
> diff --git a/include/ui/shader.h b/include/ui/shader.h
> index 1ff926c..992cde6 100644
> --- a/include/ui/shader.h
> +++ b/include/ui/shader.h
> @@ -1,7 +1,4 @@
> -#ifdef CONFIG_OPENGL
> -# include <GLES2/gl2.h>
> -# include <GLES2/gl2ext.h>
> -#endif
> +#include <epoxy/gl.h>
>   
>   void qemu_gl_run_texture_blit(GLint texture_blit_prog);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] ui: shader.h protect against double inclusion
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 2/4] ui: shader.h protect against double inclusion Gerd Hoffmann
@ 2015-05-20 10:58   ` Max Reitz
  0 siblings, 0 replies; 12+ messages in thread
From: Max Reitz @ 2015-05-20 10:58 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

On 19.05.2015 16:29, Gerd Hoffmann wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   include/ui/shader.h | 5 +++++
>   1 file changed, 5 insertions(+)

Reviewed-by: Max Reitz <mreitz@redhat.com>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] ui: add egl-helpers
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 3/4] ui: add egl-helpers Gerd Hoffmann
@ 2015-05-20 12:15   ` Max Reitz
  2015-05-20 14:46     ` Gerd Hoffmann
  0 siblings, 1 reply; 12+ messages in thread
From: Max Reitz @ 2015-05-20 12:15 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

On 19.05.2015 16:29, Gerd Hoffmann wrote:
> Add helper functions to initialize OpenGL using egl.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   configure                |   2 +-
>   include/ui/egl-helpers.h |  16 ++++++
>   ui/Makefile.objs         |   3 +
>   ui/egl-helpers.c         | 143 +++++++++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 163 insertions(+), 1 deletion(-)
>   create mode 100644 include/ui/egl-helpers.h
>   create mode 100644 ui/egl-helpers.c
>
> diff --git a/configure b/configure
> index df1048a..e0e6b54 100755
> --- a/configure
> +++ b/configure
> @@ -3153,7 +3153,7 @@ else
>   fi
>   
>   if test "$opengl" != "no" ; then
> -  opengl_pkgs="gl glesv2 epoxy"
> +  opengl_pkgs="gl glesv2 epoxy egl"
>     if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then
>       opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
>       opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
> diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
> new file mode 100644
> index 0000000..5ad5dc3
> --- /dev/null
> +++ b/include/ui/egl-helpers.h
> @@ -0,0 +1,16 @@
> +#ifndef EGL_HELPERS_H
> +#define EGL_HELPERS_H
> +
> +#include <epoxy/gl.h>
> +#include <epoxy/egl.h>
> +
> +extern EGLDisplay *qemu_egl_display;
> +extern EGLConfig qemu_egl_config;
> +
> +EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
> +
> +int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug);
> +EGLContext qemu_egl_init_ctx(void);
> +bool qemu_egl_has_ext(const char *haystack, const char *needle);
> +
> +#endif /* EGL_HELPERS_H */
> diff --git a/ui/Makefile.objs b/ui/Makefile.objs
> index 029a42a..5c46870 100644
> --- a/ui/Makefile.objs
> +++ b/ui/Makefile.objs
> @@ -30,11 +30,14 @@ sdl.mo-cflags := $(SDL_CFLAGS)
>   ifeq ($(CONFIG_OPENGL),y)
>   common-obj-y += shader.o
>   common-obj-y += console-gl.o
> +common-obj-y += egl-helpers.o
>   endif
>   
>   gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
>   shader.o-cflags += $(OPENGL_CFLAGS)
>   console-gl.o-cflags += $(OPENGL_CFLAGS)
> +egl-helpers.o-cflags += $(OPENGL_CFLAGS)
>   
>   shader.o-libs += $(OPENGL_LIBS)
>   console-gl.o-libs += $(OPENGL_LIBS)
> +egl-helpers.o-libs += $(OPENGL_LIBS)
> diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
> new file mode 100644
> index 0000000..4dcca38
> --- /dev/null
> +++ b/ui/egl-helpers.c
> @@ -0,0 +1,143 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <glob.h>
> +
> +#include "ui/egl-helpers.h"
> +
> +EGLDisplay *qemu_egl_display;
> +EGLConfig qemu_egl_config;
> +
> +/* ---------------------------------------------------------------------- */
> +
> +static int egl_debug;
> +
> +#define egl_dbg(_x ...)                          \
> +    do {                                         \
> +        if (egl_debug) {                         \
> +            fprintf(stderr, "egl: " _x);         \
> +        }                                        \
> +    } while (0);
> +
> +/* ---------------------------------------------------------------------- */
> +
> +EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
> +{
> +    EGLSurface esurface;
> +    EGLBoolean b;
> +
> +    egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
> +            (unsigned long) win);
> +    esurface = eglCreateWindowSurface(qemu_egl_display,
> +                                      qemu_egl_config,
> +                                      (EGLNativeWindowType)win, NULL);
> +    if (!esurface) {

Since I don't have any insights into EGL other than looking up the 
functions online, all I can do is nitpick:

The spec says it's EGL_NO_SURFACE (which probably is 0/NULL, but anyway...).

> +        fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
> +        return NULL;
> +    }
> +
> +    b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
> +    if (!b) {

EGL_FALSE, but assuming that is 0 is pretty reasonable, I guess. :-)

> +        fprintf(stderr, "egl: eglMakeCurrent failed\n");
> +        return NULL;
> +    }
> +
> +    return esurface;
> +}
> +
> +/* ---------------------------------------------------------------------- */
> +
> +int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
> +{
> +    static const EGLint conf_att_gl[] = {
> +        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
> +        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
> +        EGL_RED_SIZE,   1,
> +        EGL_GREEN_SIZE, 1,
> +        EGL_BLUE_SIZE,  1,

Wouldn't it be more like 5, 6, 5? Apparently it doesn't really matter 
whether one specifies 1 or e.g. 5, as long as there is a configuration 
with equal to or more than 5 bits; but we won't be able to work with 
less than 5/6/5 anyway...

> +        EGL_ALPHA_SIZE, 0,
> +        EGL_NONE,
> +    };
> +    static const EGLint conf_att_gles[] = {
> +        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
> +        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
> +        EGL_RED_SIZE,   1,
> +        EGL_GREEN_SIZE, 1,
> +        EGL_BLUE_SIZE,  1,
> +        EGL_ALPHA_SIZE, 0,
> +        EGL_NONE,
> +    };
> +    EGLint major, minor;
> +    EGLBoolean b;
> +    EGLint n;
> +
> +    if (debug) {
> +        egl_debug = 1;
> +        setenv("EGL_LOG_LEVEL", "debug", true);
> +        setenv("LIBGL_DEBUG", "verbose", true);
> +    }
> +
> +    egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
> +    qemu_egl_display = eglGetDisplay(dpy);
> +    if (!qemu_egl_display) {

EGL_NO_DISPLAY

> +        fprintf(stderr, "egl: eglGetDisplay failed\n");
> +        return -1;
> +    }
> +
> +    egl_dbg("eglInitialize ...\n");
> +    b = eglInitialize(qemu_egl_display, &major, &minor);
> +    if (!b) {
> +        fprintf(stderr, "egl: eglInitialize failed\n");
> +        return -1;
> +    }

Should we care for eglTerminate() after this point (on error) or do we 
just assume there's no hope on failure anyway?

> +
> +    egl_dbg("eglBindAPI ...\n");
> +    b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
> +    if (!b) {
> +        fprintf(stderr, "egl: eglBindAPI failed\n");
> +        return -1;
> +    }
> +
> +    egl_dbg("eglChooseConfig ...\n");
> +    b = eglChooseConfig(qemu_egl_display,
> +                        gles ? conf_att_gles : conf_att_gl,
> +                        &qemu_egl_config, 1, &n);

Well... It would be sad if the system actually supported true color 
(like basically any system everywhere) and we get some 5/6/5 
configuration here (or even worse). I do think it would be better to 
actually receive the whole list and then scan through it to find the 
best configuration; if you want to keep it this way, we probably really 
have to make the attributes above reflect the minimum requirements 
(5/6/5 for R/G/B bit sizes).

> +    if (!b || n != 1) {
> +        fprintf(stderr, "egl: eglChooseConfig failed\n");
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +EGLContext qemu_egl_init_ctx(void)
> +{
> +    static const EGLint ctx_att[] = {
> +        EGL_CONTEXT_CLIENT_VERSION, 2,
> +        EGL_NONE
> +    };
> +
> +    EGLContext ectx;
> +    EGLBoolean b;
> +
> +    egl_dbg("eglCreateContext ...\n");
> +    ectx = eglCreateContext(qemu_egl_display, qemu_egl_config,
> +                            EGL_NO_CONTEXT, ctx_att);

The manpage says specifying EGL_CONTEXT_CLIENT_VERSION is only valid 
when creating an OpenGL ES context.

> +    if (!ectx) {

EGL_NO_CONTEXT :-)

> +        fprintf(stderr, "egl: eglCreateContext failed\n");
> +        return NULL;
> +    }
> +
> +    b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);

What is this call for? So that some rudimentary OpenGL operations can be 
executed which don't need access to a framebuffer?

Max

> +    if (!b) {
> +        fprintf(stderr, "egl: eglMakeCurrent failed\n");
> +        return NULL;
> +    }
> +
> +    return ectx;
> +}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl
  2015-05-19 14:29 ` [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl Gerd Hoffmann
@ 2015-05-20 13:29   ` Max Reitz
  2015-05-20 14:14     ` Gerd Hoffmann
  0 siblings, 1 reply; 12+ messages in thread
From: Max Reitz @ 2015-05-20 13:29 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel; +Cc: Paolo Bonzini

[-- Attachment #1: Type: text/plain, Size: 2634 bytes --]

On 19.05.2015 16:29, Gerd Hoffmann wrote:
> This adds opengl rendering support to the gtk ui, using egl.
> It's off by default for now, use 'qemu -display gtk,gl=on'
> to play with this.
>
> Note that gtk got native opengl support with release 3.16.
> There most likely will be a separate implementation for 3.16+,
> using the native gtk opengl support.  This patch covers older
> versions (and for the time being 3.16 too, hopefully without
> rendering quirks).
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   include/ui/console.h |   2 +-
>   include/ui/gtk.h     |  23 +++++++++
>   ui/Makefile.objs     |   3 ++
>   ui/gtk-egl.c         | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   ui/gtk.c             |  77 ++++++++++++++++++++++------
>   vl.c                 |  11 +++-
>   6 files changed, 240 insertions(+), 17 deletions(-)
>   create mode 100644 ui/gtk-egl.c

I can't give any R-b, because that would require really digging into 
Gtk... The code is pretty similar to the SDL code, though (not by chance 
I guess), so it looks fine to me. If it would compile, that is, see below.

(It does work with Gtk 2, though)

((at least on my laptop with mesa; on my desktop with fglrx, creating 
the shader fails, which may or may not have to do something with "libEGL 
warning: DRI2: failed to authenticate" (which is probably in turn my own 
fault for using a proprietary driver))) Konsole output

[snip]

> diff --git a/ui/gtk.c b/ui/gtk.c
> index c58028f..bf66014 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c

[snip]

> @@ -1713,7 +1737,16 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
>       gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
>                                vc->tab_item, gtk_label_new(vc->label));
>   
> -    vc->gfx.dcl.ops = &dcl_ops;
> +#if defined(CONFIG_OPENGL)
> +    if (display_opengl) {
> +        gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);

gcc said:
 > Konsole output qemu/ui/gtk.c:1742:9: Fehler: 
»gtk_widget_set_double_buffered« is deprecated (declared at 
/usr/include/gtk-3.0/gtk/gtkwidget.h:896) [-Werror=deprecated-declarations]

(yes, the mix of German and English is gcc's doing)

But then again it didn't compile before, either: qemu/ui/gtk.c:1927:5: 
Fehler: »gdk_cursor_new« is deprecated (declared at 
/usr/include/gtk-3.0/gdk/gdkcursor.h:223) [-Werror=deprecated-declarations]

But that function was deprecated in 3.16, 
gtk_widget_set_double_buffered() was deprecated in 3.14 already (as far 
as I can see from the header file alone).

Max

[-- Attachment #2: Type: text/html, Size: 3794 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl
  2015-05-20 13:29   ` Max Reitz
@ 2015-05-20 14:14     ` Gerd Hoffmann
  2015-05-20 14:16       ` Max Reitz
  0 siblings, 1 reply; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-20 14:14 UTC (permalink / raw)
  To: Max Reitz; +Cc: Paolo Bonzini, qemu-devel

  Hi,

> I can't give any R-b, because that would require really digging into
> Gtk... The code is pretty similar to the SDL code, though (not by
> chance I guess),

Indeed ;)

>  so it looks fine to me. If it would compile, that is, see below.
> 
> (It does work with Gtk 2, though)
> 
> ((at least on my laptop with mesa; on my desktop with fglrx, creating
> the shader fails, which may or may not have to do something with
> "libEGL warning: DRI2: failed to authenticate" (which is probably in
> turn my own fault for using a proprietary driver))) 

Could also be selinux.

> > +#if defined(CONFIG_OPENGL)
> > +    if (display_opengl) {
> > +        gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
> 
> gcc said:
> > qemu/ui/gtk.c:1742:9: Fehler: »gtk_widget_set_double_buffered« is
> deprecated (declared at /usr/include/gtk-3.0/gtk/gtkwidget.h:896)
> [-Werror=deprecated-declarations]

Yep, that is a bit awkward.

Deprecated because gtk_widget_set_double_buffered() doesn't work with
the wayland backend.  The switch simply doesn't make sense with the
wayland rendering pipeline, and the egl rendering might not work on
wayland because of that (/me didn't try).

Nevertheless gtk_widget_set_double_buffered() is required to make gl
rendering work (on X11 backend), for versions older than 3.16.  On 3.16+
we can use the opengl support provided by gtk instead.  Code for that
still needs to be written though.

> But then again it didn't compile before, either: qemu/ui/gtk.c:1927:5:
> Fehler: »gdk_cursor_new« is deprecated (declared
> at /usr/include/gtk-3.0/gdk/gdkcursor.h:223)
> [-Werror=deprecated-declarations]

Saw your patch for that, thanks.

> gtk_widget_set_double_buffered() was deprecated in 3.14 already (as
> far as I can see from the header file alone).

They should have done that in 3.16 IMO ...

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl
  2015-05-20 14:14     ` Gerd Hoffmann
@ 2015-05-20 14:16       ` Max Reitz
  0 siblings, 0 replies; 12+ messages in thread
From: Max Reitz @ 2015-05-20 14:16 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Paolo Bonzini, qemu-devel

On 20.05.2015 16:14, Gerd Hoffmann wrote:
>    Hi,
>
>> I can't give any R-b, because that would require really digging into
>> Gtk... The code is pretty similar to the SDL code, though (not by
>> chance I guess),
> Indeed ;)
>
>>   so it looks fine to me. If it would compile, that is, see below.
>>
>> (It does work with Gtk 2, though)
>>
>> ((at least on my laptop with mesa; on my desktop with fglrx, creating
>> the shader fails, which may or may not have to do something with
>> "libEGL warning: DRI2: failed to authenticate" (which is probably in
>> turn my own fault for using a proprietary driver)))
> Could also be selinux.

Except I don't use SELinux (here). I know, I know, shame on me.

>>> +#if defined(CONFIG_OPENGL)
>>> +    if (display_opengl) {
>>> +        gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
>> gcc said:
>>> qemu/ui/gtk.c:1742:9: Fehler: »gtk_widget_set_double_buffered« is
>> deprecated (declared at /usr/include/gtk-3.0/gtk/gtkwidget.h:896)
>> [-Werror=deprecated-declarations]
> Yep, that is a bit awkward.
>
> Deprecated because gtk_widget_set_double_buffered() doesn't work with
> the wayland backend.  The switch simply doesn't make sense with the
> wayland rendering pipeline, and the egl rendering might not work on
> wayland because of that (/me didn't try).

Right, but we cannot really tell gtk that we know what we're doing. :-)

> Nevertheless gtk_widget_set_double_buffered() is required to make gl
> rendering work (on X11 backend), for versions older than 3.16.  On 3.16+
> we can use the opengl support provided by gtk instead.  Code for that
> still needs to be written though.

Yep, that's what I thought of, too. But the problem is, as you yourself 
say, that 3.14 < 3.16...

Max

>> But then again it didn't compile before, either: qemu/ui/gtk.c:1927:5:
>> Fehler: »gdk_cursor_new« is deprecated (declared
>> at /usr/include/gtk-3.0/gdk/gdkcursor.h:223)
>> [-Werror=deprecated-declarations]
> Saw your patch for that, thanks.
>
>> gtk_widget_set_double_buffered() was deprecated in 3.14 already (as
>> far as I can see from the header file alone).
> They should have done that in 3.16 IMO ...
>
> cheers,
>    Gerd

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] ui: add egl-helpers
  2015-05-20 12:15   ` Max Reitz
@ 2015-05-20 14:46     ` Gerd Hoffmann
  0 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2015-05-20 14:46 UTC (permalink / raw)
  To: Max Reitz; +Cc: qemu-devel

  Hi,

> > +    egl_dbg("eglInitialize ...\n");
> > +    b = eglInitialize(qemu_egl_display, &major, &minor);
> > +    if (!b) {
> > +        fprintf(stderr, "egl: eglInitialize failed\n");
> > +        return -1;
> > +    }
> 
> Should we care for eglTerminate() after this point (on error) or do we 
> just assume there's no hope on failure anyway?

Currently qemu will exit() on failure anyway.

> > +    egl_dbg("eglChooseConfig ...\n");
> > +    b = eglChooseConfig(qemu_egl_display,
> > +                        gles ? conf_att_gles : conf_att_gl,
> > +                        &qemu_egl_config, 1, &n);
> 
> Well... It would be sad if the system actually supported true color 
> (like basically any system everywhere) and we get some 5/6/5 
> configuration here (or even worse).

I'd expect the system to simply return the best config here ...

> (5/6/5 for R/G/B bit sizes).

Fixed that.

> > +        fprintf(stderr, "egl: eglCreateContext failed\n");
> > +        return NULL;
> > +    }
> > +
> > +    b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
> 
> What is this call for? So that some rudimentary OpenGL operations can be 
> executed which don't need access to a framebuffer?

Yes.

Saw this in sample code:  First make context active without surface,
then create surface, then make context active again, this time with the
fresh created surface.

Which made me think it is probably a good idea to make the new context
active even without surface.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-05-20 14:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-19 14:29 [Qemu-devel] [PATCH 0/4] gtk: add opengl support Gerd Hoffmann
2015-05-19 14:29 ` [Qemu-devel] [PATCH 1/4] ui: use libexpoxy Gerd Hoffmann
2015-05-20 10:47   ` Max Reitz
2015-05-19 14:29 ` [Qemu-devel] [PATCH 2/4] ui: shader.h protect against double inclusion Gerd Hoffmann
2015-05-20 10:58   ` Max Reitz
2015-05-19 14:29 ` [Qemu-devel] [PATCH 3/4] ui: add egl-helpers Gerd Hoffmann
2015-05-20 12:15   ` Max Reitz
2015-05-20 14:46     ` Gerd Hoffmann
2015-05-19 14:29 ` [Qemu-devel] [PATCH 4/4] gtk: add opengl support, using egl Gerd Hoffmann
2015-05-20 13:29   ` Max Reitz
2015-05-20 14:14     ` Gerd Hoffmann
2015-05-20 14:16       ` Max Reitz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.