From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53602) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbYoe-0003oM-BB for qemu-devel@nongnu.org; Mon, 14 Sep 2015 14:49:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZbYob-000353-4a for qemu-devel@nongnu.org; Mon, 14 Sep 2015 14:49:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56375) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbYoa-00034y-RP for qemu-devel@nongnu.org; Mon, 14 Sep 2015 14:49:21 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 71BC28E3C3 for ; Mon, 14 Sep 2015 18:49:20 +0000 (UTC) References: <1441797654-15350-1-git-send-email-kraxel@redhat.com> <1441797654-15350-7-git-send-email-kraxel@redhat.com> From: Max Reitz Message-ID: <55F716AA.4080508@redhat.com> Date: Mon, 14 Sep 2015 20:49:14 +0200 MIME-Version: 1.0 In-Reply-To: <1441797654-15350-7-git-send-email-kraxel@redhat.com> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="I3ohjDKO5xdhkJb9E2mLQke0MoCSqRI6s" Subject: Re: [Qemu-devel] [PATCH 6/9] sdl2/opengl: add opengl context and scanout support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann , qemu-devel@nongnu.org This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --I3ohjDKO5xdhkJb9E2mLQke0MoCSqRI6s Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: quoted-printable On 09.09.2015 13:20, Gerd Hoffmann wrote: > This allows virtio-gpu to render in 3d mode. >=20 > Signed-off-by: Gerd Hoffmann > --- > include/ui/sdl2.h | 22 ++++++++- > ui/sdl2-gl.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++= ++++++++ > ui/sdl2.c | 7 +++ > 3 files changed, 161 insertions(+), 1 deletion(-) >=20 > diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h > index 2fdad8f..b397631 100644 > --- a/include/ui/sdl2.h > +++ b/include/ui/sdl2.h > @@ -15,12 +15,18 @@ struct sdl2_console { > SDL_Renderer *real_renderer; > int idx; > int last_vm_running; /* per console for caption reasons */ > - int x, y; > + int x, y, w, h; > int hidden; > int opengl; > int updates; > SDL_GLContext winctx; > +#ifdef CONFIG_OPENGL > ConsoleGLState *gls; > + GLuint tex_id; > + GLuint fbo_id; > + bool y0_top; > + bool scanout_mode; > +#endif > }; > =20 > void sdl2_window_create(struct sdl2_console *scon); > @@ -48,4 +54,18 @@ void sdl2_gl_switch(DisplayChangeListener *dcl, > void sdl2_gl_refresh(DisplayChangeListener *dcl); > void sdl2_gl_redraw(struct sdl2_console *scon); > =20 > +qemu_gl_context sdl2_gl_create_context(DisplayChangeListener *dcl, > + struct qemu_gl_params *params);= > +void sdl2_gl_destroy_context(DisplayChangeListener *dcl, qemu_gl_conte= xt ctx); > +int sdl2_gl_make_context_current(DisplayChangeListener *dcl, > + qemu_gl_context ctx); > +qemu_gl_context sdl2_gl_get_current_context(DisplayChangeListener *dcl= ); > + > +void sdl2_gl_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 sdl2_gl_scanout_flush(DisplayChangeListener *dcl, > + uint32_t x, uint32_t y, uint32_t w, uint32_= t h); > + > #endif /* SDL2_H */ > diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c > index b604c06..bc73c0e 100644 > --- a/ui/sdl2-gl.c > +++ b/ui/sdl2-gl.c > @@ -31,11 +31,36 @@ > #include "ui/sdl2.h" > #include "sysemu/sysemu.h" > =20 > +#include > + > +static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scan= out) > +{ > + if (scon->scanout_mode =3D=3D scanout) { > + return; > + } > + > + scon->scanout_mode =3D 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); I'm not sure, but maybe the framebuffer itself should be unbound here, too? (i.e., glBindFramebuffer(GL_FRAMEBUFFER, 0)) I know it's deleted but I don't know whether that's enough. > + scon->fbo_id =3D 0; > + } > + if (scon->surface) { > + surface_gl_destroy_texture(scon->gls, scon->surface); > + surface_gl_create_texture(scon->gls, scon->surface); > + } > + } > +} > + > static void sdl2_gl_render_surface(struct sdl2_console *scon) > { > int ww, wh; > =20 > SDL_GL_MakeCurrent(scon->real_window, scon->winctx); > + sdl2_set_scanout_mode(scon, false); > =20 > SDL_GetWindowSize(scon->real_window, &ww, &wh); > surface_gl_setup_viewport(scon->gls, scon->surface, ww, wh); > @@ -110,3 +135,111 @@ void sdl2_gl_redraw(struct sdl2_console *scon) > sdl2_gl_render_surface(scon); > } > } > + > +qemu_gl_context sdl2_gl_create_context(DisplayChangeListener *dcl, > + struct qemu_gl_params *params) > +{ > + struct sdl2_console *scon =3D container_of(dcl, struct sdl2_consol= e, dcl); > + SDL_GLContext ctx; > + > + assert(scon->opengl); > + > + SDL_GL_MakeCurrent(scon->real_window, scon->winctx); > + > + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); > + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, > + SDL_GL_CONTEXT_PROFILE_CORE); > + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, params->major_ve= r); > + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, params->minor_ve= r); > + > + ctx =3D SDL_GL_CreateContext(scon->real_window); > + return (qemu_gl_context)ctx; > +} > + > +void sdl2_gl_destroy_context(DisplayChangeListener *dcl, qemu_gl_conte= xt ctx) > +{ > + SDL_GLContext sdlctx =3D (SDL_GLContext)ctx; > + > + SDL_GL_DeleteContext(sdlctx); > +} > + > +int sdl2_gl_make_context_current(DisplayChangeListener *dcl, > + qemu_gl_context ctx) > +{ > + struct sdl2_console *scon =3D container_of(dcl, struct sdl2_consol= e, dcl); > + SDL_GLContext sdlctx =3D (SDL_GLContext)ctx; > + > + assert(scon->opengl); > + > + return SDL_GL_MakeCurrent(scon->real_window, sdlctx); > +} > + > +qemu_gl_context sdl2_gl_get_current_context(DisplayChangeListener *dcl= ) > +{ > + SDL_GLContext sdlctx; > + > + sdlctx =3D SDL_GL_GetCurrentContext(); > + return (qemu_gl_context)sdlctx; > +} > + > +void sdl2_gl_scanout(DisplayChangeListener *dcl, > + uint32_t backing_id, bool backing_y_0_top, > + uint32_t x, uint32_t y, > + uint32_t w, uint32_t h) > +{ > + struct sdl2_console *scon =3D container_of(dcl, struct sdl2_consol= e, dcl); > + > + assert(scon->opengl); > + scon->x =3D x; > + scon->y =3D y; > + scon->w =3D w; > + scon->h =3D h; > + scon->tex_id =3D backing_id; > + scon->y0_top =3D backing_y_0_top; > + > + SDL_GL_MakeCurrent(scon->real_window, scon->winctx); > + > + if (scon->tex_id =3D=3D 0 || scon->w =3D=3D 0 || scon->h =3D=3D 0)= { > + sdl2_set_scanout_mode(scon, false); > + return; > + } > + > + 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); > +} > + > +void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, > + uint32_t x, uint32_t y, uint32_t w, uint32_= t h) > +{ > + struct sdl2_console *scon =3D container_of(dcl, struct sdl2_consol= e, dcl); > + int ww, wh, y1, y2; > + > + assert(scon->opengl); > + if (!scon->scanout_mode) { > + return; > + } > + if (!scon->fbo_id) { > + 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 =3D scon->y0_top ? 0 : scon->h; > + y2 =3D scon->y0_top ? scon->h : 0; > + glBlitFramebuffer(0, y1, scon->w, y2, > + 0, 0, ww, wh, > + GL_COLOR_BUFFER_BIT, GL_NEAREST); Should we bind the FBO back to GL_DRAW_FRAMEBUFFER after the blit operati= on? Max > + > + SDL_GL_SwapWindow(scon->real_window); > +} > diff --git a/ui/sdl2.c b/ui/sdl2.c > index 5cb75aa..73a84a8 100644 > --- a/ui/sdl2.c > +++ b/ui/sdl2.c > @@ -700,6 +700,13 @@ static const DisplayChangeListenerOps dcl_gl_ops =3D= { > .dpy_refresh =3D sdl2_gl_refresh, > .dpy_mouse_set =3D sdl_mouse_warp, > .dpy_cursor_define =3D sdl_mouse_define, > + > + .dpy_gl_ctx_create =3D sdl2_gl_create_context, > + .dpy_gl_ctx_destroy =3D sdl2_gl_destroy_context, > + .dpy_gl_ctx_make_current =3D sdl2_gl_make_context_current, > + .dpy_gl_ctx_get_current =3D sdl2_gl_get_current_context, > + .dpy_gl_scanout =3D sdl2_gl_scanout, > + .dpy_gl_update =3D sdl2_gl_scanout_flush, > }; > #endif > =20 >=20 --I3ohjDKO5xdhkJb9E2mLQke0MoCSqRI6s Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAEBCAAGBQJV9xaqAAoJEDuxQgLoOKyt0l4H/0VUBLguBq39bAhIiZM5Rdt8 b459X2HClEQFZ8bIpd+OapP8ErMSEcoK+qm9ySOUqIMG1pRNJT7SPiH/owLz31qx DYHqEmtqc31ks6m+i+XYXb6sv1zWZSGgLXFB4eD/zO8Oa4heDl1mVjd7ADUwn2AA OprVY81MjDYTb/T24Ni4LCGSz8FILxtfDRW43ln4Sb3wlgiPFt9KDonEIzCQjRL3 //dcB09WYmAL5VoyysF8sCO5jsdgvIRY24j8YPUa6+7X0TOvGGj3sg4yiK5LsNC7 QYQOBxwfHUKgFSrZdKHwTawbPwDMXIvQxhZOdZkRnRg4TTYfEtnoOzHqdYdELpk= =AYD+ -----END PGP SIGNATURE----- --I3ohjDKO5xdhkJb9E2mLQke0MoCSqRI6s--