Use the new wl_callback interface

dev
Kristian Høgsberg 13 years ago
parent 361d2ade02
commit 334182062f
  1. 34
      clients/simple-egl.c
  2. 30
      clients/simple-shm.c
  3. 21
      clients/window.c
  4. 26
      compositor/compositor-wayland.c
  5. 51
      compositor/compositor.c
  6. 1
      compositor/compositor.h

@ -189,14 +189,6 @@ init_gl(struct window *window)
glGetUniformLocation(window->gl.program, "rotation"); glGetUniformLocation(window->gl.program, "rotation");
} }
static void
sync_callback(void *data)
{
int *done = data;
*done = 1;
}
static void static void
create_surface(struct window *window) create_surface(struct window *window)
{ {
@ -205,15 +197,12 @@ create_surface(struct window *window)
EGLBoolean ret; EGLBoolean ret;
int done = 0; int done = 0;
if (!display->premultiplied_argb_visual) { if (!display->premultiplied_argb_visual)
wl_display_sync_callback(display->display, sync_callback, &done); wl_display_roundtrip(display->display);
while (!done)
wl_display_iterate(display->display, display->mask);
if (!display->premultiplied_argb_visual) { if (!display->premultiplied_argb_visual) {
fprintf(stderr, "premultiplied argb visual missing\n"); fprintf(stderr, "premultiplied argb visual missing\n");
exit(1); exit(1);
} }
}
window->surface = wl_compositor_create_surface(display->compositor); window->surface = wl_compositor_create_surface(display->compositor);
visual = display->premultiplied_argb_visual; visual = display->premultiplied_argb_visual;
@ -235,8 +224,10 @@ create_surface(struct window *window)
assert(ret == EGL_TRUE); assert(ret == EGL_TRUE);
} }
static const struct wl_callback_listener frame_listener;
static void 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; struct window *window = data;
static const GLfloat verts[3][2] = { static const GLfloat verts[3][2] = {
@ -287,11 +278,17 @@ redraw(struct wl_surface *surface, void *data, uint32_t time)
glFlush(); glFlush();
eglSwapBuffers(window->display->egl.dpy, window->egl_surface); eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
wl_display_frame_callback(window->display->display, if (callback)
window->surface, wl_callback_destroy(callback);
redraw, window);
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 static void
compositor_handle_visual(void *data, compositor_handle_visual(void *data,
struct wl_compositor *compositor, struct wl_compositor *compositor,
@ -356,12 +353,13 @@ main(int argc, char **argv)
display_handle_global, &display); display_handle_global, &display);
wl_display_get_fd(display.display, event_mask_update, &display); wl_display_get_fd(display.display, event_mask_update, &display);
wl_display_iterate(display.display, WL_DISPLAY_READABLE);
init_egl(&display); init_egl(&display);
create_surface(&window); create_surface(&window);
init_gl(&window); init_gl(&window);
redraw(window.surface, &window, 0); redraw(&window, NULL, 0);
while (true) while (true)
wl_display_iterate(display.display, display.mask); wl_display_iterate(display.display, display.mask);

@ -112,8 +112,10 @@ create_window(struct display *display, int width, int height)
return window; return window;
} }
static const struct wl_callback_listener frame_listener;
static void 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; struct window *window = data;
uint32_t *p; uint32_t *p;
@ -130,11 +132,17 @@ redraw(struct wl_surface *surface, void *data, uint32_t time)
wl_surface_damage(window->surface, wl_surface_damage(window->surface,
0, 0, window->width, window->height); 0, 0, window->width, window->height);
wl_display_frame_callback(window->display->display, if (callback)
window->surface, wl_callback_destroy(callback);
redraw, window);
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 static void
compositor_handle_visual(void *data, compositor_handle_visual(void *data,
struct wl_compositor *compositor, struct wl_compositor *compositor,
@ -180,19 +188,10 @@ event_mask_update(uint32_t mask, void *data)
return 0; return 0;
} }
static void
sync_callback(void *data)
{
int *done = data;
*done = 1;
}
static struct display * static struct display *
create_display(void) create_display(void)
{ {
struct display *display; struct display *display;
int done;
display = malloc(sizeof *display); display = malloc(sizeof *display);
display->display = wl_display_connect(NULL); 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_get_fd(display->display, event_mask_update, display);
wl_display_sync_callback(display->display, sync_callback, &done);
while (!display->xrgb_visual) while (!display->xrgb_visual)
wl_display_iterate(display->display, display->mask); wl_display_roundtrip(display->display);
return display; return display;
} }
@ -220,7 +218,7 @@ main(int argc, char **argv)
display = create_display(); display = create_display();
window = create_window(display, 250, 250); window = create_window(display, 250, 250);
redraw(window->surface, window, 0); redraw(window, NULL, 0);
while (true) while (true)
wl_display_iterate(display->display, display->mask); wl_display_iterate(display->display, display->mask);

