compositor, clients: apply wl_surface.frame on commit

Apply wl_surface.frame request only on the next wl_surface.commit
according to the new protocol.

This makes it explicit, which repaint actually triggered the frame
callback, since commit schedules a repaint. Otherwise, something causing
a repaint before a commit could trigger the frame callback too early.

Ensure all demo clients send commit after wl_surface.frame. Note, that
GL apps rely on eglSwapBuffers() sending commit. In toytoolkit, it is
assumed that window_flush() always does a commit.

compositor-wayland assumes renderer->repaint_output does a commit.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
dev
Pekka Paalanen 12 years ago committed by Kristian Høgsberg
parent 6c71ee1ba2
commit bc10638cd9
  1. 4
      clients/simple-egl.c
  2. 2
      clients/simple-shm.c
  3. 14
      clients/window.c
  4. 4
      src/compositor-wayland.c
  5. 15
      src/compositor.c
  6. 3
      src/compositor.h

@ -410,10 +410,10 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
wl_region_destroy(region); wl_region_destroy(region);
} }
eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
window->callback = wl_surface_frame(window->surface); window->callback = wl_surface_frame(window->surface);
wl_callback_add_listener(window->callback, &frame_listener, window); wl_callback_add_listener(window->callback, &frame_listener, window);
eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
} }
static const struct wl_callback_listener frame_listener = { static const struct wl_callback_listener frame_listener = {

@ -217,13 +217,13 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
paint_pixels(window->shm_data, 20, window->width, window->height, time); paint_pixels(window->shm_data, 20, window->width, window->height, time);
wl_surface_damage(window->surface, wl_surface_damage(window->surface,
20, 20, window->width - 40, window->height - 40); 20, 20, window->width - 40, window->height - 40);
wl_surface_commit(window->surface);
if (callback) if (callback)
wl_callback_destroy(callback); wl_callback_destroy(callback);
window->callback = wl_surface_frame(window->surface); window->callback = wl_surface_frame(window->surface);
wl_callback_add_listener(window->callback, &frame_listener, window); wl_callback_add_listener(window->callback, &frame_listener, window);
wl_surface_commit(window->surface);
} }
static const struct wl_callback_listener frame_listener = { static const struct wl_callback_listener frame_listener = {

@ -2670,16 +2670,16 @@ pointer_surface_frame_callback(void *data, struct wl_callback *callback,
else else
i = wl_cursor_frame(cursor, time - input->cursor_anim_start); i = wl_cursor_frame(cursor, time - input->cursor_anim_start);
input_set_pointer_image_index(input, i); if (cursor->image_count > 1) {
input->cursor_frame_cb =
if (cursor->image_count == 1) wl_surface_frame(input->pointer_surface);
return;
input->cursor_frame_cb = wl_surface_frame(input->pointer_surface);
wl_callback_add_listener(input->cursor_frame_cb, wl_callback_add_listener(input->cursor_frame_cb,
&pointer_surface_listener, input); &pointer_surface_listener, input);
} }
input_set_pointer_image_index(input, i);
}
static const struct wl_callback_listener pointer_surface_listener = { static const struct wl_callback_listener pointer_surface_listener = {
pointer_surface_frame_callback pointer_surface_frame_callback
}; };
@ -2973,12 +2973,12 @@ idle_redraw(struct task *task, uint32_t events)
window_create_surface(window); window_create_surface(window);
widget_redraw(window->widget); widget_redraw(window->widget);
window_flush(window);
window->redraw_needed = 0; window->redraw_needed = 0;
wl_list_init(&window->redraw_task.link); wl_list_init(&window->redraw_task.link);
window->frame_cb = wl_surface_frame(window->surface); window->frame_cb = wl_surface_frame(window->surface);
wl_callback_add_listener(window->frame_cb, &listener, window); wl_callback_add_listener(window->frame_cb, &listener, window);
window_flush(window);
} }
void void

