Merge remote-tracking branch 'bnf/surface-frame-event'

Conflicts:
	compositor/compositor.c
dev
Kristian Høgsberg 14 years ago
commit 11e2828bdc
  1. 4
      clients/gears.c
  2. 7
      clients/resizor.c
  3. 9
      clients/simple-client.c
  4. 4
      clients/smoke.c
  5. 6
      clients/window.c
  6. 3
      clients/window.h
  7. 25
      compositor/compositor-drm.c
  8. 26
      compositor/compositor-wayland.c
  9. 20
      compositor/compositor-x11.c
  10. 90
      compositor/compositor.c
  11. 11
      compositor/compositor.h
  12. 1
      compositor/shell.c

@ -295,7 +295,7 @@ redraw_handler(struct window *window, void *data)
} }
static void static void
frame_callback(void *data, uint32_t time) frame_callback(struct wl_surface *surface, void *data, uint32_t time)
{ {
struct gears *gears = data; struct gears *gears = data;
@ -303,6 +303,7 @@ frame_callback(void *data, uint32_t time)
window_schedule_redraw(gears->window); window_schedule_redraw(gears->window);
wl_display_frame_callback(display_get_display(gears->d), wl_display_frame_callback(display_get_display(gears->d),
window_get_wl_surface(gears->window),
frame_callback, gears); frame_callback, gears);
} }
@ -363,6 +364,7 @@ gears_create(struct display *display)
draw_gears(gears); draw_gears(gears);
wl_display_frame_callback(display_get_display(gears->d), wl_display_frame_callback(display_get_display(gears->d),
window_get_wl_surface(gears->window),
frame_callback, gears); frame_callback, gears);
return gears; return gears;

@ -49,7 +49,7 @@ struct resizor {
}; };
static void static void
frame_callback(void *data, uint32_t time) frame_callback(struct wl_surface *surface, void *data, uint32_t time)
{ {
struct resizor *resizor = data; struct resizor *resizor = data;
double force, height; double force, height;
@ -107,6 +107,7 @@ resizor_draw(struct resizor *resizor)
if (fabs(resizor->height.previous - resizor->height.target) > 0.1) { if (fabs(resizor->height.previous - resizor->height.target) > 0.1) {
wl_display_frame_callback(display_get_display(resizor->display), wl_display_frame_callback(display_get_display(resizor->display),
window_get_wl_surface(resizor->window),
frame_callback, resizor); frame_callback, resizor);
} }
} }
@ -140,11 +141,11 @@ key_handler(struct window *window, struct input *input, uint32_t time,
switch (sym) { switch (sym) {
case XK_Down: case XK_Down:
resizor->height.target = 400; resizor->height.target = 400;
frame_callback(resizor, 0); frame_callback(window_get_wl_surface(window), resizor, 0);
break; break;
case XK_Up: case XK_Up:
resizor->height.target = 200; resizor->height.target = 200;
frame_callback(resizor, 0); frame_callback(window_get_wl_surface(window), resizor, 0);
break; break;
} }
} }

@ -217,7 +217,7 @@ create_surface(struct window *window)
} }
static void static void
redraw(void *data, uint32_t time) redraw(struct wl_surface *surface, void *data, uint32_t time)
{ {
struct window *window = data; struct window *window = data;
static const GLfloat verts[3][2] = { static const GLfloat verts[3][2] = {
@ -268,7 +268,9 @@ redraw(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, redraw, window); wl_display_frame_callback(window->display->display,
window->surface,
redraw, window);
} }
static void static void
@ -316,7 +318,8 @@ main(int argc, char **argv)
create_surface(&window); create_surface(&window);
init_gl(&window); init_gl(&window);
wl_display_frame_callback(display.display, redraw, &window); wl_display_frame_callback(display.display, window.surface,
redraw, &window);
wl_display_get_fd(display.display, event_mask_update, &display); wl_display_get_fd(display.display, event_mask_update, &display);
while (true) while (true)

@ -173,7 +173,7 @@ static void render(struct smoke *smoke)
} }
static void static void
frame_callback(void *data, uint32_t time) frame_callback(struct wl_surface *surface, void *data, uint32_t time)
{ {
struct smoke *smoke = data; struct smoke *smoke = data;
@ -201,6 +201,7 @@ frame_callback(void *data, uint32_t time)
window_damage(smoke->window, 0, 0, smoke->width, smoke->height); window_damage(smoke->window, 0, 0, smoke->width, smoke->height);
wl_display_frame_callback(display_get_display(smoke->display), wl_display_frame_callback(display_get_display(smoke->display),
window_get_wl_surface(smoke->window),
frame_callback, smoke); frame_callback, smoke);
} }
@ -288,6 +289,7 @@ int main(int argc, char *argv[])
window_set_user_data(smoke.window, &smoke); window_set_user_data(smoke.window, &smoke);
wl_display_frame_callback(display_get_display(d), wl_display_frame_callback(display_get_display(d),
window_get_wl_surface(smoke.window),
frame_callback, &smoke); frame_callback, &smoke);
display_run(d); display_run(d);

@ -913,6 +913,12 @@ window_get_surface(struct window *window)
return cairo_surface_reference(window->cairo_surface); return cairo_surface_reference(window->cairo_surface);
} }
struct wl_surface *
window_get_wl_surface(struct window *window)
{
return window->surface;
}
static int static int
get_pointer_location(struct window *window, int32_t x, int32_t y) get_pointer_location(struct window *window, int32_t x, int32_t y)
{ {

@ -175,6 +175,9 @@ window_damage(struct window *window, int32_t x, int32_t y,
cairo_surface_t * cairo_surface_t *
window_get_surface(struct window *window); window_get_surface(struct window *window);
struct wl_surface *
window_get_wl_surface(struct window *window);
void void
window_flush(struct window *window); window_flush(struct window *window);

@ -79,15 +79,15 @@ drm_output_prepare_render(struct wlsc_output *output_base)
return 0; return 0;
} }
static void static int
drm_compositor_present(struct wlsc_compositor *ec) drm_output_present(struct wlsc_output *output_base)
{ {
struct drm_compositor *c = (struct drm_compositor *) ec; struct drm_output *output = (struct drm_output *) output_base;
struct drm_output *output; struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor;
wl_list_for_each(output, &ec->output_list, base.link) {
if (drm_output_prepare_render(&output->base)) if (drm_output_prepare_render(&output->base))
continue; return -1;
glFlush(); glFlush();
output->current ^= 1; output->current ^= 1;
@ -95,7 +95,8 @@ drm_compositor_present(struct wlsc_compositor *ec)
drmModePageFlip(c->drm.fd, output->crtc_id, drmModePageFlip(c->drm.fd, output->crtc_id,
output->fb_id[output->current ^ 1], output->fb_id[output->current ^ 1],
DRM_MODE_PAGE_FLIP_EVENT, output); DRM_MODE_PAGE_FLIP_EVENT, output);
}
return 0;
} }
static void static void
@ -103,16 +104,10 @@ page_flip_handler(int fd, unsigned int frame,
unsigned int sec, unsigned int usec, void *data) unsigned int sec, unsigned int usec, void *data)
{ {
struct wlsc_output *output = data; struct wlsc_output *output = data;
struct wlsc_compositor *compositor = output->compositor;
uint32_t msecs; uint32_t msecs;
/* run synchronized to first output, ignore other pflip events.
* FIXME: support per output/surface frame callbacks */
if (output == container_of(compositor->output_list.prev,
struct wlsc_output, link)) {
msecs = sec * 1000 + usec / 1000; msecs = sec * 1000 + usec / 1000;
wlsc_compositor_finish_frame(compositor, msecs); wlsc_output_finish_frame(output, msecs);
}
} }
static void static void
@ -287,6 +282,7 @@ create_output_for_connector(struct drm_compositor *ec,
} }
output->base.prepare_render = drm_output_prepare_render; output->base.prepare_render = drm_output_prepare_render;
output->base.present = drm_output_present;
wl_list_insert(ec->base.output_list.prev, &output->base.link); wl_list_insert(ec->base.output_list.prev, &output->base.link);
@ -523,7 +519,6 @@ drm_compositor_create(struct wl_display *display, int connector)
} }
ec->base.destroy = drm_destroy; ec->base.destroy = drm_destroy;
ec->base.present = drm_compositor_present;
ec->base.create_buffer = wlsc_shm_buffer_create; ec->base.create_buffer = wlsc_shm_buffer_create;
ec->base.focus = 1; ec->base.focus = 1;

@ -156,11 +156,11 @@ wayland_compositor_init_egl(struct wayland_compositor *c)
} }
static void static void
frame_callback(void *data, uint32_t time) frame_callback(struct wl_surface *surface, void *data, uint32_t time)
{ {
struct wayland_compositor *c = (struct wayland_compositor *) data; struct wlsc_output *output = data;
wlsc_compositor_finish_frame(&c->base, time); wlsc_output_finish_frame(output, time);
} }
static int static int
@ -178,20 +178,22 @@ wayland_output_prepare_render(struct wlsc_output *output_base)
return 0; return 0;
} }
static void static int
wayland_compositor_present(struct wlsc_compositor *base) wayland_output_present(struct wlsc_output *output_base)
{ {
struct wayland_compositor *c = (struct wayland_compositor *) base; struct wayland_output *output = (struct wayland_output *) output_base;
struct wayland_output *output; struct wayland_compositor *c =
(struct wayland_compositor *) output->base.compositor;
wl_list_for_each(output, &base->output_list, base.link) {
if (wayland_output_prepare_render(&output->base)) if (wayland_output_prepare_render(&output->base))
continue; return -1;
eglSwapBuffers(c->base.display, output->egl_surface); eglSwapBuffers(c->base.display, output->egl_surface);
} wl_display_frame_callback(c->parent.display,
output->parent.surface,
frame_callback, &output->base);
wl_display_frame_callback(c->parent.display, frame_callback, c); return 0;
} }
static int static int
@ -243,6 +245,7 @@ wayland_compositor_create_output(struct wayland_compositor *c,
glClearColor(0, 0, 0, 0.5); glClearColor(0, 0, 0, 0.5);
output->base.prepare_render = wayland_output_prepare_render; output->base.prepare_render = wayland_output_prepare_render;
output->base.present = wayland_output_present;
wl_list_insert(c->base.output_list.prev, &output->base.link); wl_list_insert(c->base.output_list.prev, &output->base.link);
@ -477,7 +480,6 @@ wayland_compositor_create(struct wl_display *display, int width, int height)
return NULL; return NULL;
c->base.destroy = wayland_destroy; c->base.destroy = wayland_destroy;
c->base.present = wayland_compositor_present;
c->base.create_buffer = wlsc_shm_buffer_create; c->base.create_buffer = wlsc_shm_buffer_create;
/* Can't init base class until we have a current egl context */ /* Can't init base class until we have a current egl context */

@ -171,24 +171,24 @@ x11_output_prepare_render(struct wlsc_output *output_base)
return 0; return 0;
} }
static void static int
x11_compositor_present(struct wlsc_compositor *base) x11_output_present(struct wlsc_output *output_base)
{ {
struct x11_compositor *c = (struct x11_compositor *) base; struct x11_output *output = (struct x11_output *) output_base;
struct x11_output *output; struct wlsc_compositor *ec = output->base.compositor;
struct timeval tv; struct timeval tv;
uint32_t msec; uint32_t msec;
wl_list_for_each(output, &c->base.output_list, base.link) {
if (x11_output_prepare_render(&output->base)) if (x11_output_prepare_render(&output->base))
continue; return -1;
eglSwapBuffers(c->base.display, output->egl_surface); eglSwapBuffers(ec->display, output->egl_surface);
}
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
wlsc_compositor_finish_frame(&c->base, msec); wlsc_output_finish_frame(&output->base, msec);
return 0;
} }
static void static void
@ -338,6 +338,7 @@ x11_compositor_create_output(struct x11_compositor *c, int width, int height)
} }
output->base.prepare_render = x11_output_prepare_render; output->base.prepare_render = x11_output_prepare_render;
output->base.present = x11_output_present;
wl_list_insert(c->base.output_list.prev, &output->base.link); wl_list_insert(c->base.output_list.prev, &output->base.link);
@ -573,7 +574,6 @@ x11_compositor_create(struct wl_display *display, int width, int height)
return NULL; return NULL;
c->base.destroy = x11_destroy; c->base.destroy = x11_destroy;
c->base.present = x11_compositor_present;
c->base.create_buffer = wlsc_shm_buffer_create; c->base.create_buffer = wlsc_shm_buffer_create;
/* Can't init base class until we have a current egl context */ /* Can't init base class until we have a current egl context */

