ui: opengl updates for dma-buf support.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJZ5eXgAAoJEEy22O7T6HE4nhEQANHY8Exu2HFGKHbd59IR7MAl jc3CiT5tc9/HGcPuhUw5BuEBpd053/COZQktSTAjOUYo7tDmwM+dbEz5SU0dIVXf hu1ZoAvgOmC+X+TZRY2YyFrjvwjORRxATxnLlg3ETTDbaEu8EI4G0xA8NYox7j1X nPduAsSEK4YiPcOkfbi2LmQIaLE4phtmFnVed0cLWG0hE1n1KWDu0TQGQB4ZNLb1 t5RtEc/qLrkVSGupLy0lwBIlMGAFZzjmr2co13IpPd6Weow8v++c68aO6PtAWQWA pFhDuWwENg/LshyHa2tgWg+QaGl5p+306fVq79RX23juLZ5OaPyPtuptL2uXen5N 74GroqLwkbl9TabjLpmNGGLvwKwV5cLtmpGW/t4jAX0fhb0RjfMwIeazgeWkifED z4o7tkXTR9EUc+6nHYXbdy5okmxBXv3JvDM9LAMG1d3c4T9VRsKJJMwoPclbkwi1 SxGLoYvz9IU4VjYAkFgoeYeKGX9UbJPzKp3kyuczZEAAm8Gd9uaAhCYvIk9nE/Mi JlPPfz1J8EerdD2mJjbIMZvz/7mvcrkRhQBzM/bTUDxuVTdWVrD+mP5qoq7XuApi 0GgMJbubYEBSBsD3tpRArSOkLmoRanH9CaGetY5o2m4p+BaQ7ssiCQ5oPczrW4lj L83OfkWx4PiBB5swQHv1 =P3Cr -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/opengl-20171017-pull-request' into staging ui: opengl updates for dma-buf support. # gpg: Signature made Tue 17 Oct 2017 12:13:36 BST # gpg: using RSA key 0x4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/opengl-20171017-pull-request: egl-headless: add dmabuf support egl-helpers: add egl_texture_blit and egl_texture_blend egl-helpers: add dmabuf import support opengl: add flipping vertex shader opengl: move shader init from console-gl.c to shader.c console: add support for dmabufs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						ba6f0fc25e
					
				
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@ -724,8 +724,10 @@ ui/shader/%-frag.h: $(SRC_PATH)/ui/shader/%.frag $(SRC_PATH)/scripts/shaderinclu
 | 
				
			|||||||
		perl $(SRC_PATH)/scripts/shaderinclude.pl $< > $@,\
 | 
							perl $(SRC_PATH)/scripts/shaderinclude.pl $< > $@,\
 | 
				
			||||||
		"FRAG","$@")
 | 
							"FRAG","$@")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ui/console-gl.o: $(SRC_PATH)/ui/console-gl.c \
 | 
					ui/shader.o: $(SRC_PATH)/ui/shader.c \
 | 
				
			||||||
	ui/shader/texture-blit-vert.h ui/shader/texture-blit-frag.h
 | 
						ui/shader/texture-blit-vert.h \
 | 
				
			||||||
 | 
						ui/shader/texture-blit-flip-vert.h \
 | 
				
			||||||
 | 
						ui/shader/texture-blit-frag.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# documentation
 | 
					# documentation
 | 
				
			||||||
MAKEINFO=makeinfo
 | 
					MAKEINFO=makeinfo
 | 
				
			||||||
 | 
				
			|||||||
@ -83,6 +83,7 @@ typedef struct PropertyInfo PropertyInfo;
 | 
				
			|||||||
typedef struct PS2State PS2State;
 | 
					typedef struct PS2State PS2State;
 | 
				
			||||||
typedef struct QEMUBH QEMUBH;
 | 
					typedef struct QEMUBH QEMUBH;
 | 
				
			||||||
typedef struct QemuConsole QemuConsole;
 | 
					typedef struct QemuConsole QemuConsole;
 | 
				
			||||||
 | 
					typedef struct QemuDmaBuf QemuDmaBuf;
 | 
				
			||||||
typedef struct QEMUFile QEMUFile;
 | 
					typedef struct QEMUFile QEMUFile;
 | 
				
			||||||
typedef struct QemuOpt QemuOpt;
 | 
					typedef struct QemuOpt QemuOpt;
 | 
				
			||||||
typedef struct QemuOpts QemuOpts;
 | 
					typedef struct QemuOpts QemuOpts;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,12 +5,14 @@
 | 
				
			|||||||
#include "qom/object.h"
 | 
					#include "qom/object.h"
 | 
				
			||||||
#include "qapi/qmp/qdict.h"
 | 
					#include "qapi/qmp/qdict.h"
 | 
				
			||||||
#include "qemu/notify.h"
 | 
					#include "qemu/notify.h"
 | 
				
			||||||
 | 
					#include "qemu/typedefs.h"
 | 
				
			||||||
#include "qapi-types.h"
 | 
					#include "qapi-types.h"
 | 
				
			||||||
#include "qemu/error-report.h"
 | 
					#include "qemu/error-report.h"
 | 
				
			||||||
