Use the new wl_callback interface
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 17 Aug 2011 03:01:28 +0000 (23:01 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Mon, 29 Aug 2011 21:12:36 +0000 (17:12 -0400)
clients/simple-egl.c
clients/simple-shm.c
clients/window.c
compositor/compositor-wayland.c
compositor/compositor.c
compositor/compositor.h

index f2a1f77..2ffbee2 100644 (file)
@@ -190,14 +190,6 @@ init_gl(struct window *window)
 }
 
 static void
-sync_callback(void *data)
-{
-       int *done = data;
-
-       *done = 1;
-}
-
-static void
 create_surface(struct window *window)
 {
        struct display *display = window->display;
@@ -205,14 +197,11 @@ create_surface(struct window *window)
        EGLBoolean ret;
        int done = 0;
        
+       if (!display->premultiplied_argb_visual)
+               wl_display_roundtrip(display->display);
        if (!display->premultiplied_argb_visual) {
-               wl_display_sync_callback(display->display, sync_callback, &done);
-               while (!done)
-                       wl_display_iterate(display->display, display->mask);
-               if (!display->premultiplied_argb_visual) {
-                       fprintf(stderr, "premultiplied argb visual missing\n");
-                       exit(1);
-               }
+               fprintf(stderr, "premultiplied argb visual missing\n");
+               exit(1);
        }
 
        window->surface = wl_compositor_create_surface(display->compositor);
@@ -235,8 +224,10 @@ create_surface(struct window *window)
        assert(ret == EGL_TRUE);
 }
 
+static const struct wl_callback_listener frame_listener;
+
 static void
-redraw(struct wl_surface *surface, void *data, uint32_t time)
+redraw(void *data, struct wl_callback *callback, uint32_t time)
 {
        struct window *window = data;
        static const GLfloat verts[3][2] = {
@@ -287,11 +278,17 @@ redraw(struct wl_surface *surface, void *data, uint32_t time)
        glFlush();
 
        eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
-       wl_display_frame_callback(window->display->display,
-                                 window->surface,
-                                 redraw, window);
+       if (callback)
+               wl_callback_destroy(callback);
+
+       callback = wl_surface_frame(window->surface);
+       wl_callback_add_listener(callback, &frame_listener, window);
 }
 
+static const struct wl_callback_listener frame_listener = {
+       redraw
+};
+
 static void
 compositor_handle_visual(void *data,
                         struct wl_compositor *compositor,
@@ -356,12 +353,13 @@ main(int argc, char **argv)
                                       display_handle_global, &display);
 
        wl_display_get_fd(display.display, event_mask_update, &display);
+       wl_display_iterate(display.display, WL_DISPLAY_READABLE);
 
        init_egl(&display);
        create_surface(&window);
        init_gl(&window);
 
-       redraw(window.surface, &window, 0);
+       redraw(&window, NULL, 0);
 
        while (true)
                wl_display_iterate(display.display, display.mask);
index 9e8a978..7b45005 100644 (file)
@@ -112,8 +112,10 @@ create_window(struct display *display, int width, int height)
        return window;
 }
 
+static const struct wl_callback_listener frame_listener;
+
 static void
-redraw(struct wl_surface *surface, void *data, uint32_t time)
+redraw(void *data, struct wl_callback *callback, uint32_t time)
 {
        struct window *window = data;
        uint32_t *p;
@@ -130,11 +132,17 @@ redraw(struct wl_surface *surface, void *data, uint32_t time)
        wl_surface_damage(window->surface,
                          0, 0, window->width, window->height);
 
-       wl_display_frame_callback(window->display->display,
-                                 window->surface,
-                                 redraw, window);
+       if (callback)
+               wl_callback_destroy(callback);
+
+       callback = wl_surface_frame(window->surface);
+       wl_callback_add_listener(callback, &frame_listener, window);
 }
 
+static const struct wl_callback_listener frame_listener = {
+       redraw
+};
+
 static void
 compositor_handle_visual(void *data,
                         struct wl_compositor *compositor,
@@ -180,19 +188,10 @@ event_mask_update(uint32_t mask, void *data)
        return 0;
 }
 
-static void
-sync_callback(void *data)
-{
-       int *done = data;
-
-       *done = 1;
-}
-
 static struct display *
 create_display(void)
 {
        struct display *display;
-       int done;
 
        display = malloc(sizeof *display);
        display->display = wl_display_connect(NULL);
@@ -204,9 +203,8 @@ create_display(void)
 
        wl_display_get_fd(display->display, event_mask_update, display);
        
-       wl_display_sync_callback(display->display, sync_callback, &done);
        while (!display->xrgb_visual)
-               wl_display_iterate(display->display, display->mask);
+               wl_display_roundtrip(display->display);
 
        return display;
 }
@@ -220,7 +218,7 @@ main(int argc, char **argv)
        display = create_display();
        window = create_window(display, 250, 250);
 
-       redraw(window->surface, window, 0);
+       redraw(window, NULL, 0);
 
        while (true)
                wl_display_iterate(display->display, display->mask);
index 5679f89..30a1179 100644 (file)
@@ -1887,25 +1887,6 @@ init_egl(struct display *d)
        return 0;
 }
 
-static void
-sync_callback(void *data)
-{
-       int *done = data;
-
-       *done = 1;
-}
-
-static void
-force_roundtrip(struct display *d)
-{
-       int done = 0;
-
-       wl_display_sync_callback(d->display, sync_callback, &done);
-       wl_display_iterate(d->display, WL_DISPLAY_WRITABLE);
-       while (!done)
-               wl_display_iterate(d->display, WL_DISPLAY_READABLE);
-}
-
 struct display *
 display_create(int *argc, char **argv[], const GOptionEntry *option_entries,
               display_global_handler_t handler)
