qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers
@ 2017-06-06 11:04 Gerd Hoffmann
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

All UIs with opengl support have simliar code to handle opengl
framebuffers.  Create some helpers and put them into use to reduce
code duplication.

Gerd Hoffmann (4):
  egl-helpers: add helpers to handle opengl framebuffers
  egl-headless: use framebuffer helper functions.
  sdl2: use framebuffer helper functions.
  gtk: use framebuffer helper functions.

 include/ui/egl-helpers.h | 14 ++++++++++
 include/ui/gtk.h         |  4 +--
 include/ui/sdl2.h        |  8 ++++--
 ui/egl-headless.c        | 67 ++++++++++++----------------------------------
 ui/egl-helpers.c         | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
 ui/gtk-egl.c             | 38 ++++++--------------------
 ui/gtk-gl-area.c         | 26 +++++-------------
 ui/sdl2-gl.c             | 38 ++++++--------------------
 8 files changed, 131 insertions(+), 133 deletions(-)

-- 
2.9.3

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

* [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers
  2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
  2017-06-07 19:16   ` Marc-André Lureau
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add a collection of egl_fb_*() helper functions to manage and use opengl
framebuffers, which is a common pattern in UI code with opengl support.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/egl-helpers.h | 14 ++++++++++
 ui/egl-helpers.c         | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index c785d60e91..01aa45fb32 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -8,6 +8,20 @@
 extern EGLDisplay *qemu_egl_display;
 extern EGLConfig qemu_egl_config;
 
+typedef struct egl_fb {
+    int width;
+    int height;
+    GLuint texture;
+    GLuint framebuffer;
+    bool delete_texture;
+} egl_fb;
+
+void egl_fb_destroy(egl_fb *fb);
+void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint texture);
+void egl_fb_create_new_tex(egl_fb *fb, int width, int height);
+void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip);
+void egl_fb_read(void *dst, egl_fb *src);
+
 #ifdef CONFIG_OPENGL_DMABUF
 
 extern int qemu_egl_rn_fd;
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 4a4d3370ee..b14250ae62 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -24,6 +24,75 @@
 EGLDisplay *qemu_egl_display;
 EGLConfig qemu_egl_config;
 
+/* ------------------------------------------------------------------ */
+
+void egl_fb_destroy(egl_fb *fb)
+{
+    if (!fb->framebuffer) {
+        return;
+    }
+
+    if (fb->delete_texture) {
+        glDeleteTextures(1, &fb->texture);
+        fb->delete_texture = false;
+    }
+    glDeleteFramebuffers(1, &fb->framebuffer);
+
+    fb->width = 0;
+    fb->height = 0;
+    fb->texture = 0;
+    fb->framebuffer = 0;
+}
+
+void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint texture)
+{
+    fb->width = width;
+    fb->height = height;
+    fb->texture = texture;
+    if (!fb->framebuffer) {
+        glGenFramebuffers(1, &fb->framebuffer);
+    }
+
+    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb->framebuffer);
+    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                              GL_TEXTURE_2D, fb->texture, 0);
+}
+
+void egl_fb_create_new_tex(egl_fb *fb, int width, int height)
+{
+    GLuint texture;
+
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
+                 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
+
+    egl_fb_create_for_tex(fb, width, height, texture);
+    fb->delete_texture = true;
+}
+
+void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
+{
+    GLuint y1, y2;
+
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->framebuffer);
+    glViewport(0, 0, dst->width, dst->height);
+    y1 = flip ? src->height : 0;
+    y2 = flip ? 0 : src->height;
+    glBlitFramebuffer(0, y1, src->width, y2,
+                      0, 0, dst->width, dst->height,
+                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
+}
+
+void egl_fb_read(void *dst, egl_fb *src)
+{
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
+    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+    glReadPixels(0, 0, src->width, src->height,
+                 GL_BGRA, GL_UNSIGNED_BYTE, dst);
+}
+
 /* ---------------------------------------------------------------------- */
 
 #ifdef CONFIG_OPENGL_DMABUF
-- 
2.9.3

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

* [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
  2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
  2017-06-07 21:02   ` Marc-André Lureau
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 4/4] gtk: " Gerd Hoffmann
  3 siblings, 1 reply; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/egl-headless.c | 67 ++++++++++++++-----------------------------------------
 1 file changed, 17 insertions(+), 50 deletions(-)

diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index d8d800f8a6..809bfde99c 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -8,14 +8,13 @@
 typedef struct egl_dpy {
     DisplayChangeListener dcl;
     DisplaySurface *ds;
-    int width, height;
-    GLuint texture;
-    GLuint framebuffer;
-    GLuint blit_texture;
-    GLuint blit_framebuffer;
+    egl_fb guest_fb;
+    egl_fb blit_fb;
     bool y_0_top;
 } egl_dpy;
 
