[PATCH weston] compositor: add a map ref-count for weston_surface
Giulio Camuffo
giuliocamuffo at gmail.com
Thu Aug 15 08:11:19 PDT 2013
add a 'mapped' field to weston_surface so that it is initialized
to 0 on surface creation, and to 1 when the surface output is set.
One can manually increase it to make the surface remain visible
after an attach with a NULL buffer, so that it can animate it and
call weston_surface_unmap at the end. weston_surface_unmap decreases
the value of mapped and if it reaches 0 it actually unmaps the surface.
Instead of setting surface->output directly it is now preferable to
set a surface's output via the new function weston_surface_set_output,
which checks if it was mapped before, and if not it increases the
mapped value.
---
src/compositor.c | 24 +++++++++++++++++++++---
src/compositor.h | 5 +++++
src/shell.c | 14 +++++++-------
3 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index 8da348a..cae74e1 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -299,6 +299,7 @@ weston_surface_create(struct weston_compositor *compositor)
surface->pending.buffer_transform = surface->buffer_transform;
surface->pending.buffer_scale = surface->buffer_scale;
surface->output = NULL;
+ surface->mapped = 0;
surface->plane = &compositor->primary_plane;
surface->pending.newly_attached = 0;
@@ -567,7 +568,7 @@ weston_surface_assign_output(struct weston_surface *es)
}
pixman_region32_fini(®ion);
- es->output = new_output;
+ weston_surface_set_output(es, new_output);
weston_surface_update_output_mask(es, mask);
}
@@ -885,6 +886,16 @@ weston_surface_set_transform_parent(struct weston_surface *surface,
weston_surface_geometry_dirty(surface);
}
+WL_EXPORT void
+weston_surface_set_output(struct weston_surface *surface,
+ struct weston_output *output)
+{
+ if (!weston_surface_is_mapped(surface))
+ ++surface->mapped;
+
+ surface->output = output;
+}
+
WL_EXPORT int
weston_surface_is_mapped(struct weston_surface *surface)
{
@@ -976,7 +987,11 @@ weston_surface_unmap(struct weston_surface *surface)
{
struct weston_seat *seat;
+ if (--surface->mapped > 0)
+ return;
+
weston_surface_damage_below(surface);
+ surface->mapped = 0;
surface->output = NULL;
wl_list_remove(&surface->layer_link);
@@ -1137,9 +1152,11 @@ weston_surface_attach(struct weston_surface *surface,
if (!buffer) {
if (weston_surface_is_mapped(surface))
weston_surface_unmap(surface);
+ } else {
+ // Keep the old buffer around, so that it can be used to do
+ // unmap animations by the shell
+ surface->compositor->renderer->attach(surface, buffer);
}
-
- surface->compositor->renderer->attach(surface, buffer);
}
WL_EXPORT void
@@ -2008,6 +2025,7 @@ subsurface_configure(struct weston_surface *surface, int32_t dx, int32_t dy,
assert(!wl_list_empty(&compositor->output_list));
surface->output = container_of(compositor->output_list.next,
struct weston_output, link);
+ ++surface->mapped;
}
}
diff --git a/src/compositor.h b/src/compositor.h
index 6db3c61..891db0e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -710,6 +710,7 @@ struct weston_surface {
float alpha; /* part of geometry, see below */
struct weston_plane *plane;
int32_t ref_count;
+ int32_t mapped;
void *renderer_state;
@@ -851,6 +852,10 @@ weston_surface_buffer_width(struct weston_surface *surface);
int32_t
weston_surface_buffer_height(struct weston_surface *surface);
+void
+weston_surface_set_output(struct weston_surface *surface,
+ struct weston_output *output);
+
WL_EXPORT void
weston_surface_to_buffer_float(struct weston_surface *surface,
float x, float y, float *bx, float *by);
diff --git a/src/shell.c b/src/shell.c
index 8f2be78..88685d0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1790,7 +1790,7 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
wl_list_insert(&surface->layer_link,
&shsurf->fullscreen.black_surface->layer_link);
- shsurf->fullscreen.black_surface->output = output;
+ weston_surface_set_output(shsurf->fullscreen.black_surface, output);
surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
&surf_width, &surf_height);
@@ -2149,7 +2149,7 @@ shell_map_popup(struct shell_surface *shsurf)
struct weston_surface *es = shsurf->surface;
struct weston_surface *parent = shsurf->parent;
- es->output = parent->output;
+ weston_surface_set_output(es, parent->output);
weston_surface_set_transform_parent(es, parent);
weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
@@ -2453,7 +2453,7 @@ desktop_shell_set_background(struct wl_client *client,
surface->configure = background_configure;
surface->configure_private = shell;
- surface->output = wl_resource_get_user_data(output_resource);
+ weston_surface_set_output(surface, wl_resource_get_user_data(output_resource));
desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
@@ -2487,7 +2487,7 @@ desktop_shell_set_panel(struct wl_client *client,
surface->configure = panel_configure;
surface->configure_private = shell;
- surface->output = wl_resource_get_user_data(output_resource);
+ weston_surface_set_output(surface, wl_resource_get_user_data(output_resource));
desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
@@ -3434,7 +3434,7 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
if (surface_type != SHELL_SURFACE_NONE) {
weston_surface_update_transform(surface);
if (surface_type == SHELL_SURFACE_MAXIMIZED)
- surface->output = shsurf->output;
+ weston_surface_set_output(surface, shsurf->output);
}
switch (surface_type) {
@@ -3509,7 +3509,7 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
weston_surface_update_transform(surface);
if (surface_type == SHELL_SURFACE_MAXIMIZED)
- surface->output = shsurf->output;
+ weston_surface_set_output(surface, shsurf->output);
}
}
@@ -3685,7 +3685,7 @@ screensaver_set_surface(struct wl_client *client,
surface->configure = screensaver_configure;
surface->configure_private = shell;
- surface->output = output;
+ weston_surface_set_output(surface, output);
}
static const struct screensaver_interface screensaver_implementation = {
--
1.8.3.4
More information about the wayland-devel
mailing list