ui: sdl2 fixes, gles support.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJbMkX/AAoJEEy22O7T6HE4nsYQAMXS8PeZj4DLHnpU9uPe5B4o
 iJvtU5TUTIv4zTTG8YUjJMzZ3js6jTPUg38jeD/U8dZgvjnxsFuZnZmaO936b8hs
 P3cOgrSamj2cxs9DqyHbdZEBMygajeiSDDk5aHzcN9viM/RV6bLvZrnhgPhN9vm2
 bDCiUDMVMCHtuOcGvoDpjh0NWV2h/hKMpo99rObM4mYvEyU2sU/skLaO8sR3FSLk
 q7x5FrT7NMGXAckYw4nvT0PuOGmC12o+DCCWtQgvPAV4LWPfGlW4egHSVZgSolZ9
 s5QA+zHDJDcYBiT6r1jSBzKXSk1d4yI70C3zPRpZvcakBwrwCoHRWpJvkXyA62d3
 8GK04kejb1reVa3hIFIGiIqsRhKnNjc83Cdpui7STORo+u5lqQP68Z0KQYAMJhoK
 mafLZLDPyhzjeZZzJIDgAeiQ+Wa7FVW2N5yCEK1nez3I5YbsB84/NMBuLxzJPgaD
 eD1FHs1SiD0HF+Iqpv/+DnruCiBBm0B/EMDutECplvRIWC+O5aCjG46Fuo3rftUl
 JELK+aUwfzb8qJ0sGcAMVaV/AAqISDPA84jQ32Ok/8FB54c3rkodSB1//9NK7jLh
 4B6PW5gmBXWNatGrInjXOo0Hr2sXIW69a5UCbIpjJTdEjW2WHnT36ugwzOghdWic
 +jpNr9mQlZlbpOUFsOqN
 =t+1l
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/ui-20180626-pull-request' into staging

ui: sdl2 fixes, gles support.

# gpg: Signature made Tue 26 Jun 2018 14:56:15 BST
# gpg:                using RSA key 4CB6D8EED3E87138
# 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/ui-20180626-pull-request:
  sdl2: add checking for NULL
  sdl2: fix copypaste issues
  Add gles support to egl-helpers, wire up in egl-headless and gtk.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-06-26 16:44:57 +01:00
commit 0ab4c574a5
9 changed files with 68 additions and 38 deletions

View file

@ -7,6 +7,7 @@
extern EGLDisplay *qemu_egl_display; extern EGLDisplay *qemu_egl_display;
extern EGLConfig qemu_egl_config; extern EGLConfig qemu_egl_config;
extern DisplayGLMode qemu_egl_mode;
typedef struct egl_fb { typedef struct egl_fb {
int width; int width;
@ -34,7 +35,7 @@ extern int qemu_egl_rn_fd;
extern struct gbm_device *qemu_egl_rn_gbm_dev; extern struct gbm_device *qemu_egl_rn_gbm_dev;
extern EGLContext qemu_egl_rn_ctx; extern EGLContext qemu_egl_rn_ctx;
int egl_rendernode_init(const char *rendernode); int egl_rendernode_init(const char *rendernode, DisplayGLMode mode);
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_import_texture(QemuDmaBuf *dmabuf);
@ -44,8 +45,8 @@ void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win); EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
int qemu_egl_init_dpy_x11(EGLNativeDisplayType dpy); int qemu_egl_init_dpy_x11(EGLNativeDisplayType dpy, DisplayGLMode mode);
int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy); int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy, DisplayGLMode mode);
EGLContext qemu_egl_init_ctx(void); EGLContext qemu_egl_init_ctx(void);
#endif /* EGL_HELPERS_H */ #endif /* EGL_HELPERS_H */

View file

@ -127,7 +127,7 @@ void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
QemuDmaBuf *dmabuf); QemuDmaBuf *dmabuf);
void gd_egl_scanout_flush(DisplayChangeListener *dcl, void gd_egl_scanout_flush(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);
void gtk_egl_init(void); void gtk_egl_init(DisplayGLMode mode);
int gd_egl_make_current(DisplayChangeListener *dcl, int gd_egl_make_current(DisplayChangeListener *dcl,
QEMUGLContext ctx); QEMUGLContext ctx);

View file

@ -6,15 +6,22 @@ QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,
QEMUGLParams *params) QEMUGLParams *params)
{ {
EGLContext ctx; EGLContext ctx;
EGLint ctx_att[] = { EGLint ctx_att_core[] = {
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_CONTEXT_CLIENT_VERSION, params->major_ver, EGL_CONTEXT_CLIENT_VERSION, params->major_ver,
EGL_CONTEXT_MINOR_VERSION_KHR, params->minor_ver, EGL_CONTEXT_MINOR_VERSION_KHR, params->minor_ver,
EGL_NONE EGL_NONE
}; };
EGLint ctx_att_gles[] = {
EGL_CONTEXT_CLIENT_VERSION, params->major_ver,
EGL_CONTEXT_MINOR_VERSION_KHR, params->minor_ver,
EGL_NONE
};
bool gles = (qemu_egl_mode == DISPLAYGL_MODE_ES);
ctx = eglCreateContext(qemu_egl_display, qemu_egl_config, ctx = eglCreateContext(qemu_egl_display, qemu_egl_config,
eglGetCurrentContext(), ctx_att); eglGetCurrentContext(),
gles ? ctx_att_gles : ctx_att_core);
return ctx; return ctx;
} }

View file

