Use the new wl_callback interface
This commit is contained in:
+18
-20
@@ -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,14 +197,11 @@ create_surface(struct window *window)
|
|||||||
EGLBoolean ret;
|
EGLBoolean ret;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
|
if (!display->premultiplied_argb_visual)
|
||||||
|
wl_display_roundtrip(display->display);
|
||||||
if (!display->premultiplied_argb_visual) {
|
if (!display->premultiplied_argb_visual) {
|
||||||
wl_display_sync_callback(display->display, sync_callback, &done);
|
fprintf(stderr, "premultiplied argb visual missing\n");
|
||||||
while (!done)
|
exit(1);
|
||||||
wl_display_iterate(display->display, display->mask);
|
|
||||||
if (!display->premultiplied_argb_visual) {
|
|
||||||
fprintf(stderr, "premultiplied argb visual missing\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window->surface = wl_compositor_create_surface(display->compositor);
|
window->surface = wl_compositor_create_surface(display->compositor);
|
||||||
@@ -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);
|
||||||
|
|||||||
+14
-16
@@ -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);
|
||||||
|
|||||||
+1
-20
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-8
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user