+/* ------------------------------------------------------------------ */
+
 static void egl_refresh(DisplayChangeListener *dcl)
 {
     graphic_hw_update(dcl->con);
@@ -38,8 +37,8 @@ static void egl_scanout_disable(DisplayChangeListener *dcl)
 {
     egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
 
-    edpy->texture = 0;
-    /* XXX: delete framebuffers here ??? */
+    egl_fb_destroy(&edpy->guest_fb);
+    egl_fb_destroy(&edpy->blit_fb);
 }
 
 static void egl_scanout_texture(DisplayChangeListener *dcl,
@@ -52,34 +51,17 @@ static void egl_scanout_texture(DisplayChangeListener *dcl,
 {
     egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
 
-    edpy->texture = backing_id;
     edpy->y_0_top = backing_y_0_top;
 
     /* source framebuffer */
-    if (!edpy->framebuffer) {
-        glGenFramebuffers(1, &edpy->framebuffer);
-    }
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->framebuffer);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                              GL_TEXTURE_2D, edpy->texture, 0);
+    egl_fb_create_for_tex(&edpy->guest_fb,
+                          backing_width, backing_height, backing_id);
 
     /* dest framebuffer */
-    if (!edpy->blit_framebuffer) {
-        glGenFramebuffers(1, &edpy->blit_framebuffer);
-        glGenTextures(1, &edpy->blit_texture);
-        edpy->width = 0;
-        edpy->height = 0;
-    }
-    if (edpy->width != backing_width || edpy->height != backing_height) {
-        edpy->width   = backing_width;
-        edpy->height  = backing_height;
-        glBindTexture(GL_TEXTURE_2D, edpy->blit_texture);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
-                     edpy->width, edpy->height,
-                     0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
-        glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->blit_framebuffer);
-        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                                  GL_TEXTURE_2D, edpy->blit_texture, 0);
+    if (edpy->blit_fb.width  != backing_width ||
+        edpy->blit_fb.height != backing_height) {
+        egl_fb_destroy(&edpy->blit_fb);
+        egl_fb_create_new_tex(&edpy->blit_fb, backing_width, backing_height);
     }
 }
 
@@ -88,32 +70,17 @@ static void egl_scanout_flush(DisplayChangeListener *dcl,
                               uint32_t w, uint32_t h)
 {
     egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
-    GLuint y1, y2;
 
-    if (!edpy->texture || !edpy->ds) {
+    if (!edpy->guest_fb.texture || !edpy->ds) {
         return;
     }
-    assert(surface_width(edpy->ds)  == edpy->width);
-    assert(surface_height(edpy->ds) == edpy->height);
+    assert(surface_width(edpy->ds)  == edpy->guest_fb.width);
+    assert(surface_height(edpy->ds) == edpy->guest_fb.height);
     assert(surface_format(edpy->ds) == PIXMAN_x8r8g8b8);
 
-    /* blit framebuffer, flip if needed */
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->framebuffer);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, edpy->blit_framebuffer);
-    glViewport(0, 0, edpy->width, edpy->height);
-    y1 = edpy->y_0_top ? edpy->height : 0;
-    y2 = edpy->y_0_top ? 0 : edpy->height;
-    glBlitFramebuffer(0, y1, edpy->width, y2,
-                      0, 0, edpy->width, edpy->height,
-                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
+    egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
+    egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
 
-    /* read pixels to surface */
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->blit_framebuffer);
-    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
-    glReadPixels(0, 0, edpy->width, edpy->height,
-                 GL_BGRA, GL_UNSIGNED_BYTE, surface_data(edpy->ds));
-
-    /* notify about updates */
     dpy_gfx_update(edpy->dcl.con, x, y, w, h);
 }
 
-- 
2.9.3

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

