All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@gmail.com>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: QEMU <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH 8/9] gtk/opengl: add opengl context and scanout support (egl)
Date: Fri, 11 Sep 2015 16:36:33 +0200	[thread overview]
Message-ID: <CAJ+F1CKa7-MztTHmO46b+=Xb0EVA2nOMvvVhxfyP4bkX9cAkpA@mail.gmail.com> (raw)
In-Reply-To: <1441797654-15350-9-git-send-email-kraxel@redhat.com>

On Wed, Sep 9, 2015 at 1:20 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> This allows virtio-gpu to render in 3d mode.
> Uses egl, for gtk versions 3.14 and older.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  include/ui/gtk.h |  16 +++++++
>  ui/gtk-egl.c     | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++----
>  ui/gtk.c         |   7 +++
>  3 files changed, 144 insertions(+), 8 deletions(-)
>
> diff --git a/include/ui/gtk.h b/include/ui/gtk.h
> index ee6dffd..1e04c0c 100644
> --- a/include/ui/gtk.h
> +++ b/include/ui/gtk.h
> @@ -24,6 +24,7 @@
>
>  #if defined(CONFIG_OPENGL)
>  #include "ui/egl-helpers.h"
> +#include "ui/egl-context.h"
>  #endif
>
>  /* Compatibility define to let us build on both Gtk2 and Gtk3 */
> @@ -50,6 +51,11 @@ typedef struct VirtualGfxConsole {
>      EGLContext ectx;
>      EGLSurface esurface;
>      int glupdates;
> +    int x, y, w, h;
> +    GLuint tex_id;
> +    GLuint fbo_id;
> +    bool y0_top;
> +    bool scanout_mode;
>  #endif
>  } VirtualGfxConsole;
>
> @@ -94,6 +100,16 @@ void gd_egl_update(DisplayChangeListener *dcl,
>  void gd_egl_refresh(DisplayChangeListener *dcl);
>  void gd_egl_switch(DisplayChangeListener *dcl,
>                     DisplaySurface *surface);
> +qemu_gl_context gd_egl_create_context(DisplayChangeListener *dcl,
> +                                      struct qemu_gl_params *params);
> +void gd_egl_scanout(DisplayChangeListener *dcl,
> +                    uint32_t backing_id, bool backing_y_0_top,
> +                    uint32_t x, uint32_t y,
> +                    uint32_t w, uint32_t h);
> +void gd_egl_scanout_flush(DisplayChangeListener *dcl,
> +                          uint32_t x, uint32_t y, uint32_t w, uint32_t h);
>  void gtk_egl_init(void);
> +int gd_egl_make_current(DisplayChangeListener *dcl,
> +                        qemu_gl_context ctx);
>
>  #endif /* UI_GTK_H */
> diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
> index 15b41f2..ae5c7d0 100644
> --- a/ui/gtk-egl.c
> +++ b/ui/gtk-egl.c
> @@ -21,6 +21,28 @@
>
>  #include "sysemu/sysemu.h"
>
> +static void gtk_egl_set_scanout_mode(VirtualConsole *vc, bool scanout)
> +{
> +    if (vc->gfx.scanout_mode == scanout) {
> +        return;
> +    }
> +
> +    vc->gfx.scanout_mode = scanout;
> +    if (!vc->gfx.scanout_mode) {
> +        if (vc->gfx.fbo_id) {
> +            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
> +                                      GL_COLOR_ATTACHMENT0_EXT,
> +                                      GL_TEXTURE_2D, 0, 0);
> +            glDeleteFramebuffers(1, &vc->gfx.fbo_id);
> +            vc->gfx.fbo_id = 0;
> +        }
> +        if (vc->gfx.surface) {
> +            surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
> +            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
> +        }
> +    }
> +}
> +
>  /** DisplayState Callbacks (opengl version) **/
>
>  void gd_egl_init(VirtualConsole *vc)
> @@ -50,19 +72,26 @@ void gd_egl_draw(VirtualConsole *vc)
>      GdkWindow *window;
>      int ww, wh;
>
> -    if (!vc->gfx.gls || !vc->gfx.ds) {
> +    if (!vc->gfx.gls) {
>          return;
>      }
>
> -    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
> -                   vc->gfx.esurface, vc->gfx.ectx);
> +    if (vc->gfx.scanout_mode) {
> +        gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);
> +    } else {
> +        if (!vc->gfx.ds) {
> +            return;
> +        }
> +        eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
> +                       vc->gfx.esurface, vc->gfx.ectx);
>
> -    window = gtk_widget_get_window(vc->gfx.drawing_area);
> -    gdk_drawable_get_size(window, &ww, &wh);
> -    surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
> -    surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
> +        window = gtk_widget_get_window(vc->gfx.drawing_area);
> +        gdk_drawable_get_size(window, &ww, &wh);
> +        surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
> +        surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
>
> -    eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
> +        eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);

> +    }
>  }
>
>  void gd_egl_update(DisplayChangeListener *dcl,
> @@ -99,6 +128,7 @@ void gd_egl_refresh(DisplayChangeListener *dcl)
>
>      if (vc->gfx.glupdates) {
>          vc->gfx.glupdates = 0;
> +        gtk_egl_set_scanout_mode(vc, false);
>          gd_egl_draw(vc);
>      }
>  }
> @@ -128,6 +158,80 @@ void gd_egl_switch(DisplayChangeListener *dcl,
>      }
>  }
>
> +qemu_gl_context gd_egl_create_context(DisplayChangeListener *dcl,
> +                                      struct qemu_gl_params *params)
> +{
> +    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
> +
> +    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
> +                   vc->gfx.esurface, vc->gfx.ectx);
> +    return qemu_egl_create_context(dcl, params);
> +}
> +
> +void gd_egl_scanout(DisplayChangeListener *dcl,
> +                    uint32_t backing_id, bool backing_y_0_top,
> +                    uint32_t x, uint32_t y,
> +                    uint32_t w, uint32_t h)
> +{
> +    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
> +
> +    vc->gfx.x = x;
> +    vc->gfx.y = y;
> +    vc->gfx.w = w;
> +    vc->gfx.h = h;
> +    vc->gfx.tex_id = backing_id;
> +    vc->gfx.y0_top = backing_y_0_top;
> +
> +    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
> +                   vc->gfx.esurface, vc->gfx.ectx);
> +
> +    if (vc->gfx.tex_id == 0 || vc->gfx.w == 0 || vc->gfx.h == 0) {
> +        gtk_egl_set_scanout_mode(vc, false);
> +        return;
> +    }
> +
> +    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);
> +}
> +

looks like this doesn't respect aspect-ratio (like the rest of the
zoom code), but that's not new,

> +void gd_egl_scanout_flush(DisplayChangeListener *dcl,
> +                          uint32_t x, uint32_t y, uint32_t w, uint32_t h)
> +{
> +    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) {
> +        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);
> +
> +    eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
> +}
> +
>  void gtk_egl_init(void)
>  {
>      GdkDisplay *gdk_display = gdk_display_get_default();
> @@ -139,3 +243,12 @@ void gtk_egl_init(void)
>
>      display_opengl = 1;
>  }
> +
> +int gd_egl_make_current(DisplayChangeListener *dcl,
> +                        qemu_gl_context ctx)
> +{
> +    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
> +
> +    return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
> +                          vc->gfx.esurface, ctx);
> +}
> diff --git a/ui/gtk.c b/ui/gtk.c
> index df2a79e..6faf5a5 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -604,6 +604,13 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
>      .dpy_refresh          = gd_egl_refresh,
>      .dpy_mouse_set        = gd_mouse_set,
>      .dpy_cursor_define    = gd_cursor_define,
> +
> +    .dpy_gl_ctx_create       = gd_egl_create_context,
> +    .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
> +    .dpy_gl_ctx_make_current = gd_egl_make_current,
> +    .dpy_gl_ctx_get_current  = qemu_egl_get_current_context,
> +    .dpy_gl_scanout          = gd_egl_scanout,
> +    .dpy_gl_update           = gd_egl_scanout_flush,
>  };
>
>  #endif
> --
> 1.8.3.1
>
>

looks good to me, (and I get stuff rendered fast on screen :)

-- 
Marc-André Lureau

  reply	other threads:[~2015-09-11 14:36 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-09 11:20 [Qemu-devel] [PATCH 0/9] add virgl rendering support Gerd Hoffmann
2015-09-09 11:20 ` [Qemu-devel] [PATCH 1/9] shaders: initialize vertexes once Gerd Hoffmann
2015-09-10 12:40   ` Marc-André Lureau
2015-09-10 13:22     ` Gerd Hoffmann
2015-09-10 13:42       ` Marc-André Lureau
2015-09-10 14:59         ` Gerd Hoffmann
2015-09-14 16:00   ` Max Reitz
2015-09-14 16:19     ` Max Reitz
2015-09-15  7:10       ` Gerd Hoffmann
2015-09-09 11:20 ` [Qemu-devel] [PATCH 2/9] sdl2: quick & dirty flicker workaround Gerd Hoffmann
2015-09-10 12:40   ` Marc-André Lureau
2015-09-14 16:16   ` Max Reitz
2015-09-09 11:20 ` [Qemu-devel] [PATCH 3/9] ui/console: add opengl context and scanout support interfaces Gerd Hoffmann
2015-09-10 12:40   ` Marc-André Lureau
2015-09-15  8:30   ` Paolo Bonzini
2015-09-09 11:20 ` [Qemu-devel] [PATCH 4/9] virtio-gpu: update headers for virgl/3d Gerd Hoffmann
2015-09-10 12:41   ` Marc-André Lureau
2015-09-09 11:20 ` [Qemu-devel] [PATCH 5/9] virtio-gpu: add 3d mode and virgl rendering support Gerd Hoffmann
2015-09-14 18:14   ` Max Reitz
2015-09-15  7:33     ` Gerd Hoffmann
2015-09-15  8:33   ` Paolo Bonzini
2015-09-09 11:20 ` [Qemu-devel] [PATCH 6/9] sdl2/opengl: add opengl context and scanout support Gerd Hoffmann
2015-09-14 18:49   ` Max Reitz
2015-09-15  7:54     ` Gerd Hoffmann
2015-09-16 13:44       ` Max Reitz
2015-09-09 11:20 ` [Qemu-devel] [PATCH 7/9] opengl: add egl-context.[ch] helpers Gerd Hoffmann
2015-09-11 14:13   ` Marc-André Lureau
2015-09-09 11:20 ` [Qemu-devel] [PATCH 8/9] gtk/opengl: add opengl context and scanout support (egl) Gerd Hoffmann
2015-09-11 14:36   ` Marc-André Lureau [this message]
2015-09-09 11:20 ` [Qemu-devel] [PATCH 9/9] gtk/opengl: add opengl context and scanout support (GtkGLArea) Gerd Hoffmann
2015-09-11 14:44   ` Marc-André Lureau
2015-09-14 13:50     ` Gerd Hoffmann
2015-09-11 16:10 ` [Qemu-devel] [PATCH 0/9] add virgl rendering support Marc-André Lureau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJ+F1CKa7-MztTHmO46b+=Xb0EVA2nOMvvVhxfyP4bkX9cAkpA@mail.gmail.com' \
    --to=marcandre.lureau@gmail.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.