@ -171,11 +171,12 @@ static void early_egl_headless_init(DisplayOptions *opts)
static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) static void egl_headless_init(DisplayState *ds, DisplayOptions *opts)
{ {
DisplayGLMode mode = opts->has_gl ? opts->gl : DISPLAYGL_MODE_ON;
QemuConsole *con; QemuConsole *con;
egl_dpy *edpy; egl_dpy *edpy;
int idx; int idx;
if (egl_rendernode_init(NULL) < 0) { if (egl_rendernode_init(NULL, mode) < 0) {
error_report("egl: render node init failed"); error_report("egl: render node init failed");
exit(1); exit(1);
} }

View file

@ -24,6 +24,7 @@
EGLDisplay *qemu_egl_display; EGLDisplay *qemu_egl_display;
EGLConfig qemu_egl_config; EGLConfig qemu_egl_config;
DisplayGLMode qemu_egl_mode;
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
@ -191,7 +192,7 @@ static int qemu_egl_rendernode_open(const char *rendernode)
return fd; return fd;
} }
int egl_rendernode_init(const char *rendernode) int egl_rendernode_init(const char *rendernode, DisplayGLMode mode)
{ {
qemu_egl_rn_fd = -1; qemu_egl_rn_fd = -1;
int rc; int rc;
@ -208,7 +209,8 @@ int egl_rendernode_init(const char *rendernode)
goto err; goto err;
} }
rc = qemu_egl_init_dpy_mesa((EGLNativeDisplayType)qemu_egl_rn_gbm_dev); rc = qemu_egl_init_dpy_mesa((EGLNativeDisplayType)qemu_egl_rn_gbm_dev,
mode);
if (rc != 0) { if (rc != 0) {
/* qemu_egl_init_dpy_mesa reports error */ /* qemu_egl_init_dpy_mesa reports error */
goto err; goto err;
@ -392,9 +394,10 @@ static EGLDisplay qemu_egl_get_display(EGLNativeDisplayType native,
} }
static int qemu_egl_init_dpy(EGLNativeDisplayType dpy, static int qemu_egl_init_dpy(EGLNativeDisplayType dpy,
EGLenum platform) EGLenum platform,
DisplayGLMode mode)
{ {
static const EGLint conf_att_gl[] = { static const EGLint conf_att_core[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_RED_SIZE, 5, EGL_RED_SIZE, 5,
@ -403,9 +406,19 @@ static int qemu_egl_init_dpy(EGLNativeDisplayType dpy,
EGL_ALPHA_SIZE, 0, EGL_ALPHA_SIZE, 0,
EGL_NONE, EGL_NONE,
}; };
static const EGLint conf_att_gles[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 5,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 0,
EGL_NONE,
};
EGLint major, minor; EGLint major, minor;
EGLBoolean b; EGLBoolean b;
EGLint n; EGLint n;
bool gles = (mode == DISPLAYGL_MODE_ES);
qemu_egl_display = qemu_egl_get_display(dpy, platform); qemu_egl_display = qemu_egl_get_display(dpy, platform);
if (qemu_egl_display == EGL_NO_DISPLAY) { if (qemu_egl_display == EGL_NO_DISPLAY) {
@ -419,50 +432,60 @@ static int qemu_egl_init_dpy(EGLNativeDisplayType dpy,
return -1; return -1;
} }
b = eglBindAPI(EGL_OPENGL_API); b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
if (b == EGL_FALSE) { if (b == EGL_FALSE) {
error_report("egl: eglBindAPI failed"); error_report("egl: eglBindAPI failed (%s mode)",
gles ? "gles" : "core");
return -1; return -1;
} }
b = eglChooseConfig(qemu_egl_display, conf_att_gl, b = eglChooseConfig(qemu_egl_display,
gles ? conf_att_gles : conf_att_core,
&qemu_egl_config, 1, &n); &qemu_egl_config, 1, &n);
if (b == EGL_FALSE || n != 1) { if (b == EGL_FALSE || n != 1) {
error_report("egl: eglChooseConfig failed"); error_report("egl: eglChooseConfig failed (%s mode)",
gles ? "gles" : "core");
return -1; return -1;
} }
qemu_egl_mode = gles ? DISPLAYGL_MODE_ES : DISPLAYGL_MODE_CORE;
return 0; return 0;
} }
int qemu_egl_init_dpy_x11(EGLNativeDisplayType dpy) int qemu_egl_init_dpy_x11(EGLNativeDisplayType dpy, DisplayGLMode mode)
{ {
#ifdef EGL_KHR_platform_x11 #ifdef EGL_KHR_platform_x11
return qemu_egl_init_dpy(dpy, EGL_PLATFORM_X11_KHR); return qemu_egl_init_dpy(dpy, EGL_PLATFORM_X11_KHR, mode);
#else #else
return qemu_egl_init_dpy(dpy, 0); return qemu_egl_init_dpy(dpy, 0, mode);
#endif #endif
} }
int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy) int qemu_egl_init_dpy_mesa(EGLNativeDisplayType dpy, DisplayGLMode mode)
{ {
#ifdef EGL_MESA_platform_gbm #ifdef EGL_MESA_platform_gbm
return qemu_egl_init_dpy(dpy, EGL_PLATFORM_GBM_MESA); return qemu_egl_init_dpy(dpy, EGL_PLATFORM_GBM_MESA, mode);
#else #else
return qemu_egl_init_dpy(dpy, 0); return qemu_egl_init_dpy(dpy, 0, mode);
#endif #endif
} }
EGLContext qemu_egl_init_ctx(void) EGLContext qemu_egl_init_ctx(void)
{ {
static const EGLint ctx_att_gl[] = { static const EGLint ctx_att_core[] = {
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_NONE EGL_NONE
}; };
static const EGLint ctx_att_gles[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
bool gles = (qemu_egl_mode == DISPLAYGL_MODE_ES);
EGLContext ectx; EGLContext ectx;
EGLBoolean b; EGLBoolean b;
ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT, ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
ctx_att_gl); gles ? ctx_att_gles : ctx_att_core);
if (ectx == EGL_NO_CONTEXT) { if (ectx == EGL_NO_CONTEXT) {
error_report("egl: eglCreateContext failed"); error_report("egl: eglCreateContext failed");
return NULL; return NULL;

View file

@ -280,12 +280,12 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
eglSwapBuffers(qemu_egl_display, vc->gfx.esurface); eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
} }
void gtk_egl_init(void) void gtk_egl_init(DisplayGLMode mode)
{ {
GdkDisplay *gdk_display = gdk_display_get_default(); GdkDisplay *gdk_display = gdk_display_get_default();
Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display); Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
if (qemu_egl_init_dpy_x11(x11_display) < 0) { if (qemu_egl_init_dpy_x11(x11_display, mode) < 0) {
return; return;
} }

View file

@ -2485,10 +2485,6 @@ static void early_gtk_display_init(DisplayOptions *opts)
assert(opts->type == DISPLAY_TYPE_GTK); assert(opts->type == DISPLAY_TYPE_GTK);
if (opts->has_gl && opts->gl != DISPLAYGL_MODE_OFF) { if (opts->has_gl && opts->gl != DISPLAYGL_MODE_OFF) {
if (opts->gl == DISPLAYGL_MODE_ES) {
error_report("gtk: opengl es not supported");
return;
}
#if defined(CONFIG_OPENGL) #if defined(CONFIG_OPENGL)
#if defined(CONFIG_GTK_GL) && defined(GDK_WINDOWING_WAYLAND) #if defined(CONFIG_GTK_GL) && defined(GDK_WINDOWING_WAYLAND)
if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
@ -2497,7 +2493,8 @@ static void early_gtk_display_init(DisplayOptions *opts)
} else } else
#endif #endif
{ {
gtk_egl_init(); DisplayGLMode mode = opts->has_gl ? opts->gl : DISPLAYGL_MODE_ON;
gtk_egl_init(mode);
} }
#endif #endif
} }

View file

@ -424,7 +424,7 @@ static void handle_keyup(SDL_Event *ev)
static void handle_textinput(SDL_Event *ev) static void handle_textinput(SDL_Event *ev)
{ {
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); struct sdl2_console *scon = get_scon_from_window(ev->text.windowID);
QemuConsole *con = scon ? scon->dcl.con : NULL; QemuConsole *con = scon ? scon->dcl.con : NULL;
if (qemu_console_is_graphic(con)) { if (qemu_console_is_graphic(con)) {
@ -436,9 +436,9 @@ static void handle_textinput(SDL_Event *ev)
static void handle_mousemotion(SDL_Event *ev) static void handle_mousemotion(SDL_Event *ev)
{ {
int max_x, max_y; int max_x, max_y;
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); struct sdl2_console *scon = get_scon_from_window(ev->motion.windowID);
if (!qemu_console_is_graphic(scon->dcl.con)) { if (!scon || !qemu_console_is_graphic(scon->dcl.con)) {
return; return;
} }
@ -468,9 +468,9 @@ static void handle_mousebutton(SDL_Event *ev)
{ {
int buttonstate = SDL_GetMouseState(NULL, NULL); int buttonstate = SDL_GetMouseState(NULL, NULL);
SDL_MouseButtonEvent *bev; SDL_MouseButtonEvent *bev;
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); struct sdl2_console *scon = get_scon_from_window(ev->button.windowID);
if (!qemu_console_is_graphic(scon->dcl.con)) { if (!scon || !qemu_console_is_graphic(scon->dcl.con)) {
return; return;
} }
@ -492,11 +492,11 @@ static void handle_mousebutton(SDL_Event *ev)
static void handle_mousewheel(SDL_Event *ev) static void handle_mousewheel(SDL_Event *ev)
{ {
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); struct sdl2_console *scon = get_scon_from_window(ev->wheel.windowID);
SDL_MouseWheelEvent *wev = &ev->wheel; SDL_MouseWheelEvent *wev = &ev->wheel;
InputButton btn; InputButton btn;
if (!qemu_console_is_graphic(scon->dcl.con)) { if (!scon || !qemu_console_is_graphic(scon->dcl.con)) {
return; return;
} }

View file

@ -829,7 +829,8 @@ void qemu_spice_init(void)
"incompatible with -spice port/tls-port"); "incompatible with -spice port/tls-port");
exit(1); exit(1);
} }
if (egl_rendernode_init(qemu_opt_get(opts, "rendernode")) != 0) { if (egl_rendernode_init(qemu_opt_get(opts, "rendernode"),
DISPLAYGL_MODE_ON) != 0) {
error_report("Failed to initialize EGL render node for SPICE GL"); error_report("Failed to initialize EGL render node for SPICE GL");
exit(1); exit(1);
} }