compositor-x11: Call finish_frame from a timer callback
authorKristian Høgsberg <krh@bitplanet.net>
Sat, 29 Oct 2011 18:39:13 +0000 (14:39 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Sat, 29 Oct 2011 18:39:13 +0000 (14:39 -0400)
The repaint logic breaks when finish_frame is called from the present
callback.  Ideally we should throttle to vsync (or even better, the
compositor repaint cycle, but hey, X is X), but this goes a long way.

compositor/compositor-x11.c

index d077029..4962b5e 100644 (file)
@@ -77,6 +77,7 @@ struct x11_output {
        xcb_window_t            window;
        EGLSurface              egl_surface;
        struct wlsc_mode        mode;
+       struct wl_event_source *finish_frame_timer;
 };
 
 struct x11_input {
@@ -180,21 +181,31 @@ x11_output_prepare_render(struct wlsc_output *output_base)
 }
 
 static int
+finish_frame_handler(void *data)
+{
+       struct x11_output *output = data;
+       uint32_t msec;
+       struct timeval tv;
+       
+       gettimeofday(&tv, NULL);
+       msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+       wlsc_output_finish_frame(&output->base, msec);
+
+       return 1;
+}
+
+static int
 x11_output_present(struct wlsc_output *output_base)
 {
        struct x11_output *output = (struct x11_output *) output_base;
        struct wlsc_compositor *ec = output->base.compositor;
-       struct timeval tv;
-       uint32_t msec;
 
        if (x11_output_prepare_render(&output->base))
                return -1;
 
        eglSwapBuffers(ec->display, output->egl_surface);
 
-       gettimeofday(&tv, NULL);
-       msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
-       wlsc_output_finish_frame(&output->base, msec);
+       wl_event_source_timer_update(output->finish_frame_timer, 10);
 
        return 0;
 }
@@ -319,6 +330,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
        struct x11_output *output;
        xcb_screen_iterator_t iter;
        struct wm_normal_hints normal_hints;
+       struct wl_event_loop *loop;
        uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
        uint32_t values[2] = { 
                XCB_EVENT_MASK_KEY_PRESS |
@@ -412,6 +424,10 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
                return -1;
        }
 
+       loop = wl_display_get_event_loop(c->base.wl_display);
+       output->finish_frame_timer =
+               wl_event_loop_add_timer(loop, finish_frame_handler, output);
+
        output->base.prepare_render = x11_output_prepare_render;
        output->base.present = x11_output_present;
        output->base.prepare_scanout_surface =