@ -1887,25 +1887,6 @@ init_egl(struct display *d)
return 0; 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 * struct display *
display_create(int *argc, char **argv[], const GOptionEntry *option_entries, display_create(int *argc, char **argv[], const GOptionEntry *option_entries,
display_global_handler_t handler) 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"); d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
if (!d->premultiplied_argb_visual || !d->rgb_visual) { if (!d->premultiplied_argb_visual || !d->rgb_visual) {
force_roundtrip(d); wl_display_roundtrip(d->display);
if (!d->premultiplied_argb_visual || !d->rgb_visual) { if (!d->premultiplied_argb_visual || !d->rgb_visual) {
fprintf(stderr, "failed to retreive visuals\n"); fprintf(stderr, "failed to retreive visuals\n");
return NULL; return NULL;

@ -157,14 +157,6 @@ wayland_compositor_init_egl(struct wayland_compositor *c)
return 0; 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 static int
wayland_output_prepare_render(struct wlsc_output *output_base) wayland_output_prepare_render(struct wlsc_output *output_base)
{ {
@ -180,20 +172,32 @@ wayland_output_prepare_render(struct wlsc_output *output_base)
return 0; 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 static int
wayland_output_present(struct wlsc_output *output_base) wayland_output_present(struct wlsc_output *output_base)
{ {
struct wayland_output *output = (struct wayland_output *) output_base; struct wayland_output *output = (struct wayland_output *) output_base;
struct wayland_compositor *c = struct wayland_compositor *c =
(struct wayland_compositor *) output->base.compositor; (struct wayland_compositor *) output->base.compositor;
struct wl_callback *callback;
if (wayland_output_prepare_render(&output->base)) if (wayland_output_prepare_render(&output->base))
return -1; return -1;
eglSwapBuffers(c->base.display, output->egl_surface); eglSwapBuffers(c->base.display, output->egl_surface);
wl_display_frame_callback(c->parent.display, callback = wl_surface_frame(output->parent.surface);
output->parent.surface, wl_callback_add_listener(callback, &frame_listener, output);
frame_callback, &output->base);
return 0; return 0;
} }

@ -897,26 +897,31 @@ wlsc_output_repaint(struct wlsc_output *output)
fade_output(output, ec->fade.spring.current, &total_damage); 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 static void
repaint(void *data, int msecs) repaint(void *data, int msecs)
{ {
struct wlsc_output *output = data; struct wlsc_output *output = data;
struct wlsc_compositor *compositor = output->compositor; struct wlsc_compositor *compositor = output->compositor;
struct wlsc_surface *es;
struct wlsc_animation *animation, *next; struct wlsc_animation *animation, *next;
struct wlsc_frame_callback *cb, *cnext;
wlsc_output_repaint(output); wlsc_output_repaint(output);
output->repaint_needed = 0; output->repaint_needed = 0;
output->repaint_scheduled = 1; output->repaint_scheduled = 1;
output->present(output); output->present(output);
/* FIXME: Keep the surfaces in an per-output list. */ wl_list_for_each_safe(cb, cnext, &output->frame_callback_list, link) {
wl_list_for_each(es, &compositor->surface_list, link) { wl_client_post_event(cb->client, &cb->resource.object,
if (es->output == output) { WL_CALLBACK_DONE, msecs);
wl_display_post_frame(compositor->wl_display, wl_resource_destroy(&cb->resource, cb->client, 0);
&es->surface, msecs);
}
} }
wl_list_init(&output->frame_callback_list);
wl_list_for_each_safe(animation, next, wl_list_for_each_safe(animation, next,
&compositor->animation_list, link) &compositor->animation_list, link)
@ -1052,10 +1057,39 @@ surface_damage(struct wl_client *client,
wlsc_surface_damage_rectangle(es, x, y, width, height); 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 = { const static struct wl_surface_interface surface_interface = {
surface_destroy, surface_destroy,
surface_attach, surface_attach,
surface_damage surface_damage,
surface_frame
}; };
static void static void
@ -1820,6 +1854,7 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
output->scanout_buffer_destroy_listener.func = output->scanout_buffer_destroy_listener.func =
output_handle_scanout_buffer_destroy; output_handle_scanout_buffer_destroy;
wl_list_init(&output->scanout_buffer_destroy_listener.link); wl_list_init(&output->scanout_buffer_destroy_listener.link);
wl_list_init(&output->frame_callback_list);
output->object.interface = &wl_output_interface; output->object.interface = &wl_output_interface;
wl_display_add_object(c->wl_display, &output->object); wl_display_add_object(c->wl_display, &output->object);

@ -66,6 +66,7 @@ struct wlsc_output {
struct wlsc_compositor *compositor; struct wlsc_compositor *compositor;
struct wlsc_surface *background; struct wlsc_surface *background;
struct wlsc_matrix matrix; struct wlsc_matrix matrix;
struct wl_list frame_callback_list;
int32_t x, y, mm_width, mm_height; int32_t x, y, mm_width, mm_height;
pixman_region32_t region; pixman_region32_t region;
pixman_region32_t previous_damage; pixman_region32_t previous_damage;

Loading…
Cancel
Save