Hi, Sorry, I have no idea why --subject-prefix didn't actually work. These two patches are for the demos repo.
Cheers, Daniel On 17 July 2017 at 12:00, Daniel Stone <dani...@collabora.com> wrote: > The eglut_wayland event loop attempted to use frame events to drive the > redraw loop. However, the frame events were being requested after > eglSwapBuffers (i.e. wl_surface_commit()), which means they would not > actually activate until the next eglSwapBuffers. > > This was being balanced out by 'redisplay' being set immediately by > es2gears, which would do an instant-return poll before calling > eglSwapBuffers, which would internally wait on its own frame event, and > as a side effect trigger the frame event that eglut_wayland had just > placed, causing redraw to be called again. The result would be a > stuttering 40fps. > > Rewrite the event loop, so that: > - frame events are placed before eglSwapBuffers is called > - 'redisplay' no longer triggers an immediate return from poll > - the frame event handler redraws if redisplay is requested, and > exits if not > - if redisplay is requested whilst we do not have a pending frame > event, redraw instantly > > Reported-by: Daniel van Vugt <daniel.van.v...@canonical.com> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101814 > Signed-off-by: Daniel Stone <dani...@collabora.com> > --- > src/egl/eglut/eglut_wayland.c | 83 > +++++++++++++++++++++++++------------------ > 1 file changed, 48 insertions(+), 35 deletions(-) > > diff --git a/src/egl/eglut/eglut_wayland.c b/src/egl/eglut/eglut_wayland.c > index 968b33fe..6376acc0 100644 > --- a/src/egl/eglut/eglut_wayland.c > +++ b/src/egl/eglut/eglut_wayland.c > @@ -94,6 +94,7 @@ _eglutNativeInitDisplay(void) > wl_registry_destroy(registry); > > _eglut->surface_type = EGL_WINDOW_BIT; > + _eglut->redisplay = 1; > } > > void > @@ -149,19 +150,27 @@ static const struct wl_callback_listener frame_listener > = { > > static void > draw(void *data, struct wl_callback *callback, uint32_t time) > -{ > +{ > struct window *window = (struct window *)data; > struct eglut_window *win = _eglut->current; > > + if (callback) { > + wl_callback_destroy(callback); > + window->callback = NULL; > + } > + > + /* Our client doesn't want to push another frame; go back to sleep. */ > + if (!_eglut->redisplay) > + return; > + _eglut->redisplay = 0; > + > if (win->display_cb) > win->display_cb(); > - eglSwapBuffers(_eglut->dpy, win->surface); > - > - if (callback) > - wl_callback_destroy(callback); > > window->callback = wl_surface_frame(window->surface); > wl_callback_add_listener(window->callback, &frame_listener, window); > + > + eglSwapBuffers(_eglut->dpy, win->surface); > } > > void > @@ -170,53 +179,57 @@ _eglutNativeEventLoop(void) > struct pollfd pollfd; > int ret; > > - draw(&window, NULL, 0); > - > pollfd.fd = wl_display_get_fd(display.display); > pollfd.events = POLLIN; > pollfd.revents = 0; > > while (1) { > - wl_display_dispatch_pending(display.display); > - > - if (_eglut->idle_cb) > - _eglut->idle_cb(); > + /* If we need to flush but can't, don't do anything at all which could > + * push further events into the socket. */ > + if (!(pollfd.events & POLLOUT)) { > + wl_display_dispatch_pending(display.display); > + > + if (_eglut->idle_cb) > + _eglut->idle_cb(); > + > + /* Client wants to redraw, but we have no frame event to trigger the > + * redraw; kickstart it by redrawing immediately. */ > + if (_eglut->redisplay && !window.callback) > + draw(&window, NULL, 0); > + } > > ret = wl_display_flush(display.display); > - if (ret < 0 && errno == EAGAIN) > - pollfd.events |= POLLOUT; > - else if (ret < 0) > - break; > - > - if (poll(&pollfd, 1, _eglut->redisplay ? 0 : -1) == -1) > + if (ret < 0 && errno != EAGAIN) > + break; /* fatal error; socket is broken */ > + else if (ret < 0 && errno == EAGAIN) > + pollfd.events |= POLLOUT; /* need to wait until we can flush */ > + else > + pollfd.events &= ~POLLOUT; /* successfully flushed */ > + > + if (poll(&pollfd, 1, -1) == -1) > break; > > if (pollfd.revents & (POLLERR | POLLHUP)) > break; > > + if (pollfd.events & POLLOUT) { > + if (!(pollfd.revents & POLLOUT)) > + continue; /* block until we can flush */ > + pollfd.events &= ~POLLOUT; > + } > + > if (pollfd.revents & POLLIN) { > ret = wl_display_dispatch(display.display); > if (ret == -1) > break; > } > > - if (pollfd.revents & POLLOUT) { > - ret = wl_display_flush(display.display); > - if (ret == 0) > - pollfd.events &= ~POLLOUT; > - else if (ret == -1 && errno != EAGAIN) > - break; > - } > - > - if (_eglut->redisplay) { > - struct eglut_window *win = _eglut->current; > - > - _eglut->redisplay = 0; > - > - if (win->display_cb) > - win->display_cb(); > - > - eglSwapBuffers(_eglut->dpy, win->surface); > - } > + ret = wl_display_flush(display.display); > + if (ret < 0 && errno != EAGAIN) > + break; /* fatal error; socket is broken */ > + else if (ret < 0 && errno == EAGAIN) > + pollfd.events |= POLLOUT; /* need to wait until we can flush */ > + else > + pollfd.events &= ~POLLOUT; /* successfully flushed */ > } > } > -- > 2.13.3 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev