diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-02-29 12:42:35 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-02-29 12:52:33 -0500 |
commit | ad1eebaa044f631038fe42affe46c5aad774bd12 (patch) | |
tree | 9c52dbf664734655086537f911c18095480e2d20 | |
parent | 0eec5aab0c8d5a191e15194a42cd69be66fb5d2c (diff) |
compositor: Organize surface stack using new struct weston_layerlayers
The surface data structure is now a list of list of surfaces. The core
compositor defines the fade and cursor layer, and it's up to the shell to
provide more layers for the various surface types it implements.
-rw-r--r-- | src/compositor.c | 66 | ||||
-rw-r--r-- | src/compositor.h | 16 | ||||
-rw-r--r-- | src/shell.c | 141 |
3 files changed, 89 insertions, 134 deletions
diff --git a/src/compositor.c b/src/compositor.c index 38f7e742..861f84b7 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -600,6 +600,7 @@ weston_surface_unmap(struct weston_surface *surface) weston_surface_damage_below(surface); surface->output = NULL; wl_list_remove(&surface->link); + wl_list_remove(&surface->layer_link); weston_compositor_repick(surface->compositor); weston_compositor_schedule_repaint(surface->compositor); } @@ -808,37 +809,15 @@ out: pixman_region32_fini(&repaint); } -WL_EXPORT struct wl_list * -weston_compositor_top(struct weston_compositor *compositor) -{ - struct weston_input_device *input_device; - struct wl_list *list; - - input_device = (struct weston_input_device *) compositor->input_device; - - /* Insert below pointer */ - list = &compositor->surface_list; - if (compositor->fade.surface && - list->next == &compositor->fade.surface->link) - list = list->next; - if (list->next == &input_device->sprite->link) - list = list->next; - if (input_device->drag_surface && - list->next == &input_device->drag_surface->link) - list = list->next; - - return list; -} - -static void -weston_surface_raise(struct weston_surface *surface) +WL_EXPORT void +weston_surface_restack(struct weston_surface *surface, struct wl_list *below) { struct weston_compositor *compositor = surface->compositor; - struct wl_list *list = weston_compositor_top(compositor); - wl_list_remove(&surface->link); - wl_list_insert(list, &surface->link); + wl_list_remove(&surface->layer_link); + wl_list_insert(below, &surface->layer_link); weston_compositor_repick(compositor); + weston_surface_damage_below(surface); weston_surface_damage(surface); } @@ -912,6 +891,7 @@ weston_output_repaint(struct weston_output *output, int msecs) { struct weston_compositor *ec = output->compositor; struct weston_surface *es; + struct weston_layer *layer; struct weston_animation *animation, *next; struct weston_frame_callback *cb, *cnext; pixman_region32_t opaque, new_damage, output_damage; @@ -925,10 +905,14 @@ weston_output_repaint(struct weston_output *output, int msecs) output->border.top + output->border.bottom; glViewport(0, 0, width, height); - wl_list_for_each(es, &ec->surface_list, link) - /* Update surface transform now to avoid calling it ever - * again from the repaint sub-functions. */ - weston_surface_update_transform(es); + /* Rebuild the surface list and update surface transforms up front. */ + wl_list_init(&ec->surface_list); + wl_list_for_each(layer, &ec->layer_list, link) { + wl_list_for_each(es, &layer->surface_list, layer_link) { + weston_surface_update_transform(es); + wl_list_insert(ec->surface_list.prev, &es->link); + } + } if (output->assign_planes) /* @@ -1003,6 +987,13 @@ weston_output_finish_frame(struct weston_output *output, int msecs) } WL_EXPORT void +weston_layer_init(struct weston_layer *layer, struct wl_list *below) +{ + wl_list_init(&layer->surface_list); + wl_list_insert(below, &layer->link); +} + +WL_EXPORT void weston_compositor_schedule_repaint(struct weston_compositor *compositor) { struct weston_output *output; @@ -1041,7 +1032,8 @@ weston_compositor_fade(struct weston_compositor *compositor, float tint) surface = weston_surface_create(compositor); weston_surface_configure(surface, 0, 0, 8192, 8192); weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0); - wl_list_insert(&compositor->surface_list, &surface->link); + wl_list_insert(&compositor->fade_layer.surface_list, + &surface->layer_link); weston_surface_assign_output(surface); compositor->fade.surface = surface; pixman_region32_init(&surface->input); @@ -1478,7 +1470,6 @@ WL_EXPORT void weston_surface_activate(struct weston_surface *surface, struct weston_input_device *device, uint32_t time) { - weston_surface_raise(surface); wl_input_device_set_keyboard_focus(&device->input_device, &surface->surface, time); wl_data_device_set_keyboard_focus(&device->input_device); @@ -1803,13 +1794,14 @@ input_device_attach(struct wl_client *client, if (!buffer_resource && device->sprite->output) { wl_list_remove(&device->sprite->link); + wl_list_remove(&device->sprite->layer_link); device->sprite->output = NULL; return; } if (!device->sprite->output) { - wl_list_insert(&compositor->surface_list, - &device->sprite->link); + wl_list_insert(&compositor->cursor_layer.surface_list, + &device->sprite->layer_link); weston_surface_assign_output(device->sprite); } @@ -2259,6 +2251,7 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display) ec->bind_display(ec->display, ec->wl_display); wl_list_init(&ec->surface_list); + wl_list_init(&ec->layer_list); wl_list_init(&ec->input_device_list); wl_list_init(&ec->output_list); wl_list_init(&ec->binding_list); @@ -2267,6 +2260,9 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display) ec->fade.animation.frame = fade_frame; wl_list_init(&ec->fade.animation.link); + weston_layer_init(&ec->fade_layer, &ec->layer_list); + weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link); + ec->screenshooter = screenshooter_create(ec); wl_data_device_manager_init(ec->wl_display); diff --git a/src/compositor.h b/src/compositor.h index ad43bd6f..5f0faa45 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -150,6 +150,11 @@ enum { struct screenshooter; +struct weston_layer { + struct wl_list surface_list; + struct wl_list link; +}; + struct weston_compositor { struct wl_shm *shm; struct weston_xserver *wxs; @@ -168,8 +173,12 @@ struct weston_compositor { /* There can be more than one, but not right now... */ struct wl_input_device *input_device; + struct weston_layer fade_layer; + struct weston_layer cursor_layer; + struct wl_list output_list; struct wl_list input_device_list; + struct wl_list layer_list; struct wl_list surface_list; struct wl_list binding_list; struct wl_list animation_list; @@ -254,6 +263,7 @@ struct weston_surface { pixman_region32_t input; int32_t pitch; struct wl_list link; + struct wl_list layer_link; struct wl_list buffer_link; struct weston_shader *shader; GLfloat color[4]; @@ -359,6 +369,9 @@ notify_touch(struct wl_input_device *device, uint32_t time, int touch_id, int x, int y, int touch_type); void +weston_layer_init(struct weston_layer *layer, struct wl_list *below); + +void weston_output_finish_frame(struct weston_output *output, int msecs); void weston_output_damage(struct weston_output *output); @@ -411,6 +424,9 @@ weston_surface_configure(struct weston_surface *surface, GLfloat x, GLfloat y, int width, int height); void +weston_surface_restack(struct weston_surface *surface, struct wl_list *below); + +void weston_surface_set_position(struct weston_surface *surface, GLfloat x, GLfloat y); diff --git a/src/shell.c b/src/shell.c index a28302b0..16bd0270 100644 --- a/src/shell.c +++ b/src/shell.c @@ -42,6 +42,11 @@ struct wl_shell { struct weston_compositor *compositor; struct weston_shell shell; + struct weston_layer fullscreen_layer; + struct weston_layer panel_layer; + struct weston_layer toplevel_layer; + struct weston_layer background_layer; + struct { struct weston_process process; struct wl_client *client; @@ -56,7 +61,6 @@ struct wl_shell { struct shell_surface *lock_surface; struct wl_listener lock_surface_listener; - struct wl_list hidden_surface_list; struct wl_list backgrounds; struct wl_list panels; @@ -772,12 +776,12 @@ show_screensaver(struct wl_shell *shell, struct shell_surface *surface) struct wl_list *list; if (shell->lock_surface) - list = &shell->lock_surface->surface->link; + list = &shell->lock_surface->surface->layer_link; else - list = &shell->compositor->surface_list; + list = &shell->toplevel_layer.surface_list; - wl_list_remove(&surface->surface->link); - wl_list_insert(list, &surface->surface->link); + wl_list_remove(&surface->surface->layer_link); + wl_list_insert(list, &surface->surface->layer_link); surface->surface->output = surface->output; weston_surface_damage(surface->surface); } @@ -905,8 +909,6 @@ desktop_shell_set_lock_surface(struct wl_client *client, static void resume_desktop(struct wl_shell *shell) { - struct weston_surface *surface; - struct wl_list *list; struct shell_surface *tmp; wl_list_for_each(tmp, &shell->screensaver.surfaces, link) @@ -914,21 +916,9 @@ resume_desktop(struct wl_shell *shell) terminate_screensaver(shell); - wl_list_for_each(surface, &shell->hidden_surface_list, link) - weston_surface_assign_output(surface); - - if (wl_list_empty(&shell->backgrounds)) { - list = &shell->compositor->surface_list; - } else { - struct shell_surface *background; - background = container_of(shell->backgrounds.prev, - struct shell_surface, link); - list = background->surface->link.prev; - } - - if (!wl_list_empty(&shell->hidden_surface_list)) - wl_list_insert_list(list, &shell->hidden_surface_list); - wl_list_init(&shell->hidden_surface_list); + wl_list_insert(&shell->fullscreen_layer.link, + &shell->panel_layer.link); + wl_list_insert(&shell->panel_layer.link, &shell->toplevel_layer.link); shell->locked = false; weston_compositor_repick(shell->compositor); @@ -1250,7 +1240,6 @@ activate(struct weston_shell *base, struct weston_surface *es, { struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct weston_compositor *compositor = shell->compositor; - struct wl_list *list; weston_surface_activate(es, device, time); @@ -1259,32 +1248,20 @@ activate(struct weston_shell *base, struct weston_surface *es, switch (get_shell_surface_type(es)) { case SHELL_SURFACE_BACKGROUND: - /* put background back to bottom */ - wl_list_remove(&es->link); - wl_list_insert(compositor->surface_list.prev, &es->link); - break; case SHELL_SURFACE_PANEL: - /* already put on top */ break; + case SHELL_SURFACE_SCREENSAVER: /* always below lock surface */ if (shell->lock_surface) { - wl_list_remove(&es->link); - wl_list_insert(&shell->lock_surface->surface->link, - &es->link); + weston_surface_restack(es, + &shell->lock_surface->surface->link); } break; default: - if (!shell->locked) { - list = weston_compositor_top(compositor); - - /* bring panel back to top */ - struct shell_surface *panel; - wl_list_for_each(panel, &shell->panels, link) { - wl_list_remove(&panel->surface->link); - wl_list_insert(list, &panel->surface->link); - } - } + weston_surface_restack(es, + &shell->toplevel_layer.surface_list); + break; } } @@ -1306,9 +1283,6 @@ static void lock(struct weston_shell *base) { struct wl_shell *shell = container_of(base, struct wl_shell, shell); - struct wl_list *surface_list = &shell->compositor->surface_list; - struct weston_surface *cur; - struct weston_surface *tmp; struct weston_input_device *device; struct shell_surface *shsurf; uint32_t time; @@ -1318,28 +1292,12 @@ lock(struct weston_shell *base) shell->locked = true; - /* Move all surfaces from compositor's list to our hidden list, - * except the background. This way nothing else can show or - * receive input events while we are locked. */ + /* Hide all surfaces by removing the toplevel and panels + * layers. This way nothing else can show or receive input + * events while we are locked. */ - if (!wl_list_empty(&shell->hidden_surface_list)) { - fprintf(stderr, - "%s: Assertion failed: hidden_surface_list is not empty.\n", - __func__); - } - - wl_list_for_each_safe(cur, tmp, surface_list, link) { - /* skip input device sprites, cur->surface is uninitialised */ - if (cur->surface.resource.client == NULL) - continue; - - if (get_shell_surface_type(cur) == SHELL_SURFACE_BACKGROUND) - continue; - - cur->output = NULL; - wl_list_remove(&cur->link); - wl_list_insert(shell->hidden_surface_list.prev, &cur->link); - } + wl_list_remove(&shell->panel_layer.link); + wl_list_remove(&shell->toplevel_layer.link); launch_screensaver(shell); @@ -1407,24 +1365,14 @@ map(struct weston_shell *base, struct weston_surface *surface, { struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct weston_compositor *compositor = shell->compositor; - struct wl_list *list; struct shell_surface *shsurf; enum shell_surface_type surface_type = SHELL_SURFACE_NONE; - int do_configure; int panel_height = 0; shsurf = get_shell_surface(surface); if (shsurf) surface_type = shsurf->type; - if (shell->locked) { - list = &shell->hidden_surface_list; - do_configure = 0; - } else { - list = weston_compositor_top(compositor); - do_configure = 1; - } - surface->geometry.width = width; surface->geometry.height = height; surface->geometry.dirty = 1; @@ -1465,19 +1413,19 @@ map(struct weston_shell *base, struct weston_surface *surface, switch (surface_type) { case SHELL_SURFACE_BACKGROUND: /* background always visible, at the bottom */ - wl_list_insert(compositor->surface_list.prev, &surface->link); - do_configure = 1; + wl_list_insert(&shell->background_layer.surface_list, + &surface->layer_link); break; case SHELL_SURFACE_PANEL: /* panel always on top, hidden while locked */ - wl_list_insert(list, &surface->link); + wl_list_insert(&shell->panel_layer.surface_list, + &surface->layer_link); break; case SHELL_SURFACE_LOCK: /* lock surface always visible, on top */ - wl_list_insert(&compositor->surface_list, &surface->link); - + wl_list_insert(&shell->toplevel_layer.surface_list, + &surface->layer_link); weston_compositor_wake(compositor); - do_configure = 1; break; case SHELL_SURFACE_SCREENSAVER: /* If locked, show it. */ @@ -1488,29 +1436,19 @@ map(struct weston_shell *base, struct weston_surface *surface, if (!shell->lock_surface) compositor->state = WESTON_COMPOSITOR_IDLE; } - do_configure = 0; break; case SHELL_SURFACE_NONE: - do_configure = 0; break; default: - /* everything else just below the panel */ - if (!wl_list_empty(&shell->panels)) { - struct shell_surface *panel = - container_of(shell->panels.prev, - struct shell_surface, link); - wl_list_insert(&panel->surface->link, &surface->link); - } else { - wl_list_insert(list, &surface->link); - } + wl_list_insert(&shell->toplevel_layer.surface_list, + &surface->layer_link); + break; } - if (do_configure) { - weston_surface_assign_output(surface); - weston_compositor_repick(compositor); - if (surface_type == SHELL_SURFACE_MAXIMIZED) - surface->output = shsurf->output; - } + weston_surface_assign_output(surface); + weston_compositor_repick(compositor); + if (surface_type == SHELL_SURFACE_MAXIMIZED) + surface->output = shsurf->output; switch (surface_type) { case SHELL_SURFACE_TOPLEVEL: @@ -1865,11 +1803,16 @@ shell_init(struct weston_compositor *ec) shell->shell.configure = configure; shell->shell.destroy = shell_destroy; - wl_list_init(&shell->hidden_surface_list); wl_list_init(&shell->backgrounds); wl_list_init(&shell->panels); wl_list_init(&shell->screensaver.surfaces); + weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link); + weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link); + weston_layer_init(&shell->toplevel_layer, &shell->panel_layer.link); + weston_layer_init(&shell->background_layer, + &shell->toplevel_layer.link); + shell_configuration(shell); if (wl_display_add_global(ec->wl_display, &wl_shell_interface, |