All of lore.kernel.org
 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 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.