* [Qemu-devel] [PATCH 3/4] sdl2: use framebuffer helper functions.
  2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
  2017-06-08  7:11   ` Marc-André Lureau
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 4/4] gtk: " Gerd Hoffmann
  3 siblings, 1 reply; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/sdl2.h |  8 ++++++--
 ui/sdl2-gl.c      | 38 ++++++++------------------------------
 2 files changed, 14 insertions(+), 32 deletions(-)

diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index aaf226c2c0..454367ac84 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -7,6 +7,10 @@
 #include <SDL.h>
 #include <SDL_syswm.h>
 
+#ifdef CONFIG_OPENGL
+# include "ui/egl-helpers.h"
+#endif
+
 struct sdl2_console {
     DisplayChangeListener dcl;
     DisplaySurface *surface;
@@ -23,8 +27,8 @@ struct sdl2_console {
     SDL_GLContext winctx;
 #ifdef CONFIG_OPENGL
     ConsoleGLState *gls;
-    GLuint tex_id;
-    GLuint fbo_id;
+    egl_fb guest_fb;
+    egl_fb win_fb;
     bool y0_top;
     bool scanout_mode;
 #endif
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index 1cd77e2c16..6640d0a9c8 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -42,14 +42,7 @@ static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
 
     scon->scanout_mode = scanout;
     if (!scon->scanout_mode) {
-        if (scon->fbo_id) {
-            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-                                      GL_COLOR_ATTACHMENT0_EXT,
-                                      GL_TEXTURE_2D, 0, 0);
-            glDeleteFramebuffers(1, &scon->fbo_id);
-            glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
-            scon->fbo_id = 0;
-        }
+        egl_fb_destroy(&scon->guest_fb);
         if (scon->surface) {
             surface_gl_destroy_texture(scon->gls, scon->surface);
             surface_gl_create_texture(scon->gls, scon->surface);
@@ -191,7 +184,6 @@ void sdl2_gl_scanout_disable(DisplayChangeListener *dcl)
     assert(scon->opengl);
     scon->w = 0;
     scon->h = 0;
-    scon->tex_id = 0;
     sdl2_set_scanout_mode(scon, false);
 }
 
@@ -210,48 +202,34 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
     scon->y = y;
     scon->w = w;
     scon->h = h;
-    scon->tex_id = backing_id;
     scon->y0_top = backing_y_0_top;
 
     SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
 
     sdl2_set_scanout_mode(scon, true);
-    if (!scon->fbo_id) {
-        glGenFramebuffers(1, &scon->fbo_id);
-    }
-
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                              GL_TEXTURE_2D, scon->tex_id, 0);
+    egl_fb_create_for_tex(&scon->guest_fb, backing_width, backing_height,
+                          backing_id);
 }
 
 void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
                            uint32_t x, uint32_t y, uint32_t w, uint32_t h)
 {
     struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-    int ww, wh, y1, y2;
 
     assert(scon->opengl);
     if (!scon->scanout_mode) {
         return;
     }
-    if (!scon->fbo_id) {
+    if (!scon->guest_fb.framebuffer) {
         return;
     }
 
     SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
 
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
-    SDL_GetWindowSize(scon->real_window, &ww, &wh);
-    glViewport(0, 0, ww, wh);
-    y1 = scon->y0_top ? 0 : scon->h;
-    y2 = scon->y0_top ? scon->h : 0;
-    glBlitFramebuffer(0, y1, scon->w, y2,
-                      0, 0, ww, wh,
-                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
+    SDL_GetWindowSize(scon->real_window,
+                      &scon->win_fb.width,
+                      &scon->win_fb.height);
+    egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top);
 
     SDL_GL_SwapWindow(scon->real_window);
 }
-- 
2.9.3

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

* [Qemu-devel] [PATCH 4/4] gtk: use framebuffer helper functions.
  2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
@ 2017-06-06 11:04 ` Gerd Hoffmann
  3 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-06 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/gtk.h |  4 ++--
 ui/gtk-egl.c     | 38 ++++++++------------------------------
 ui/gtk-gl-area.c | 26 +++++++-------------------
 3 files changed, 17 insertions(+), 51 deletions(-)

diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index ca9a2268de..2f7b720358 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -52,8 +52,8 @@ typedef struct VirtualGfxConsole {
     EGLSurface esurface;
     int glupdates;
     int x, y, w, h;
-    GLuint tex_id;
-    GLuint fbo_id;
+    egl_fb guest_fb;
+    egl_fb win_fb;
     bool y0_top;
     bool scanout_mode;
 #endif
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index cf48cca259..c40f028b4b 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -30,14 +30,7 @@ static void gtk_egl_set_scanout_mode(VirtualConsole *vc, bool scanout)
 
     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;
-        }
+        egl_fb_destroy(&vc->gfx.guest_fb);
         if (vc->gfx.surface) {
             surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
             surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
@@ -176,7 +169,6 @@ void gd_egl_scanout_disable(DisplayChangeListener *dcl)
 
     vc->gfx.w = 0;
     vc->gfx.h = 0;
-    vc->gfx.tex_id = 0;
     gtk_egl_set_scanout_mode(vc, false);
 }
 
@@ -192,20 +184,14 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl,
     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;
 
     eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                    vc->gfx.esurface, vc->gfx.ectx);
 
     gtk_egl_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);