@ -479,9 +479,20 @@ wlsc_surface_update_matrix(struct wlsc_surface *es)
} }
void void
wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs) wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
{ {
wl_display_post_frame(compositor->wl_display, msecs); struct wlsc_compositor *compositor = output->compositor;
struct wlsc_surface *es;
wl_list_for_each(es, &compositor->surface_list, link) {
if (es->output == output) {
wl_display_post_frame(compositor->wl_display,
&es->surface, msecs);
}
}
output->finished = 1;
wl_event_source_timer_update(compositor->timer_source, 5); wl_event_source_timer_update(compositor->timer_source, 5);
compositor->repaint_on_timeout = 1; compositor->repaint_on_timeout = 1;
} }
@ -569,23 +580,37 @@ repaint(void *data)
{ {
struct wlsc_compositor *ec = data; struct wlsc_compositor *ec = data;
struct wlsc_output *output; struct wlsc_output *output;
int repainted_all_outputs = 1;
if (!ec->repaint_needed) { wl_list_for_each(output, &ec->output_list, link) {
ec->repaint_on_timeout = 0; if (!output->repaint_needed)
return; continue;
if (!output->finished) {
repainted_all_outputs = 0;
continue;
} }
wl_list_for_each(output, &ec->output_list, link)
wlsc_output_repaint(output); wlsc_output_repaint(output);
output->finished = 0;
output->repaint_needed = 0;
output->present(output);
}
ec->repaint_needed = 0; if (repainted_all_outputs)
ec->present(ec); ec->repaint_on_timeout = 0;
else
wl_event_source_timer_update(ec->timer_source, 1);
} }
void void
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor) wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
{ {
compositor->repaint_needed = 1; struct wlsc_output *output;
wl_list_for_each(output, &compositor->output_list, link)
output->repaint_needed = 1;
if (compositor->repaint_on_timeout) if (compositor->repaint_on_timeout)
return; return;
@ -600,6 +625,32 @@ surface_destroy(struct wl_client *client,
wl_resource_destroy(&surface->resource, client); wl_resource_destroy(&surface->resource, client);
} }
void
wlsc_surface_assign_output(struct wlsc_surface *es)
{
struct wlsc_compositor *ec = es->compositor;
struct wlsc_output *output;
struct wlsc_output *tmp = es->output;
es->output = NULL;
wl_list_for_each(output, &ec->output_list, link) {
if (output->x < es->x && es->x < output->x + output->width &&
output->y < es->y && es->y < output->y + output->height) {
if (output != tmp)
printf("assiging surface %p to output %p\n",
es, output);
es->output = output;
}
}
if (es->output == NULL) {
printf("no output found\n");
es->output = container_of(ec->output_list.next,
struct wlsc_output, link);
}
}
static void static void
surface_attach(struct wl_client *client, surface_attach(struct wl_client *client,
struct wl_surface *surface, struct wl_buffer *buffer, struct wl_surface *surface, struct wl_buffer *buffer,
@ -620,6 +671,8 @@ surface_attach(struct wl_client *client,
es->y += y; es->y += y;
es->width = buffer->width; es->width = buffer->width;
es->height = buffer->height; es->height = buffer->height;
if (x != 0 || y != 0)
wlsc_surface_assign_output(es);
wlsc_surface_update_matrix(es); wlsc_surface_update_matrix(es);
} }
@ -628,12 +681,16 @@ surface_map_toplevel(struct wl_client *client,
struct wl_surface *surface) struct wl_surface *surface)
{ {
struct wlsc_surface *es = (struct wlsc_surface *) surface; struct wlsc_surface *es = (struct wlsc_surface *) surface;
struct wlsc_compositor *ec = es->compositor;
switch (es->map_type) { switch (es->map_type) {
case WLSC_SURFACE_MAP_UNMAPPED: case WLSC_SURFACE_MAP_UNMAPPED:
es->x = 10 + random() % 400; es->x = 10 + random() % 400;
es->y = 10 + random() % 400; es->y = 10 + random() % 400;
wlsc_surface_update_matrix(es); wlsc_surface_update_matrix(es);
/* assign to first output */
es->output = container_of(ec->output_list.next,
struct wlsc_output, link);
wl_list_insert(&es->compositor->surface_list, &es->link); wl_list_insert(&es->compositor->surface_list, &es->link);
break; break;
case WLSC_SURFACE_MAP_TOPLEVEL: case WLSC_SURFACE_MAP_TOPLEVEL:
@ -663,6 +720,8 @@ surface_map_transient(struct wl_client *client,
switch (es->map_type) { switch (es->map_type) {
case WLSC_SURFACE_MAP_UNMAPPED: case WLSC_SURFACE_MAP_UNMAPPED:
wl_list_insert(&es->compositor->surface_list, &es->link); wl_list_insert(&es->compositor->surface_list, &es->link);
/* assign to parents output */
es->output = pes->output;
break; break;
case WLSC_SURFACE_MAP_FULLSCREEN: case WLSC_SURFACE_MAP_FULLSCREEN:
es->fullscreen_output = NULL; es->fullscreen_output = NULL;
@ -685,10 +744,17 @@ surface_map_fullscreen(struct wl_client *client, struct wl_surface *surface)
struct wlsc_surface *es = (struct wlsc_surface *) surface; struct wlsc_surface *es = (struct wlsc_surface *) surface;
struct wlsc_output *output; struct wlsc_output *output;
/* FIXME: Fullscreen on first output */
/* FIXME: Handle output going away */
output = container_of(es->compositor->output_list.next,
struct wlsc_output, link);
switch (es->map_type) { switch (es->map_type) {
case WLSC_SURFACE_MAP_UNMAPPED: case WLSC_SURFACE_MAP_UNMAPPED:
es->x = 10 + random() % 400; es->x = 10 + random() % 400;
es->y = 10 + random() % 400; es->y = 10 + random() % 400;
/* assign to first output */
es->output = output;
wl_list_insert(&es->compositor->surface_list, &es->link); wl_list_insert(&es->compositor->surface_list, &es->link);
break; break;
case WLSC_SURFACE_MAP_FULLSCREEN: case WLSC_SURFACE_MAP_FULLSCREEN:
@ -697,11 +763,6 @@ surface_map_fullscreen(struct wl_client *client, struct wl_surface *surface)
break; break;
} }
/* FIXME: Fullscreen on first output */
/* FIXME: Handle output going away */
output = container_of(es->compositor->output_list.next,
struct wlsc_output, link);
es->saved_x = es->x; es->saved_x = es->x;
es->saved_y = es->y; es->saved_y = es->y;
es->x = (output->width - es->width) / 2; es->x = (output->width - es->width) / 2;
@ -1441,6 +1502,7 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
background_create(output, option_background); background_create(output, option_background);
output->flags = flags; output->flags = flags;
output->finished = 1;
wlsc_output_move(output, x, y); wlsc_output_move(output, x, y);
output->object.interface = &wl_output_interface; output->object.interface = &wl_output_interface;

@ -48,8 +48,11 @@ struct wlsc_output {
int32_t x, y, width, height; int32_t x, y, width, height;
pixman_region32_t previous_damage_region; pixman_region32_t previous_damage_region;
uint32_t flags; uint32_t flags;
int repaint_needed;
int finished;
int (*prepare_render)(struct wlsc_output *output); int (*prepare_render)(struct wlsc_output *output);
int (*present)(struct wlsc_output *output);
}; };
enum wlsc_pointer_type { enum wlsc_pointer_type {
@ -104,7 +107,6 @@ struct wlsc_compositor {
/* Repaint state. */ /* Repaint state. */
struct wl_event_source *timer_source; struct wl_event_source *timer_source;
int repaint_needed;
int repaint_on_timeout; int repaint_on_timeout;
struct timespec previous_swap; struct timespec previous_swap;
pixman_region32_t damage_region; pixman_region32_t damage_region;
@ -115,7 +117,6 @@ struct wlsc_compositor {
void (*destroy)(struct wlsc_compositor *ec); void (*destroy)(struct wlsc_compositor *ec);
int (*authenticate)(struct wlsc_compositor *c, uint32_t id); int (*authenticate)(struct wlsc_compositor *c, uint32_t id);
void (*present)(struct wlsc_compositor *c);
struct wl_buffer *(*create_buffer)(struct wlsc_compositor *c, struct wl_buffer *(*create_buffer)(struct wlsc_compositor *c,
int32_t width, int32_t height, int32_t width, int32_t height,
int32_t stride, struct wl_visual *visual, int32_t stride, struct wl_visual *visual,
@ -152,6 +153,7 @@ struct wlsc_surface {
struct wlsc_matrix matrix_inv; struct wlsc_matrix matrix_inv;
struct wl_visual *visual; struct wl_visual *visual;
struct wl_buffer *buffer; struct wl_buffer *buffer;
struct wlsc_output *output;
enum wlsc_surface_map_type map_type; enum wlsc_surface_map_type map_type;
struct wlsc_output *fullscreen_output; struct wlsc_output *fullscreen_output;
}; };
@ -181,7 +183,7 @@ notify_keyboard_focus(struct wl_input_device *device,
struct wl_array *keys); struct wl_array *keys);
void void
wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs); wlsc_output_finish_frame(struct wlsc_output *output, int msecs);
void void
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor); wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor);
@ -197,6 +199,9 @@ void
wlsc_binding_destroy(struct wlsc_binding *binding); wlsc_binding_destroy(struct wlsc_binding *binding);
void
wlsc_surface_assign_output(struct wlsc_surface *surface);
void void
wlsc_surface_damage(struct wlsc_surface *surface); wlsc_surface_damage(struct wlsc_surface *surface);

@ -43,6 +43,7 @@ move_grab_motion(struct wl_grab *grab,
wlsc_surface_damage(es); wlsc_surface_damage(es);
es->x = x + move->dx; es->x = x + move->dx;
es->y = y + move->dy; es->y = y + move->dy;
wlsc_surface_assign_output(es);
wlsc_surface_update_matrix(es); wlsc_surface_update_matrix(es);
wlsc_surface_damage(es); wlsc_surface_damage(es);
} }

Loading…
Cancel
Save