@ -307,12 +307,10 @@ wayland_output_repaint(struct weston_output *output_base,
struct weston_compositor *ec = output->base.compositor; struct weston_compositor *ec = output->base.compositor;
struct wl_callback *callback; struct wl_callback *callback;
ec->renderer->repaint_output(&output->base, damage);
callback = wl_surface_frame(output->parent.surface); callback = wl_surface_frame(output->parent.surface);
wl_callback_add_listener(callback, &frame_listener, output); wl_callback_add_listener(callback, &frame_listener, output);
return; ec->renderer->repaint_output(&output->base, damage);
} }
static void static void

@ -266,6 +266,7 @@ weston_surface_create(struct weston_compositor *compositor)
pixman_region32_init(&surface->pending.damage); pixman_region32_init(&surface->pending.damage);
pixman_region32_init(&surface->pending.opaque); pixman_region32_init(&surface->pending.opaque);
region_init_infinite(&surface->pending.input); region_init_infinite(&surface->pending.input);
wl_list_init(&surface->pending.frame_callback_list);
return surface; return surface;
} }
@ -767,6 +768,10 @@ destroy_surface(struct wl_resource *resource)
if (weston_surface_is_mapped(surface)) if (weston_surface_is_mapped(surface))
weston_surface_unmap(surface); weston_surface_unmap(surface);
wl_list_for_each_safe(cb, next,
&surface->pending.frame_callback_list, link)
wl_resource_destroy(&cb->resource);
pixman_region32_fini(&surface->pending.input); pixman_region32_fini(&surface->pending.input);
pixman_region32_fini(&surface->pending.opaque); pixman_region32_fini(&surface->pending.opaque);
pixman_region32_fini(&surface->pending.damage); pixman_region32_fini(&surface->pending.damage);
@ -990,7 +995,6 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
wl_callback_send_done(&cb->resource, msecs); wl_callback_send_done(&cb->resource, msecs);
wl_resource_destroy(&cb->resource); wl_resource_destroy(&cb->resource);
} }
wl_list_init(&frame_callback_list);
wl_list_for_each_safe(animation, next, &output->animation_list, link) { wl_list_for_each_safe(animation, next, &output->animation_list, link) {
animation->frame_counter++; animation->frame_counter++;
@ -1170,7 +1174,7 @@ surface_frame(struct wl_client *client,
struct wl_resource *resource, uint32_t callback) struct wl_resource *resource, uint32_t callback)
{ {
struct weston_frame_callback *cb; struct weston_frame_callback *cb;
struct weston_surface *es = resource->data; struct weston_surface *surface = resource->data;
cb = malloc(sizeof *cb); cb = malloc(sizeof *cb);
if (cb == NULL) { if (cb == NULL) {
@ -1185,7 +1189,7 @@ surface_frame(struct wl_client *client,
cb->resource.data = cb; cb->resource.data = cb;
wl_client_add_resource(client, &cb->resource); wl_client_add_resource(client, &cb->resource);
wl_list_insert(es->frame_callback_list.prev, &cb->link); wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
} }
static void static void
@ -1258,6 +1262,11 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
pixman_region32_intersect(&surface->input, pixman_region32_intersect(&surface->input,
&surface->input, &surface->pending.input); &surface->input, &surface->pending.input);
/* wl_surface.frame */
wl_list_insert_list(&surface->frame_callback_list,
&surface->pending.frame_callback_list);
wl_list_init(&surface->pending.frame_callback_list);
weston_surface_schedule_repaint(surface); weston_surface_schedule_repaint(surface);
} }

@ -483,6 +483,9 @@ struct weston_surface {
/* wl_surface.set_input_region */ /* wl_surface.set_input_region */
pixman_region32_t input; pixman_region32_t input;
/* wl_surface.frame */
struct wl_list frame_callback_list;
} pending; } pending;
/* /*

Loading…
Cancel
Save