simple-egl: Defer EGL surface/window creation
Rather than creating the wl_egl_window at the same time as wl_surface, do it after we get the first configure event. With it, we also defer eglMakeCurrent() as according to the spec, the first time a OpenGL or OpenGL ES context is made current, the viewport and scissor dimensions are set to the size of the draw surface. This is particulary important when attempting to start simple-egl either as fullscreen or as maximized, as not doing so will either incorrectly commit a buffer with the original dimensions, and later on to resize to the correct dimensions (which is the case for fullscreen), or it will terminate the wayland connection abruptly due to xdg-shell protocol violation, with a mismatch for the client's geometry (the case for maximized). Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Suggested-by: Daniel Stone <daniel.stone@collabora.com>
This commit is contained in:
parent
c15699b7f8
commit
0277046a1d
@ -262,6 +262,19 @@ init_gl(struct window *window)
|
||||
GLuint frag, vert;
|
||||
GLuint program;
|
||||
GLint status;
|
||||
EGLBoolean ret;
|
||||
|
||||
window->native = wl_egl_window_create(window->surface,
|
||||
window->geometry.width,
|
||||
window->geometry.height);
|
||||
window->egl_surface =
|
||||
weston_platform_create_egl_surface(window->display->egl.dpy,
|
||||
window->display->egl.conf,
|
||||
window->native, NULL);
|
||||
|
||||
ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
|
||||
window->egl_surface, window->display->egl.ctx);
|
||||
assert(ret == EGL_TRUE);
|
||||
|
||||
frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER);
|
||||
vert = create_shader(window, vert_shader_text, GL_VERTEX_SHADER);
|
||||
@ -362,19 +375,9 @@ static void
|
||||
create_surface(struct window *window)
|
||||
{
|
||||
struct display *display = window->display;
|
||||
EGLBoolean ret;
|
||||
|
||||
window->surface = wl_compositor_create_surface(display->compositor);
|
||||
|
||||
window->native =
|
||||
wl_egl_window_create(window->surface,
|
||||
window->geometry.width,
|
||||
window->geometry.height);
|
||||
window->egl_surface =
|
||||
weston_platform_create_egl_surface(display->egl.dpy,
|
||||
display->egl.conf,
|
||||
window->native, NULL);
|
||||
|
||||
window->xdg_surface = xdg_wm_base_get_xdg_surface(display->wm_base,
|
||||
window->surface);
|
||||
xdg_surface_add_listener(window->xdg_surface,
|
||||
@ -392,10 +395,6 @@ create_surface(struct window *window)
|
||||
window->wait_for_configure = true;
|
||||
wl_surface_commit(window->surface);
|
||||
|
||||
ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
|
||||
window->egl_surface, window->display->egl.ctx);
|
||||
assert(ret == EGL_TRUE);
|
||||
|
||||
if (!window->frame_sync)
|
||||
eglSwapInterval(display->egl.dpy, 0);
|
||||
|
||||
@ -866,7 +865,17 @@ main(int argc, char **argv)
|
||||
|
||||
init_egl(&display, &window);
|
||||
create_surface(&window);
|
||||
init_gl(&window);
|
||||
|
||||
/* we already have wait_for_configure set after create_surface() */
|
||||
while (running && ret != -1 && window.wait_for_configure) {
|
||||
ret = wl_display_dispatch(display.display);
|
||||
|
||||
/* wait until xdg_surface::configure acks the new dimensions */
|
||||
if (window.wait_for_configure)
|
||||
continue;
|
||||
|
||||
init_gl(&window);
|
||||
}
|
||||
|
||||
display.cursor_surface =
|
||||
wl_compositor_create_surface(display.compositor);
|
||||
@ -876,17 +885,9 @@ main(int argc, char **argv)
|
||||
sigint.sa_flags = SA_RESETHAND;
|
||||
sigaction(SIGINT, &sigint, NULL);
|
||||
|
||||
/* The mainloop here is a little subtle. Redrawing will cause
|
||||
* EGL to read events so we can just call
|
||||
* wl_display_dispatch_pending() to handle any events that got
|
||||
* queued up as a side effect. */
|
||||
while (running && ret != -1) {
|
||||
if (window.wait_for_configure) {
|
||||
ret = wl_display_dispatch(display.display);
|
||||
} else {
|
||||
ret = wl_display_dispatch_pending(display.display);
|
||||
redraw(&window, NULL, 0);
|
||||
}
|
||||
ret = wl_display_dispatch_pending(display.display);
|
||||
redraw(&window, NULL, 0);
|
||||
}
|
||||
|
||||
fprintf(stderr, "simple-egl exiting\n");
|
||||
|
Loading…
Reference in New Issue
Block a user