@@ -1966,7 +1947,7 @@ display_create(int *argc, char **argv[], const GOptionEntry *option_entries,
        d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
 
        if (!d->premultiplied_argb_visual || !d->rgb_visual) {
-               force_roundtrip(d);
+               wl_display_roundtrip(d->display);
                if (!d->premultiplied_argb_visual || !d->rgb_visual) {
                        fprintf(stderr, "failed to retreive visuals\n");
                        return NULL;
index df63daf..fad04aa 100644 (file)
@@ -157,14 +157,6 @@ wayland_compositor_init_egl(struct wayland_compositor *c)
        return 0;
 }
 
-static void
-frame_callback(struct wl_surface *surface, void *data, uint32_t time)
-{
-       struct wlsc_output *output = data;
-
-       wlsc_output_finish_frame(output, time);
-}
-
 static int
 wayland_output_prepare_render(struct wlsc_output *output_base)
 {
@@ -180,20 +172,32 @@ wayland_output_prepare_render(struct wlsc_output *output_base)
        return 0;
 }
 
+static void
+frame_done(void *data, struct wl_callback *wl_callback, uint32_t time)
+{
+       struct wlsc_output *output = data;
+
+       wlsc_output_finish_frame(output, time);
+}
+
+static const struct wl_callback_listener frame_listener = {
+       frame_done
+};
+
 static int
 wayland_output_present(struct wlsc_output *output_base)
 {
        struct wayland_output *output = (struct wayland_output *) output_base;
        struct wayland_compositor *c =
                (struct wayland_compositor *) output->base.compositor;
+       struct wl_callback *callback;
 
        if (wayland_output_prepare_render(&output->base))
                return -1;
 
        eglSwapBuffers(c->base.display, output->egl_surface);
-       wl_display_frame_callback(c->parent.display,
-                                 output->parent.surface,
-                                 frame_callback, &output->base);
+       callback = wl_surface_frame(output->parent.surface);
+       wl_callback_add_listener(callback, &frame_listener, output);
 
        return 0;
 }
index bf31220..34bd366 100644 (file)
@@ -897,26 +897,31 @@ wlsc_output_repaint(struct wlsc_output *output)
                fade_output(output, ec->fade.spring.current, &total_damage);
 }
 
+struct wlsc_frame_callback {
+       struct wl_resource resource;
+       struct wl_client *client;
+       struct wl_list link;
+};
+
 static void
 repaint(void *data, int msecs)
 {
        struct wlsc_output *output = data;
        struct wlsc_compositor *compositor = output->compositor;
-       struct wlsc_surface *es;
        struct wlsc_animation *animation, *next;
+       struct wlsc_frame_callback *cb, *cnext;
 
        wlsc_output_repaint(output);
        output->repaint_needed = 0;
        output->repaint_scheduled = 1;
        output->present(output);
 
-       /* FIXME: Keep the surfaces in an per-output list. */
-       wl_list_for_each(es, &compositor->surface_list, link) {
-               if (es->output == output) {
-                       wl_display_post_frame(compositor->wl_display,
-                                             &es->surface, msecs);
-               }
+       wl_list_for_each_safe(cb, cnext, &output->frame_callback_list, link) {
+               wl_client_post_event(cb->client, &cb->resource.object, 
+                                    WL_CALLBACK_DONE, msecs);
+               wl_resource_destroy(&cb->resource, cb->client, 0);
        }
+       wl_list_init(&output->frame_callback_list);
 
        wl_list_for_each_safe(animation, next,
                              &compositor->animation_list, link)
@@ -1052,10 +1057,39 @@ surface_damage(struct wl_client *client,
        wlsc_surface_damage_rectangle(es, x, y, width, height);
 }
 
+static void
+destroy_frame_callback(struct wl_resource *resource, struct wl_client *client)
+{
+       free(resource);
+}
+
+static void
+surface_frame(struct wl_client *client,
+             struct wl_surface *surface, uint32_t callback)
+{
+       struct wlsc_frame_callback *cb;
+       struct wlsc_surface *es = (struct wlsc_surface *) surface;
+
+       cb = malloc(sizeof *cb);
+       if (cb == NULL) {
+               wl_client_post_no_memory(client);
+               return;
+       }
+               
+       cb->resource.object.interface = &wl_callback_interface;
+       cb->resource.object.id = callback;
+       cb->resource.destroy = destroy_frame_callback;
+       wl_list_insert(es->output->frame_callback_list.prev, &cb->link);
+       cb->client = client;
+
+       wl_client_add_resource(client, &cb->resource);
+}
+
 const static struct wl_surface_interface surface_interface = {
        surface_destroy,
        surface_attach,
-       surface_damage
+       surface_damage,
+       surface_frame
 };
 
 static void
@@ -1820,6 +1854,7 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
        output->scanout_buffer_destroy_listener.func =
                output_handle_scanout_buffer_destroy;
        wl_list_init(&output->scanout_buffer_destroy_listener.link);
+       wl_list_init(&output->frame_callback_list);
 
        output->object.interface = &wl_output_interface;
        wl_display_add_object(c->wl_display, &output->object);
index db23c43..5896463 100644 (file)
@@ -66,6 +66,7 @@ struct wlsc_output {
        struct wlsc_compositor *compositor;
        struct wlsc_surface *background;
        struct wlsc_matrix matrix;
+       struct wl_list frame_callback_list;
        int32_t x, y, mm_width, mm_height;
        pixman_region32_t region;
        pixman_region32_t previous_damage;