#include "qapi/error.h"
 | 
					#include "qapi/error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_OPENGL
 | 
					#ifdef CONFIG_OPENGL
 | 
				
			||||||
# include <epoxy/gl.h>
 | 
					# include <epoxy/gl.h>
 | 
				
			||||||
 | 
					# include "ui/shader.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* keyboard/mouse support */
 | 
					/* keyboard/mouse support */
 | 
				
			||||||
@ -180,6 +182,15 @@ struct QEMUGLParams {
 | 
				
			|||||||
    int minor_ver;
 | 
					    int minor_ver;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct QemuDmaBuf {
 | 
				
			||||||
 | 
					    int       fd;
 | 
				
			||||||
 | 
					    uint32_t  width;
 | 
				
			||||||
 | 
					    uint32_t  height;
 | 
				
			||||||
 | 
					    uint32_t  stride;
 | 
				
			||||||
 | 
					    uint32_t  fourcc;
 | 
				
			||||||
 | 
					    uint32_t  texture;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct DisplayChangeListenerOps {
 | 
					typedef struct DisplayChangeListenerOps {
 | 
				
			||||||
    const char *dpy_name;
 | 
					    const char *dpy_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -220,6 +231,13 @@ typedef struct DisplayChangeListenerOps {
 | 
				
			|||||||
                                   uint32_t backing_height,
 | 
					                                   uint32_t backing_height,
 | 
				
			||||||
                                   uint32_t x, uint32_t y,
 | 
					                                   uint32_t x, uint32_t y,
 | 
				
			||||||
                                   uint32_t w, uint32_t h);
 | 
					                                   uint32_t w, uint32_t h);
 | 
				
			||||||
 | 
					    void (*dpy_gl_scanout_dmabuf)(DisplayChangeListener *dcl,
 | 
				
			||||||
 | 
					                                  QemuDmaBuf *dmabuf);
 | 
				
			||||||
 | 
					    void (*dpy_gl_cursor_dmabuf)(DisplayChangeListener *dcl,
 | 
				
			||||||
 | 
					                                 QemuDmaBuf *dmabuf,
 | 
				
			||||||
 | 
					                                 uint32_t pos_x, uint32_t pos_y);
 | 
				
			||||||
 | 
					    void (*dpy_gl_release_dmabuf)(DisplayChangeListener *dcl,
 | 
				
			||||||
 | 
					                                  QemuDmaBuf *dmabuf);
 | 
				
			||||||
    void (*dpy_gl_update)(DisplayChangeListener *dcl,
 | 
					    void (*dpy_gl_update)(DisplayChangeListener *dcl,
 | 
				
			||||||
                          uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 | 
					                          uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -288,6 +306,13 @@ void dpy_gl_scanout_texture(QemuConsole *con,
 | 
				
			|||||||
                            uint32_t backing_id, bool backing_y_0_top,
 | 
					                            uint32_t backing_id, bool backing_y_0_top,
 | 
				
			||||||
                            uint32_t backing_width, uint32_t backing_height,
 | 
					                            uint32_t backing_width, uint32_t backing_height,
 | 
				
			||||||
                            uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 | 
					                            uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 | 
				
			||||||
 | 
					void dpy_gl_scanout_dmabuf(QemuConsole *con,
 | 
				
			||||||
 | 
					                           QemuDmaBuf *dmabuf);
 | 
				
			||||||
 | 
					void dpy_gl_cursor_dmabuf(QemuConsole *con,
 | 
				
			||||||
 | 
					                          QemuDmaBuf *dmabuf,
 | 
				
			||||||
 | 
					                          uint32_t pos_x, uint32_t pos_y);
 | 
				
			||||||
 | 
					void dpy_gl_release_dmabuf(QemuConsole *con,
 | 
				
			||||||
 | 
					                           QemuDmaBuf *dmabuf);
 | 
				
			||||||
void dpy_gl_update(QemuConsole *con,
 | 
					void dpy_gl_update(QemuConsole *con,
 | 
				
			||||||
                   uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 | 
					                   uint32_t x, uint32_t y, uint32_t w, uint32_t h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -298,6 +323,7 @@ int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx);
 | 
				
			|||||||
QEMUGLContext dpy_gl_ctx_get_current(QemuConsole *con);
 | 
					QEMUGLContext dpy_gl_ctx_get_current(QemuConsole *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool console_has_gl(QemuConsole *con);
 | 
					bool console_has_gl(QemuConsole *con);
 | 
				
			||||||
 | 
					bool console_has_gl_dmabuf(QemuConsole *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int surface_stride(DisplaySurface *s)
 | 
					static inline int surface_stride(DisplaySurface *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -390,22 +416,19 @@ void qemu_console_resize(QemuConsole *con, int width, int height);
 | 
				
			|||||||
DisplaySurface *qemu_console_surface(QemuConsole *con);
 | 
					DisplaySurface *qemu_console_surface(QemuConsole *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* console-gl.c */
 | 
					/* console-gl.c */
 | 
				
			||||||
typedef struct ConsoleGLState ConsoleGLState;
 | 
					 | 
				
			||||||
#ifdef CONFIG_OPENGL
 | 
					#ifdef CONFIG_OPENGL
 | 
				
			||||||
ConsoleGLState *console_gl_init_context(void);
 | 
					 | 
				
			||||||
void console_gl_fini_context(ConsoleGLState *gls);
 | 
					 | 
				
			||||||
bool console_gl_check_format(DisplayChangeListener *dcl,
 | 
					bool console_gl_check_format(DisplayChangeListener *dcl,
 | 
				
			||||||
                             pixman_format_code_t format);
 | 
					                             pixman_format_code_t format);
 | 
				
			||||||
void surface_gl_create_texture(ConsoleGLState *gls,
 | 
					void surface_gl_create_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface);
 | 
					                               DisplaySurface *surface);
 | 
				
			||||||
void surface_gl_update_texture(ConsoleGLState *gls,
 | 
					void surface_gl_update_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface,
 | 
					                               DisplaySurface *surface,
 | 
				
			||||||
                               int x, int y, int w, int h);
 | 
					                               int x, int y, int w, int h);
 | 
				
			||||||
void surface_gl_render_texture(ConsoleGLState *gls,
 | 
					void surface_gl_render_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface);
 | 
					                               DisplaySurface *surface);
 | 
				
			||||||
void surface_gl_destroy_texture(ConsoleGLState *gls,
 | 
					void surface_gl_destroy_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface);
 | 
					                               DisplaySurface *surface);
 | 
				
			||||||
void surface_gl_setup_viewport(ConsoleGLState *gls,
 | 
					void surface_gl_setup_viewport(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface,
 | 
					                               DisplaySurface *surface,
 | 
				
			||||||
                               int ww, int wh);
 | 
					                               int ww, int wh);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,10 @@ void egl_fb_setup_new_tex(egl_fb *fb, int width, int height);
 | 
				
			|||||||
void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip);
 | 
					void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip);
 | 
				
			||||||
void egl_fb_read(void *dst, egl_fb *src);
 | 
					void egl_fb_read(void *dst, egl_fb *src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip);
 | 
				
			||||||
 | 
					void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
 | 
				
			||||||
 | 
					                       int x, int y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_OPENGL_DMABUF
 | 
					#ifdef CONFIG_OPENGL_DMABUF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int qemu_egl_rn_fd;
 | 
					extern int qemu_egl_rn_fd;
 | 
				
			||||||
@ -33,6 +37,9 @@ extern EGLContext qemu_egl_rn_ctx;
 | 
				
			|||||||
int egl_rendernode_init(const char *rendernode);
 | 
					int egl_rendernode_init(const char *rendernode);
 | 
				
			||||||
int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc);
 | 
					int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf);
 | 
				
			||||||
 | 
					void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
 | 
					EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,7 @@ typedef struct VirtualGfxConsole {
 | 
				
			|||||||
    double scale_x;
 | 
					    double scale_x;
 | 
				
			||||||
    double scale_y;
 | 
					    double scale_y;
 | 
				
			||||||
#if defined(CONFIG_OPENGL)
 | 
					#if defined(CONFIG_OPENGL)
 | 
				
			||||||
    ConsoleGLState *gls;
 | 
					    QemuGLShader *gls;
 | 
				
			||||||
    EGLContext ectx;
 | 
					    EGLContext ectx;
 | 
				
			||||||
    EGLSurface esurface;
 | 
					    EGLSurface esurface;
 | 
				
			||||||
    int glupdates;
 | 
					    int glupdates;
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ struct sdl2_console {
 | 
				
			|||||||
    int idle_counter;
 | 
					    int idle_counter;
 | 
				
			||||||
    SDL_GLContext winctx;
 | 
					    SDL_GLContext winctx;
 | 
				
			||||||
#ifdef CONFIG_OPENGL
 | 
					#ifdef CONFIG_OPENGL
 | 
				
			||||||
    ConsoleGLState *gls;
 | 
					    QemuGLShader *gls;
 | 
				
			||||||
    egl_fb guest_fb;
 | 
					    egl_fb guest_fb;
 | 
				
			||||||
    egl_fb win_fb;
 | 
					    egl_fb win_fb;
 | 
				
			||||||
    bool y0_top;
 | 
					    bool y0_top;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,13 +3,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <epoxy/gl.h>
 | 
					#include <epoxy/gl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog);
 | 
					typedef struct QemuGLShader QemuGLShader;
 | 
				
			||||||
void qemu_gl_run_texture_blit(GLint texture_blit_prog,
 | 
					 | 
				
			||||||
                              GLint texture_blit_vao);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src);
 | 
					void qemu_gl_run_texture_blit(QemuGLShader *gls, bool flip);
 | 
				
			||||||
GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag);
 | 
					
 | 
				
			||||||
GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
 | 
					QemuGLShader *qemu_gl_init_shader(void);
 | 
				
			||||||
                                           const GLchar *frag_src);
 | 
					void qemu_gl_fini_shader(QemuGLShader *gls);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* QEMU_SHADER_H */
 | 
					#endif /* QEMU_SHADER_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -119,7 +119,7 @@ struct SimpleSpiceDisplay {
 | 
				
			|||||||
    /* opengl rendering */
 | 
					    /* opengl rendering */
 | 
				
			||||||
    QEMUBH *gl_unblock_bh;
 | 
					    QEMUBH *gl_unblock_bh;
 | 
				
			||||||
    QEMUTimer *gl_unblock_timer;
 | 
					    QEMUTimer *gl_unblock_timer;
 | 
				
			||||||
    ConsoleGLState *gls;
 | 
					    QemuGLShader *gls;
 | 
				
			||||||
    int gl_updates;
 | 
					    int gl_updates;
 | 
				
			||||||
    bool have_scanout;
 | 
					    bool have_scanout;
 | 
				
			||||||
    bool have_surface;
 | 
					    bool have_surface;
 | 
				
			||||||
 | 
				
			|||||||
@ -29,40 +29,8 @@
 | 
				
			|||||||
#include "ui/console.h"
 | 
					#include "ui/console.h"
 | 
				
			||||||
#include "ui/shader.h"
 | 
					#include "ui/shader.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "shader/texture-blit-vert.h"
 | 
					 | 
				
			||||||
#include "shader/texture-blit-frag.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct ConsoleGLState {
 | 
					 | 
				
			||||||
    GLint texture_blit_prog;
 | 
					 | 
				
			||||||
    GLint texture_blit_vao;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConsoleGLState *console_gl_init_context(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ConsoleGLState *gls = g_new0(ConsoleGLState, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gls->texture_blit_prog = qemu_gl_create_compile_link_program
 | 
					 | 
				
			||||||
        (texture_blit_vert_src, texture_blit_frag_src);
 | 
					 | 
				
			||||||
    if (!gls->texture_blit_prog) {
 | 
					 | 
				
			||||||
        exit(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gls->texture_blit_vao =
 | 
					 | 
				
			||||||
        qemu_gl_init_texture_blit(gls->texture_blit_prog);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return gls;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void console_gl_fini_context(ConsoleGLState *gls)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (!gls) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    g_free(gls);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool console_gl_check_format(DisplayChangeListener *dcl,
 | 
					bool console_gl_check_format(DisplayChangeListener *dcl,
 | 
				
			||||||
                             pixman_format_code_t format)
 | 
					                             pixman_format_code_t format)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -76,7 +44,7 @@ bool console_gl_check_format(DisplayChangeListener *dcl,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void surface_gl_create_texture(ConsoleGLState *gls,
 | 
					void surface_gl_create_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface)
 | 
					                               DisplaySurface *surface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(gls);
 | 
					    assert(gls);
 | 
				
			||||||
@ -116,7 +84,7 @@ void surface_gl_create_texture(ConsoleGLState *gls,
 | 
				
			|||||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
					    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void surface_gl_update_texture(ConsoleGLState *gls,
 | 
					void surface_gl_update_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface,
 | 
					                               DisplaySurface *surface,
 | 
				
			||||||
                               int x, int y, int w, int h)
 | 
					                               int x, int y, int w, int h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -133,7 +101,7 @@ void surface_gl_update_texture(ConsoleGLState *gls,
 | 
				
			|||||||
                    + surface_bytes_per_pixel(surface) * x);
 | 
					                    + surface_bytes_per_pixel(surface) * x);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void surface_gl_render_texture(ConsoleGLState *gls,
 | 
					void surface_gl_render_texture(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface)
 | 
					                               DisplaySurface *surface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(gls);
 | 
					    assert(gls);
 | 
				
			||||||
@ -141,11 +109,10 @@ void surface_gl_render_texture(ConsoleGLState *gls,
 | 
				
			|||||||
    glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
 | 
					    glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
 | 
				
			||||||
    glClear(GL_COLOR_BUFFER_BIT);
 | 
					    glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_gl_run_texture_blit(gls->texture_blit_prog,
 | 
					    qemu_gl_run_texture_blit(gls, false);
 | 
				
			||||||
                             gls->texture_blit_vao);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void surface_gl_destroy_texture(ConsoleGLState *gls,
 | 
					void surface_gl_destroy_texture(QemuGLShader *gls,
 | 
				
			||||||
                                DisplaySurface *surface)
 | 
					                                DisplaySurface *surface)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!surface || !surface->texture) {
 | 
					    if (!surface || !surface->texture) {
 | 
				
			||||||
@ -155,7 +122,7 @@ void surface_gl_destroy_texture(ConsoleGLState *gls,
 | 
				
			|||||||
    surface->texture = 0;
 | 
					    surface->texture = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void surface_gl_setup_viewport(ConsoleGLState *gls,
 | 
					void surface_gl_setup_viewport(QemuGLShader *gls,
 | 
				
			||||||
                               DisplaySurface *surface,
 | 
					                               DisplaySurface *surface,
 | 
				
			||||||
                               int ww, int wh)
 | 
					                               int ww, int wh)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										33
									
								
								ui/console.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								ui/console.c
									
									
									
									
									
								
							@ -1404,6 +1404,11 @@ bool console_has_gl(QemuConsole *con)
 | 
				
			|||||||
    return con->gl != NULL;
 | 
					    return con->gl != NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool console_has_gl_dmabuf(QemuConsole *con)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return con->gl != NULL && con->gl->ops->dpy_gl_scanout_dmabuf != NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void register_displaychangelistener(DisplayChangeListener *dcl)
 | 
					void register_displaychangelistener(DisplayChangeListener *dcl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static const char nodev[] =
 | 
					    static const char nodev[] =
 | 
				
			||||||
@ -1745,6 +1750,34 @@ void dpy_gl_scanout_texture(QemuConsole *con,
 | 
				
			|||||||
                                         x, y, width, height);
 | 
					                                         x, y, width, height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dpy_gl_scanout_dmabuf(QemuConsole *con,
 | 
				
			||||||
 | 
					                           QemuDmaBuf *dmabuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(con->gl);
 | 
				
			||||||
 | 
					    con->gl->ops->dpy_gl_scanout_dmabuf(con->gl, dmabuf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dpy_gl_cursor_dmabuf(QemuConsole *con,
 | 
				
			||||||
 | 
					                          QemuDmaBuf *dmabuf,
 | 
				
			||||||
 | 
					                          uint32_t pos_x, uint32_t pos_y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(con->gl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (con->gl->ops->dpy_gl_cursor_dmabuf) {
 | 
				
			||||||
 | 
					        con->gl->ops->dpy_gl_cursor_dmabuf(con->gl, dmabuf, pos_x, pos_y);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dpy_gl_release_dmabuf(QemuConsole *con,
 | 
				
			||||||
 | 
					                          QemuDmaBuf *dmabuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(con->gl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (con->gl->ops->dpy_gl_release_dmabuf) {
 | 
				
			||||||
 | 
					        con->gl->ops->dpy_gl_release_dmabuf(con->gl, dmabuf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dpy_gl_update(QemuConsole *con,
 | 
					void dpy_gl_update(QemuConsole *con,
 | 
				
			||||||
                   uint32_t x, uint32_t y, uint32_t w, uint32_t h)
 | 
					                   uint32_t x, uint32_t y, uint32_t w, uint32_t h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -4,13 +4,18 @@
 | 
				
			|||||||
#include "ui/console.h"
 | 
					#include "ui/console.h"
 | 
				
			||||||
#include "ui/egl-helpers.h"
 | 
					#include "ui/egl-helpers.h"
 | 
				
			||||||
#include "ui/egl-context.h"
 | 
					#include "ui/egl-context.h"
 | 
				
			||||||
 | 
					#include "ui/shader.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct egl_dpy {
 | 
					typedef struct egl_dpy {
 | 
				
			||||||
    DisplayChangeListener dcl;
 | 
					    DisplayChangeListener dcl;
 | 
				
			||||||
    DisplaySurface *ds;
 | 
					    DisplaySurface *ds;
 | 
				
			||||||
 | 
					    QemuGLShader *gls;
 | 
				
			||||||
    egl_fb guest_fb;
 | 
					    egl_fb guest_fb;
 | 
				
			||||||
 | 
					    egl_fb cursor_fb;
 | 
				
			||||||
    egl_fb blit_fb;
 | 
					    egl_fb blit_fb;
 | 
				
			||||||
    bool y_0_top;
 | 
					    bool y_0_top;
 | 
				
			||||||
 | 
					    uint32_t pos_x;
 | 
				
			||||||
 | 
					    uint32_t pos_y;
 | 
				
			||||||
} egl_dpy;
 | 
					} egl_dpy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ------------------------------------------------------------------ */
 | 
					/* ------------------------------------------------------------------ */
 | 
				
			||||||
@ -65,6 +70,43 @@ static void egl_scanout_texture(DisplayChangeListener *dcl,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void egl_scanout_dmabuf(DisplayChangeListener *dcl,
 | 
				
			||||||
 | 
					                               QemuDmaBuf *dmabuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    egl_dmabuf_import_texture(dmabuf);
 | 
				
			||||||
 | 
					    if (!dmabuf->texture) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    egl_scanout_texture(dcl, dmabuf->texture,
 | 
				
			||||||
 | 
					                        false, dmabuf->width, dmabuf->height,
 | 
				
			||||||
 | 
					                        0, 0, dmabuf->width, dmabuf->height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void egl_cursor_dmabuf(DisplayChangeListener *dcl,
 | 
				
			||||||
 | 
					                              QemuDmaBuf *dmabuf,
 | 
				
			||||||
 | 
					                              uint32_t pos_x, uint32_t pos_y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    egl_dpy *edpy = container_of(dcl, egl_dpy, dcl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    edpy->pos_x = pos_x;
 | 
				
			||||||
 | 
					    edpy->pos_y = pos_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    egl_dmabuf_import_texture(dmabuf);
 | 
				
			||||||
 | 
					    if (!dmabuf->texture) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    egl_fb_setup_for_tex(&edpy->cursor_fb, dmabuf->width, dmabuf->height,
 | 
				
			||||||
 | 
					                         dmabuf->texture, false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void egl_release_dmabuf(DisplayChangeListener *dcl,
 | 
				
			||||||
 | 
					                               QemuDmaBuf *dmabuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    egl_dmabuf_release_texture(dmabuf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void egl_scanout_flush(DisplayChangeListener *dcl,
 | 
					static void egl_scanout_flush(DisplayChangeListener *dcl,
 | 
				
			||||||
                              uint32_t x, uint32_t y,
 | 
					                              uint32_t x, uint32_t y,
 | 
				
			||||||
                              uint32_t w, uint32_t h)
 | 
					                              uint32_t w, uint32_t h)
 | 
				
			||||||
@ -78,9 +120,18 @@ static void egl_scanout_flush(DisplayChangeListener *dcl,
 | 
				
			|||||||
    assert(surface_height(edpy->ds) == edpy->guest_fb.height);
 | 
					    assert(surface_height(edpy->ds) == edpy->guest_fb.height);
 | 
				
			||||||
    assert(surface_format(edpy->ds) == PIXMAN_x8r8g8b8);
 | 
					    assert(surface_format(edpy->ds) == PIXMAN_x8r8g8b8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (edpy->cursor_fb.texture) {
 | 
				
			||||||
 | 
					        /* have cursor -> render using textures */
 | 
				
			||||||
 | 
					        egl_texture_blit(edpy->gls, &edpy->blit_fb, &edpy->guest_fb,
 | 
				
			||||||
 | 
					                         !edpy->y_0_top);
 | 
				
			||||||
 | 
					        egl_texture_blend(edpy->gls, &edpy->blit_fb, &edpy->cursor_fb,
 | 
				
			||||||
 | 
					                          !edpy->y_0_top, edpy->pos_x, edpy->pos_y);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        /* no cursor -> use simple framebuffer blit */
 | 
				
			||||||
        egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
 | 
					        egl_fb_blit(&edpy->blit_fb, &edpy->guest_fb, edpy->y_0_top);
 | 
				
			||||||
    egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    egl_fb_read(surface_data(edpy->ds), &edpy->blit_fb);
 | 
				
			||||||
    dpy_gfx_update(edpy->dcl.con, x, y, w, h);
 | 
					    dpy_gfx_update(edpy->dcl.con, x, y, w, h);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -97,6 +148,9 @@ static const DisplayChangeListenerOps egl_ops = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    .dpy_gl_scanout_disable  = egl_scanout_disable,
 | 
					    .dpy_gl_scanout_disable  = egl_scanout_disable,
 | 
				
			||||||
    .dpy_gl_scanout_texture  = egl_scanout_texture,
 | 
					    .dpy_gl_scanout_texture  = egl_scanout_texture,
 | 
				
			||||||
 | 
					    .dpy_gl_scanout_dmabuf   = egl_scanout_dmabuf,
 | 
				
			||||||
 | 
					    .dpy_gl_cursor_dmabuf    = egl_cursor_dmabuf,
 | 
				
			||||||
 | 
					    .dpy_gl_release_dmabuf   = egl_release_dmabuf,
 | 
				
			||||||
    .dpy_gl_update           = egl_scanout_flush,
 | 
					    .dpy_gl_update           = egl_scanout_flush,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -120,6 +174,7 @@ void egl_headless_init(void)
 | 
				
			|||||||
        edpy = g_new0(egl_dpy, 1);
 | 
					        edpy = g_new0(egl_dpy, 1);
 | 
				
			||||||
        edpy->dcl.con = con;
 | 
					        edpy->dcl.con = con;
 | 
				
			||||||
        edpy->dcl.ops = &egl_ops;
 | 
					        edpy->dcl.ops = &egl_ops;
 | 
				
			||||||
 | 
					        edpy->gls = qemu_gl_init_shader();
 | 
				
			||||||
        register_displaychangelistener(&edpy->dcl);
 | 
					        register_displaychangelistener(&edpy->dcl);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@
 | 
				
			|||||||
#include <dirent.h>
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "qemu/error-report.h"
 | 
					#include "qemu/error-report.h"
 | 
				
			||||||
 | 
					#include "ui/console.h"
 | 
				
			||||||
#include "ui/egl-helpers.h"
 | 
					#include "ui/egl-helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EGLDisplay *qemu_egl_display;
 | 
					EGLDisplay *qemu_egl_display;
 | 
				
			||||||
@ -110,6 +111,33 @@ void egl_fb_read(void *dst, egl_fb *src)
 | 
				
			|||||||
                 GL_BGRA, GL_UNSIGNED_BYTE, dst);
 | 
					                 GL_BGRA, GL_UNSIGNED_BYTE, dst);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    glBindFramebuffer(GL_FRAMEBUFFER_EXT, dst->framebuffer);
 | 
				
			||||||
 | 
					    glViewport(0, 0, dst->width, dst->height);
 | 
				
			||||||
 | 
					    glEnable(GL_TEXTURE_2D);
 | 
				
			||||||
 | 
					    glBindTexture(GL_TEXTURE_2D, src->texture);
 | 
				
			||||||
 | 
					    qemu_gl_run_texture_blit(gls, flip);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
 | 
				
			||||||
 | 
					                       int x, int y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    glBindFramebuffer(GL_FRAMEBUFFER_EXT, dst->framebuffer);
 | 
				
			||||||
 | 
					    if (flip) {
 | 
				
			||||||
 | 
					        glViewport(x, y, src->width, src->height);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        glViewport(x, dst->height - src->height - y,
 | 
				
			||||||
 | 
					                   src->width, src->height);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    glEnable(GL_TEXTURE_2D);
 | 
				
			||||||
 | 
					    glBindTexture(GL_TEXTURE_2D, src->texture);
 | 
				
			||||||
 | 
					    glEnable(GL_BLEND);
 | 
				
			||||||
 | 
					    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
				
			||||||
 | 
					    qemu_gl_run_texture_blit(gls, flip);
 | 
				
			||||||
 | 
					    glDisable(GL_BLEND);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_OPENGL_DMABUF
 | 
					#ifdef CONFIG_OPENGL_DMABUF
 | 
				
			||||||
@ -241,6 +269,51 @@ int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc)
 | 
				
			|||||||
    return fd;
 | 
					    return fd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EGLImageKHR image = EGL_NO_IMAGE_KHR;
 | 
				
			||||||
 | 
					    EGLint attrs[] = {
 | 
				
			||||||
 | 
					        EGL_DMA_BUF_PLANE0_FD_EXT,      dmabuf->fd,
 | 
				
			||||||
 | 
					        EGL_DMA_BUF_PLANE0_PITCH_EXT,   dmabuf->stride,
 | 
				
			||||||
 | 
					        EGL_DMA_BUF_PLANE0_OFFSET_EXT,  0,
 | 
				
			||||||
 | 
					        EGL_WIDTH,                      dmabuf->width,
 | 
				
			||||||
 | 
					        EGL_HEIGHT,                     dmabuf->height,
 | 
				
			||||||
 | 
					        EGL_LINUX_DRM_FOURCC_EXT,       dmabuf->fourcc,
 | 
				
			||||||
 | 
					        EGL_NONE, /* end of list */
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (dmabuf->texture != 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    image = eglCreateImageKHR(qemu_egl_display,
 | 
				
			||||||
 | 
					                              EGL_NO_CONTEXT,
 | 
				
			||||||
 | 
					                              EGL_LINUX_DMA_BUF_EXT,
 | 
				
			||||||
 | 
					                              NULL, attrs);
 | 
				
			||||||
 | 
					    if (image == EGL_NO_IMAGE_KHR) {
 | 
				
			||||||
 | 
					        error_report("eglCreateImageKHR failed");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glGenTextures(1, &dmabuf->texture);
 | 
				
			||||||
 | 
					    glBindTexture(GL_TEXTURE_2D, dmabuf->texture);
 | 
				
			||||||
 | 
					    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
				
			||||||
 | 
					    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
 | 
				
			||||||
 | 
					    eglDestroyImageKHR(qemu_egl_display, image);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dmabuf->texture == 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glDeleteTextures(1, &dmabuf->texture);
 | 
				
			||||||
 | 
					    dmabuf->texture = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CONFIG_OPENGL_DMABUF */
 | 
					#endif /* CONFIG_OPENGL_DMABUF */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
				
			|||||||
@ -113,7 +113,7 @@ void gd_egl_refresh(DisplayChangeListener *dcl)
 | 
				
			|||||||
        if (!vc->gfx.esurface) {
 | 
					        if (!vc->gfx.esurface) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        vc->gfx.gls = console_gl_init_context();
 | 
					        vc->gfx.gls = qemu_gl_init_shader();
 | 
				
			||||||
        if (vc->gfx.ds) {
 | 
					        if (vc->gfx.ds) {
 | 
				
			||||||
            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
 | 
					            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -96,7 +96,7 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl)
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
 | 
					        gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
 | 
				
			||||||
        vc->gfx.gls = console_gl_init_context();
 | 
					        vc->gfx.gls = qemu_gl_init_shader();
 | 
				
			||||||
        if (vc->gfx.ds) {
 | 
					        if (vc->gfx.ds) {
 | 
				
			||||||
            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
 | 
					            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,7 @@ void sdl2_gl_switch(DisplayChangeListener *dcl,
 | 
				
			|||||||
    scon->surface = new_surface;
 | 
					    scon->surface = new_surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!new_surface) {
 | 
					    if (!new_surface) {
 | 
				
			||||||
        console_gl_fini_context(scon->gls);
 | 
					        qemu_gl_fini_shader(scon->gls);
 | 
				
			||||||
        scon->gls = NULL;
 | 
					        scon->gls = NULL;
 | 
				
			||||||
        sdl2_window_destroy(scon);
 | 
					        sdl2_window_destroy(scon);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
@ -98,7 +98,7 @@ void sdl2_gl_switch(DisplayChangeListener *dcl,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (!scon->real_window) {
 | 
					    if (!scon->real_window) {
 | 
				
			||||||
        sdl2_window_create(scon);
 | 
					        sdl2_window_create(scon);
 | 
				
			||||||
        scon->gls = console_gl_init_context();
 | 
					        scon->gls = qemu_gl_init_shader();
 | 
				
			||||||
    } else if (old_surface &&
 | 
					    } else if (old_surface &&
 | 
				
			||||||
               ((surface_width(old_surface)  != surface_width(new_surface)) ||
 | 
					               ((surface_width(old_surface)  != surface_width(new_surface)) ||
 | 
				
			||||||
                (surface_height(old_surface) != surface_height(new_surface)))) {
 | 
					                (surface_height(old_surface) != surface_height(new_surface)))) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										55
									
								
								ui/shader.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								ui/shader.c
									
									
									
									
									
								
							@ -28,9 +28,19 @@
 | 
				
			|||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "ui/shader.h"
 | 
					#include "ui/shader.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "shader/texture-blit-vert.h"
 | 
				
			||||||
 | 
					#include "shader/texture-blit-flip-vert.h"
 | 
				
			||||||
 | 
					#include "shader/texture-blit-frag.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct QemuGLShader {
 | 
				
			||||||
 | 
					    GLint texture_blit_prog;
 | 
				
			||||||
 | 
					    GLint texture_blit_flip_prog;
 | 
				
			||||||
 | 
					    GLint texture_blit_vao;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
 | 
					static GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static const GLfloat in_position[] = {
 | 
					    static const GLfloat in_position[] = {
 | 
				
			||||||
        -1, -1,
 | 
					        -1, -1,
 | 
				
			||||||
@ -60,17 +70,18 @@ GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
 | 
				
			|||||||
    return vao;
 | 
					    return vao;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void qemu_gl_run_texture_blit(GLint texture_blit_prog,
 | 
					void qemu_gl_run_texture_blit(QemuGLShader *gls, bool flip)
 | 
				
			||||||
                              GLint texture_blit_vao)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    glUseProgram(texture_blit_prog);
 | 
					    glUseProgram(flip
 | 
				
			||||||
    glBindVertexArray(texture_blit_vao);
 | 
					                 ? gls->texture_blit_flip_prog
 | 
				
			||||||
 | 
					                 : gls->texture_blit_prog);
 | 
				
			||||||
 | 
					    glBindVertexArray(gls->texture_blit_vao);
 | 
				
			||||||
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 | 
					    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src)
 | 
					static GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GLuint shader;
 | 
					    GLuint shader;
 | 
				
			||||||
    GLint status, length;
 | 
					    GLint status, length;
 | 
				
			||||||
@ -94,7 +105,7 @@ GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src)
 | 
				
			|||||||
    return shader;
 | 
					    return shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
 | 
					static GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GLuint program;
 | 
					    GLuint program;
 | 
				
			||||||
    GLint status, length;
 | 
					    GLint status, length;
 | 
				
			||||||
@ -117,7 +128,7 @@ GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
 | 
				
			|||||||
    return program;
 | 
					    return program;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
 | 
					static GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
 | 
				
			||||||
                                                  const GLchar *frag_src)
 | 
					                                                  const GLchar *frag_src)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GLuint vert_shader, frag_shader, program;
 | 
					    GLuint vert_shader, frag_shader, program;
 | 
				
			||||||
@ -134,3 +145,31 @@ GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return program;
 | 
					    return program;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QemuGLShader *qemu_gl_init_shader(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QemuGLShader *gls = g_new0(QemuGLShader, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gls->texture_blit_prog = qemu_gl_create_compile_link_program
 | 
				
			||||||
 | 
					        (texture_blit_vert_src, texture_blit_frag_src);
 | 
				
			||||||
 | 
					    gls->texture_blit_flip_prog = qemu_gl_create_compile_link_program
 | 
				
			||||||
 | 
					        (texture_blit_flip_vert_src, texture_blit_frag_src);
 | 
				
			||||||
 | 
					    if (!gls->texture_blit_prog || !gls->texture_blit_flip_prog) {
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gls->texture_blit_vao =
 | 
				
			||||||
 | 
					        qemu_gl_init_texture_blit(gls->texture_blit_prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return gls;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void qemu_gl_fini_shader(QemuGLShader *gls)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!gls) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    g_free(gls);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								ui/shader/texture-blit-flip.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ui/shader/texture-blit-flip.vert
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					#version 300 es
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					in vec2  in_position;
 | 
				
			||||||
 | 
					out vec2 ex_tex_coord;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void main(void) {
 | 
				
			||||||
 | 
					    gl_Position = vec4(in_position, 0.0, 1.0);
 | 
				
			||||||
 | 
					    ex_tex_coord = vec2(1.0 + in_position.x, 1.0 + in_position.y) * 0.5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1019,7 +1019,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)
 | 
				
			|||||||
        ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
 | 
					        ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
 | 
				
			||||||
        ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
 | 
					        ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
 | 
				
			||||||
                                             qemu_spice_gl_block_timer, ssd);
 | 
					                                             qemu_spice_gl_block_timer, ssd);
 | 
				
			||||||
        ssd->gls = console_gl_init_context();
 | 
					        ssd->gls = qemu_gl_init_shader();
 | 
				
			||||||
        ssd->have_surface = false;
 | 
					        ssd->have_surface = false;
 | 
				
			||||||
        ssd->have_scanout = false;
 | 
					        ssd->have_scanout = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user