+    egl_fb_create_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
+                          backing_id);
 }
 
 void gd_egl_scanout_flush(DisplayChangeListener *dcl,
@@ -213,30 +199,22 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
 {
     VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
     GdkWindow *window;
-    int ww, wh, y1, y2;
 
     if (!vc->gfx.scanout_mode) {
         return;
     }
-    if (!vc->gfx.fbo_id) {
+    if (!vc->gfx.guest_fb.framebuffer) {
         return;
     }
 
     eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                    vc->gfx.esurface, vc->gfx.ectx);
 
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
     window = gtk_widget_get_window(vc->gfx.drawing_area);
-    gdk_drawable_get_size(window, &ww, &wh);
-    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);
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
+    gdk_drawable_get_size(window,
+                          &vc->gfx.win_fb.width,
+                          &vc->gfx.win_fb.height);
+    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-gl-area.c b/ui/gtk-gl-area.c
index b05c665cbb..18b298fc21 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -26,14 +26,7 @@ static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
 
     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;
-        }
+        egl_fb_destroy(&vc->gfx.guest_fb);
         if (vc->gfx.surface) {
             surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
             surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
@@ -56,11 +49,11 @@ void gd_gl_area_draw(VirtualConsole *vc)
     wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
 
     if (vc->gfx.scanout_mode) {
-        if (!vc->gfx.fbo_id) {
+        if (!vc->gfx.guest_fb.framebuffer) {
             return;
         }
 
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
+        glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
         /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
 
         glViewport(0, 0, ww, wh);
@@ -181,24 +174,19 @@ void gd_gl_area_scanout_texture(DisplayChangeListener *dcl,
     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) {
+    if (vc->gfx.guest_fb.framebuffer  == 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);
+    egl_fb_create_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
+                          backing_id);
 }
 
 void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
-- 
2.9.3

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

* Re: [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
@ 2017-06-07 19:16   ` Marc-André Lureau
  0 siblings, 0 replies; 11+ messages in thread
From: Marc-André Lureau @ 2017-06-07 19:16 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

Hi

On Tue, Jun 6, 2017 at 3:06 PM Gerd Hoffmann <kraxel@redhat.com> wrote:

> Add a collection of egl_fb_*() helper functions to manage and use opengl
> framebuffers, which is a common pattern in UI code with opengl support.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  include/ui/egl-helpers.h | 14 ++++++++++
>  ui/egl-helpers.c         | 69
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 83 insertions(+)
>
> diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
> index c785d60e91..01aa45fb32 100644
> --- a/include/ui/egl-helpers.h
> +++ b/include/ui/egl-helpers.h
> @@ -8,6 +8,20 @@
>  extern EGLDisplay *qemu_egl_display;
>  extern EGLConfig qemu_egl_config;
>
> +typedef struct egl_fb {
> +    int width;
> +    int height;
> +    GLuint texture;
> +    GLuint framebuffer;
> +    bool delete_texture;
> +} egl_fb;
> +
> +void egl_fb_destroy(egl_fb *fb);
> +void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint
> texture);
> +void egl_fb_create_new_tex(egl_fb *fb, int width, int height);
> +void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip);
> +void egl_fb_read(void *dst, egl_fb *src);
> +
>  #ifdef CONFIG_OPENGL_DMABUF
>
>  extern int qemu_egl_rn_fd;
> diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
> index 4a4d3370ee..b14250ae62 100644
> --- a/ui/egl-helpers.c
> +++ b/ui/egl-helpers.c
> @@ -24,6 +24,75 @@
>  EGLDisplay *qemu_egl_display;
>  EGLConfig qemu_egl_config;
>
> +/* ------------------------------------------------------------------ */
> +
> +void egl_fb_destroy(egl_fb *fb)
> +{
> +    if (!fb->framebuffer) {
> +        return;
> +    }
> +
> +    if (fb->delete_texture) {
> +        glDeleteTextures(1, &fb->texture);
> +        fb->delete_texture = false;
> +    }
> +    glDeleteFramebuffers(1, &fb->framebuffer);
> +
> +    fb->width = 0;
> +    fb->height = 0;
> +    fb->texture = 0;
> +    fb->framebuffer = 0;
> +}
> +
> +void egl_fb_create_for_tex(egl_fb *fb, int width, int height, GLuint
> texture)
> +{
> +    fb->width = width;
> +    fb->height = height;
> +    fb->texture = texture;
> +    if (!fb->framebuffer) {
> +        glGenFramebuffers(1, &fb->framebuffer);
> +    }
> +
> +    glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb->framebuffer);
> +    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> GL_COLOR_ATTACHMENT0_EXT,
> +                              GL_TEXTURE_2D, fb->texture, 0);
> +}
> +
> +void egl_fb_create_new_tex(egl_fb *fb, int width, int height)
> +{
> +    GLuint texture;
> +
> +    glGenTextures(1, &texture);
> +    glBindTexture(GL_TEXTURE_2D, texture);
> +    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
> +                 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
> +
> +    egl_fb_create_for_tex(fb, width, height, texture);
> +    fb->delete_texture = true;
> +}
> +
> +void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
> +{
> +    GLuint y1, y2;
> +
> +    glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
> +    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->framebuffer);
> +    glViewport(0, 0, dst->width, dst->height);
> +    y1 = flip ? src->height : 0;
> +    y2 = flip ? 0 : src->height;
> +    glBlitFramebuffer(0, y1, src->width, y2,
> +                      0, 0, dst->width, dst->height,
> +                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
>

Not much to say, except that GL_LINEAR could give better visual results for
desktop display when scaling down (if this case could happen).


> +}
> +
> +void egl_fb_read(void *dst, egl_fb *src)
> +{
> +    glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
> +    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
> +    glReadPixels(0, 0, src->width, src->height,
> +                 GL_BGRA, GL_UNSIGNED_BYTE, dst);
> +}
> +
>  /* ----------------------------------------------------------------------
> */
>
>  #ifdef CONFIG_OPENGL_DMABUF
> --
> 2.9.3
>
>

the rest looks good to me,
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>


-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
@ 2017-06-07 21:02   ` Marc-André Lureau
  2017-06-12  8:20     ` Gerd Hoffmann
  0 siblings, 1 reply; 11+ messages in thread
From: Marc-André Lureau @ 2017-06-07 21:02 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

Hi

The patch looks good to me, but I tried to use egl-headless for the first
time, and I get a weird crash on virgl init:
(gdb) bt
#0  0x00007fffd8cd935f in rawmemchr () at /lib64/libc.so.6
#1  0x00007fffd8cc1832 in _IO_str_init_static_internal () at
/lib64/libc.so.6
#2  0x00007fffd8cb37e7 in vsscanf () at /lib64/libc.so.6
#3  0x00007ffff6e818a6 in vsscanf () at /lib64/libasan.so.3
#4  0x00007ffff6e819d3 in sscanf () at /lib64/libasan.so.3
#5  0x00007ffff6bfe239 in vrender_get_glsl_version
(glsl_version=0x60e00001f2b8) at vrend_renderer.c:6026
#6  0x00007ffff6bfe239 in vrend_create_context (id=id@entry=0,
nlen=nlen@entry=0, debug_name=debug_name@entry=0x0) at vrend_renderer.c:4033
#7  0x00007ffff6c04f2f in vrend_renderer_context_create_internal (handle=0,
nlen=0, debug_name=0x0) at vrend_decode.c:1066
#8  0x00007ffff6bf72a3 in vrend_renderer_init (cbs=<optimized out>,
flags=0) at vrend_renderer.c:3874
#9  0x0000555556b52cc1 in virtio_gpu_virgl_init (g=0x633000008d10) at
/home/elmarco/src/qemu/hw/display/virtio-gpu-3d.c:623

This doesn't happen when I use virgl/spice (gl=on obviously)

I guess you don't know what's going on, and I will look further later, I
just thought it was worth to report in case you had an idea.

On Tue, Jun 6, 2017 at 3:05 PM Gerd Hoffmann <kraxel@redhat.com> wrote:

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

---
>  ui/egl-headless.c | 67
> ++++++++++++++-----------------------------------------
>  1 file changed, 17 insertions(+), 50 deletions(-)
>
> diff --git a/ui/egl-headless.c b/ui/egl-headless.c
> index d8d800f8a6..809bfde99c 100644
> --- a/ui/egl-headless.c
> +++ b/ui/egl-headless.c
> @@ -8,14 +8,13 @@
>  typedef struct egl_dpy {
>      DisplayChangeListener dcl;
>      DisplaySurface *ds;
> -    int width, height;
> -    GLuint texture;
> -    GLuint framebuffer;
> -    GLuint blit_texture;
> -    GLuint blit_framebuffer;
> +    egl_fb guest_fb;
> +    egl_fb blit_fb;
>      bool y_0_top;
>  } egl_dpy;
>
> +/* ------------------------------------------------------------------ */
> +
>  static void egl_refresh(DisplayChangeListener *dcl)
>  {
>      graphic_hw_update(dcl->con);
> @@ -38,8 +37,8 @@ static void egl_scanout_disable(DisplayChangeListener
> *dcl)
>  {
>      egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
>
> -    edpy->texture = 0;
> -    /* XXX: delete framebuffers here ??? */
> +    egl_fb_destroy(&edpy->guest_fb);
> +    egl_fb_destroy(&edpy->blit_fb);
>  }
>
>  static void egl_scanout_texture(DisplayChangeListener *dcl,
> @@ -52,34 +51,17 @@ static void egl_scanout_texture(DisplayChangeListener
> *dcl,
>  {
>      egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
>
> -    edpy->texture = backing_id;
>      edpy->y_0_top = backing_y_0_top;
>
>      /* source framebuffer */
> -    if (!edpy->framebuffer) {
> -        glGenFramebuffers(1, &edpy->framebuffer);
> -    }
> -    glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->framebuffer);
> -    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> GL_COLOR_ATTACHMENT0_EXT,
> -                              GL_TEXTURE_2D, edpy->texture, 0);
> +    egl_fb_create_for_tex(&edpy->guest_fb,
> +                          backing_width, backing_height, backing_id);
>
>      /* dest framebuffer */
> -    if (!edpy->blit_framebuffer) {
> -        glGenFramebuffers(1, &edpy->blit_framebuffer);
> -        glGenTextures(1, &edpy->blit_texture);
> -        edpy->width = 0;
> -        edpy->height = 0;
> -    }
> -    if (edpy->width != backing_width || edpy->height != backing_height) {
> -        edpy->width   = backing_width;
> -        edpy->height  = backing_height;
> -        glBindTexture(GL_TEXTURE_2D, edpy->blit_texture);
> -        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
> -                     edpy->width, edpy->height,
> -                     0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
> -        glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->blit_framebuffer);
> -        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> GL_COLOR_ATTACHMENT0_EXT,
> -                                  GL_TEXTURE_2D, edpy->blit_texture, 0);
> +    if (edpy->blit_fb.width  != backing_width ||
> +        edpy->blit_fb.height != backing_height) {
> +        egl_fb_destroy(&edpy->blit_fb);
> +        egl_fb_create_new_tex(&edpy->blit_fb, backing_width,
> backing_height);
>      }
>  }
>
> @@ -88,32 +70,17 @@ static void egl_scanout_flush(DisplayChangeListener
> *dcl,
>                                uint32_t w, uint32_t h)
>  {
>      egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
> -    GLuint y1, y2;
>
> -    if (!edpy->texture || !edpy->ds) {
> +    if (!edpy->guest_fb.texture || !edpy->ds) {
>          return;
>      }
> -    assert(surface_width(edpy->ds)  == edpy->width);
> -    assert(surface_height(edpy->ds) == edpy->height);
> +    assert(surface_width(edpy->ds)  == edpy->guest_fb.width);
> +    assert(surface_height(edpy->ds) == edpy->guest_fb.height);
>      assert(surface_format(edpy->ds) == PIXMAN_x8r8g8b8);
>
> -    /* blit framebuffer, flip if needed */
> -    glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->framebuffer);
> -    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, edpy->blit_framebuffer);
> -    glViewport(0, 0, edpy->width, edpy->height);
> -    y1 = edpy->y_0_top ? edpy->height : 0;
> -    y2 = edpy->y_0_top ? 0 : edpy->height;
> -    glBlitFramebuffer(0, y1, edpy->width, y2,
> -                      0, 0, edpy->width, edpy->height,
> -                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
> +    egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
> +    egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
>
> -    /* read pixels to surface */
> -    glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->blit_framebuffer);
> -    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
> -    glReadPixels(0, 0, edpy->width, edpy->height,
> -                 GL_BGRA, GL_UNSIGNED_BYTE, surface_data(edpy->ds));
> -
> -    /* notify about updates */
>      dpy_gfx_update(edpy->dcl.con, x, y, w, h);
>  }
>
> --
> 2.9.3
>
>
> --
Marc-André Lureau

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

* Re: [Qemu-devel] [PATCH 3/4] sdl2: use framebuffer helper functions.
  2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
@ 2017-06-08  7:11   ` Marc-André Lureau
  2017-06-12  8:23     ` Gerd Hoffmann
  0 siblings, 1 reply; 11+ messages in thread
From: Marc-André Lureau @ 2017-06-08  7:11 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

Hi

On Tue, Jun 6, 2017 at 3:05 PM Gerd Hoffmann <kraxel@redhat.com> wrote:

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  include/ui/sdl2.h |  8 ++++++--
>  ui/sdl2-gl.c      | 38 ++++++++------------------------------
>  2 files changed, 14 insertions(+), 32 deletions(-)
>
> diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
> index aaf226c2c0..454367ac84 100644
> --- a/include/ui/sdl2.h
> +++ b/include/ui/sdl2.h
> @@ -7,6 +7,10 @@
>  #include <SDL.h>
>  #include <SDL_syswm.h>
>
> +#ifdef CONFIG_OPENGL
> +# include "ui/egl-helpers.h"
> +#endif
> +
>  struct sdl2_console {
>      DisplayChangeListener dcl;
>      DisplaySurface *surface;
> @@ -23,8 +27,8 @@ struct sdl2_console {
>      SDL_GLContext winctx;
>  #ifdef CONFIG_OPENGL
>      ConsoleGLState *gls;
> -    GLuint tex_id;
> -    GLuint fbo_id;
> +    egl_fb guest_fb;
> +    egl_fb win_fb;
>      bool y0_top;
>      bool scanout_mode;
>  #endif
> diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
> index 1cd77e2c16..6640d0a9c8 100644
> --- a/ui/sdl2-gl.c
> +++ b/ui/sdl2-gl.c
> @@ -42,14 +42,7 @@ static void sdl2_set_scanout_mode(struct sdl2_console
> *scon, bool scanout)
>
>      scon->scanout_mode = scanout;
>      if (!scon->scanout_mode) {
> -        if (scon->fbo_id) {
> -            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> -                                      GL_COLOR_ATTACHMENT0_EXT,
> -                                      GL_TEXTURE_2D, 0, 0);
> -            glDeleteFramebuffers(1, &scon->fbo_id);
> -            glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
> -            scon->fbo_id = 0;
> -        }
> +        egl_fb_destroy(&scon->guest_fb);
>          if (scon->surface) {
>              surface_gl_destroy_texture(scon->gls, scon->surface);
>              surface_gl_create_texture(scon->gls, scon->surface);
> @@ -191,7 +184,6 @@ void sdl2_gl_scanout_disable(DisplayChangeListener
> *dcl)
>      assert(scon->opengl);
>      scon->w = 0;
>      scon->h = 0;
> -    scon->tex_id = 0;
>      sdl2_set_scanout_mode(scon, false);
>  }
>
> @@ -210,48 +202,34 @@ void sdl2_gl_scanout_texture(DisplayChangeListener
> *dcl,
>      scon->y = y;
>      scon->w = w;
>      scon->h = h;
> -    scon->tex_id = backing_id;
>      scon->y0_top = backing_y_0_top;
>
>      SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
>
>      sdl2_set_scanout_mode(scon, true);
> -    if (!scon->fbo_id) {
> -        glGenFramebuffers(1, &scon->fbo_id);
> -    }
> -
> -    glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
> -    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> GL_COLOR_ATTACHMENT0_EXT,
> -                              GL_TEXTURE_2D, scon->tex_id, 0);
> +    egl_fb_create_for_tex(&scon->guest_fb, backing_width, backing_height,
> +                          backing_id);
>  }
>
>  void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
>                             uint32_t x, uint32_t y, uint32_t w, uint32_t h)
>  {
>      struct sdl2_console *scon = container_of(dcl, struct sdl2_console,
> dcl);
> -    int ww, wh, y1, y2;
>
>      assert(scon->opengl);
>      if (!scon->scanout_mode) {
>          return;
>      }
> -    if (!scon->fbo_id) {
> +    if (!scon->guest_fb.framebuffer) {
>          return;
>      }
>
>      SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
>
> -    glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
> -    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
> -
> -    SDL_GetWindowSize(scon->real_window, &ww, &wh);
> -    glViewport(0, 0, ww, wh);
> -    y1 = scon->y0_top ? 0 : scon->h;
> -    y2 = scon->y0_top ? scon->h : 0;
> -    glBlitFramebuffer(0, y1, scon->w, y2,
> -                      0, 0, ww, wh,
> -                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
> -    glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
> +    SDL_GetWindowSize(scon->real_window,
> +                      &scon->win_fb.width,
> +                      &scon->win_fb.height);
>

It's a bit weird to have win_fb used without being really initialized.

Furthermore, there doesn't seem to be guarantee that glGenFramebuffers(1,
&fb->framebuffer) will make only non-0 values.

Perhaps you would also need a bool delete_fb, and a function to setup a
egl_fb from existing fb id.

+    egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top);
>
>      SDL_GL_SwapWindow(scon->real_window);
>  }
> --
> 2.9.3
>
>
>
Looks good otherwise.

-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
  2017-06-07 21:02   ` Marc-André Lureau
@ 2017-06-12  8:20     ` Gerd Hoffmann
  0 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-12  8:20 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel

On Wed, 2017-06-07 at 21:02 +0000, Marc-André Lureau wrote:
> Hi
> 
> The patch looks good to me, but I tried to use egl-headless for the
> first time, and I get a weird crash on virgl init:
> (gdb) bt
> #0  0x00007fffd8cd935f in rawmemchr () at /lib64/libc.so.6
> #1  0x00007fffd8cc1832 in _IO_str_init_static_internal () at
> /lib64/libc.so.6
> #2  0x00007fffd8cb37e7 in vsscanf () at /lib64/libc.so.6
> #3  0x00007ffff6e818a6 in vsscanf () at /lib64/libasan.so.3
> #4  0x00007ffff6e819d3 in sscanf () at /lib64/libasan.so.3
> #5  0x00007ffff6bfe239 in vrender_get_glsl_version
> (glsl_version=0x60e00001f2b8) at vrend_renderer.c:6026
> #6  0x00007ffff6bfe239 in vrend_create_context (id=id@entry=0, nlen=n
> len@entry=0, debug_name=debug_name@entry=0x0) at
> vrend_renderer.c:4033
> #7  0x00007ffff6c04f2f in vrend_renderer_context_create_internal
> (handle=0, nlen=0, debug_name=0x0) at vrend_decode.c:1066
> #8  0x00007ffff6bf72a3 in vrend_renderer_init (cbs=<optimized out>,
> flags=0) at vrend_renderer.c:3874
> #9  0x0000555556b52cc1 in virtio_gpu_virgl_init (g=0x633000008d10) at
> /home/elmarco/src/qemu/hw/display/virtio-gpu-3d.c:623
> 
> This doesn't happen when I use virgl/spice (gl=on obviously)
> 
> I guess you don't know what's going on,

No, havn't seen this before.

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH 3/4] sdl2: use framebuffer helper functions.
  2017-06-08  7:11   ` Marc-André Lureau
@ 2017-06-12  8:23     ` Gerd Hoffmann
  0 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-12  8:23 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel

  Hi,

> It's a bit weird to have win_fb used without being really
> initialized.
> 
> Furthermore, there doesn't seem to be guarantee that
> glGenFramebuffers(1, &fb->framebuffer) will make only non-0 values.

0 is reserved for the default framebuffer of the current context, i.e.
the sdl window in this case.

cheers,
  Gerd

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

* [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions.
  2017-06-14  8:41 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
@ 2017-06-14  8:41 ` Gerd Hoffmann
  0 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2017-06-14  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/egl-headless.c | 67 ++++++++++++++-----------------------------------------
 1 file changed, 17 insertions(+), 50 deletions(-)

diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index d8d800f8a6..809bfde99c 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -8,14 +8,13 @@
 typedef struct egl_dpy {
     DisplayChangeListener dcl;
     DisplaySurface *ds;
-    int width, height;
-    GLuint texture;
-    GLuint framebuffer;
-    GLuint blit_texture;
-    GLuint blit_framebuffer;
+    egl_fb guest_fb;
+    egl_fb blit_fb;
     bool y_0_top;
 } egl_dpy;
 
+/* ------------------------------------------------------------------ */
+
 static void egl_refresh(DisplayChangeListener *dcl)
 {
     graphic_hw_update(dcl->con);
@@ -38,8 +37,8 @@ static void egl_scanout_disable(DisplayChangeListener *dcl)
 {
     egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
 
-    edpy->texture = 0;
-    /* XXX: delete framebuffers here ??? */
+    egl_fb_destroy(&edpy->guest_fb);
+    egl_fb_destroy(&edpy->blit_fb);
 }
 
 static void egl_scanout_texture(DisplayChangeListener *dcl,
@@ -52,34 +51,17 @@ static void egl_scanout_texture(DisplayChangeListener *dcl,
 {
     egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
 
-    edpy->texture = backing_id;
     edpy->y_0_top = backing_y_0_top;
 
     /* source framebuffer */
-    if (!edpy->framebuffer) {
-        glGenFramebuffers(1, &edpy->framebuffer);
-    }
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->framebuffer);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                              GL_TEXTURE_2D, edpy->texture, 0);
+    egl_fb_create_for_tex(&edpy->guest_fb,
+                          backing_width, backing_height, backing_id);
 
     /* dest framebuffer */
-    if (!edpy->blit_framebuffer) {
-        glGenFramebuffers(1, &edpy->blit_framebuffer);
-        glGenTextures(1, &edpy->blit_texture);
-        edpy->width = 0;
-        edpy->height = 0;
-    }
-    if (edpy->width != backing_width || edpy->height != backing_height) {
-        edpy->width   = backing_width;
-        edpy->height  = backing_height;
-        glBindTexture(GL_TEXTURE_2D, edpy->blit_texture);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
-                     edpy->width, edpy->height,
-                     0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
-        glBindFramebuffer(GL_FRAMEBUFFER_EXT, edpy->blit_framebuffer);
-        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                                  GL_TEXTURE_2D, edpy->blit_texture, 0);
+    if (edpy->blit_fb.width  != backing_width ||
+        edpy->blit_fb.height != backing_height) {
+        egl_fb_destroy(&edpy->blit_fb);
+        egl_fb_create_new_tex(&edpy->blit_fb, backing_width, backing_height);
     }
 }
 
@@ -88,32 +70,17 @@ static void egl_scanout_flush(DisplayChangeListener *dcl,
                               uint32_t w, uint32_t h)
 {
     egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
-    GLuint y1, y2;
 
-    if (!edpy->texture || !edpy->ds) {
+    if (!edpy->guest_fb.texture || !edpy->ds) {
         return;
     }
-    assert(surface_width(edpy->ds)  == edpy->width);
-    assert(surface_height(edpy->ds) == edpy->height);
+    assert(surface_width(edpy->ds)  == edpy->guest_fb.width);
+    assert(surface_height(edpy->ds) == edpy->guest_fb.height);
     assert(surface_format(edpy->ds) == PIXMAN_x8r8g8b8);
 
-    /* blit framebuffer, flip if needed */
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->framebuffer);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, edpy->blit_framebuffer);
-    glViewport(0, 0, edpy->width, edpy->height);
-    y1 = edpy->y_0_top ? edpy->height : 0;
-    y2 = edpy->y_0_top ? 0 : edpy->height;
-    glBlitFramebuffer(0, y1, edpy->width, y2,
-                      0, 0, edpy->width, edpy->height,
-                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
+    egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
+    egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
 
-    /* read pixels to surface */
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, edpy->blit_framebuffer);
-    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
-    glReadPixels(0, 0, edpy->width, edpy->height,
-                 GL_BGRA, GL_UNSIGNED_BYTE, surface_data(edpy->ds));
-
-    /* notify about updates */
     dpy_gfx_update(edpy->dcl.con, x, y, w, h);
 }
 
-- 
2.9.3

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

end of thread, other threads:[~2017-06-14  8:41 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-06 11:04 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 1/4] egl-helpers: add helpers to handle opengl framebuffers Gerd Hoffmann
2017-06-07 19:16   ` Marc-André Lureau
2017-06-06 11:04 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann
2017-06-07 21:02   ` Marc-André Lureau
2017-06-12  8:20     ` Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 3/4] sdl2: " Gerd Hoffmann
2017-06-08  7:11   ` Marc-André Lureau
2017-06-12  8:23     ` Gerd Hoffmann
2017-06-06 11:04 ` [Qemu-devel] [PATCH 4/4] gtk: " Gerd Hoffmann
  -- strict thread matches above, loose matches on Subject: below --
2017-06-14  8:41 [Qemu-devel] [PATCH 0/4] ui/opengl: add and use helper functions to handle framebuffers Gerd Hoffmann
2017-06-14  8:41 ` [Qemu-devel] [PATCH 2/4] egl-headless: use framebuffer helper functions Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).