libweston: per-output z-ordered paint node list

This patch creates a per-output paint node list in the same z-order as
the global view_list in weston_compositor.

The next step is to switch output repaints and backends to use the
z-order list instead of view_list.

Having a per-output paint node list for repaints allows including only
those paint nodes that actually contribute to the output image, so that
completely occluded and out-of-screen views can be ignored in libweston
core already.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
dev
Pekka Paalanen 4 years ago
parent 1a4f87dec5
commit 2fddc539c5
  1. 6
      include/libweston/libweston.h
  2. 42
      libweston/compositor.c
  3. 7
      libweston/libweston-internal.h

@ -291,6 +291,12 @@ struct weston_output {
struct wl_list animation_list;
int32_t x, y, width, height;
/** List of paint nodes in z-order, from top to bottom, maybe pruned
*
* struct weston_paint_node::z_order_link
*/
struct wl_list paint_node_z_order_list;
/** Output area in global coordinates, simple rect */
pixman_region32_t region;

@ -121,6 +121,8 @@ weston_paint_node_create(struct weston_surface *surface,
pnode->output = output;
wl_list_insert(&output->paint_node_list, &pnode->output_link);
wl_list_init(&pnode->z_order_link);
return pnode;
}
@ -131,6 +133,7 @@ weston_paint_node_destroy(struct weston_paint_node *pnode)
wl_list_remove(&pnode->surface_link);
wl_list_remove(&pnode->view_link);
wl_list_remove(&pnode->output_link);
wl_list_remove(&pnode->z_order_link);
free(pnode);
}
@ -2676,6 +2679,18 @@ view_ensure_paint_node(struct weston_view *view, struct weston_output *output)
return weston_paint_node_create(view->surface, view, output);
}
static void
add_to_z_order_list(struct weston_output *output,
struct weston_paint_node *pnode)
{
if (!pnode)
return;
wl_list_remove(&pnode->z_order_link);
wl_list_insert(output->paint_node_z_order_list.prev,
&pnode->z_order_link);
}
static void
view_list_add_subsurface_view(struct weston_compositor *compositor,
struct weston_subsurface *sub,
@ -2684,6 +2699,7 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
{
struct weston_subsurface *child;
struct weston_view *view = NULL, *iv;
struct weston_paint_node *pnode;
if (!weston_surface_is_mapped(sub->surface))
return;
@ -2710,20 +2726,23 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
view->parent_view = parent;
weston_view_update_transform(view);
view->is_mapped = true;
view_ensure_paint_node(view, output);
pnode = view_ensure_paint_node(view, output);
if (wl_list_empty(&sub->surface->subsurface_list)) {
wl_list_insert(compositor->view_list.prev, &view->link);
add_to_z_order_list(output, pnode);
return;
}
wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
if (child->surface == sub->surface)
if (child->surface == sub->surface) {
wl_list_insert(compositor->view_list.prev, &view->link);
else
add_to_z_order_list(output, pnode);
} else {
view_list_add_subsurface_view(compositor, child, view, output);
}
}
}
/* This recursively adds the sub-surfaces for a view, relying on the
* sub-surface order. Thus, if a client restacks the sub-surfaces, that
@ -2736,23 +2755,27 @@ view_list_add(struct weston_compositor *compositor,
struct weston_view *view,
struct weston_output *output)
{
struct weston_paint_node *pnode;
struct weston_subsurface *sub;
weston_view_update_transform(view);
view_ensure_paint_node(view, output);
pnode = view_ensure_paint_node(view, output);
if (wl_list_empty(&view->surface->subsurface_list)) {
wl_list_insert(compositor->view_list.prev, &view->link);
add_to_z_order_list(output, pnode);
return;
}
wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
if (sub->surface == view->surface)
if (sub->surface == view->surface) {
wl_list_insert(compositor->view_list.prev, &view->link);
else
add_to_z_order_list(output, pnode);
} else {
view_list_add_subsurface_view(compositor, sub, view, output);
}
}
}
static void
weston_compositor_build_view_list(struct weston_compositor *compositor,
@ -2761,6 +2784,11 @@ weston_compositor_build_view_list(struct weston_compositor *compositor,
struct weston_view *view, *tmp;
struct weston_layer *layer;
if (output) {
wl_list_remove(&output->paint_node_z_order_list);
wl_list_init(&output->paint_node_z_order_list);
}
wl_list_for_each(layer, &compositor->layer_list, link)
wl_list_for_each(view, &layer->view_list.link, layer_link.link)
surface_stash_subsurface_views(view->surface);
@ -6227,6 +6255,7 @@ weston_compositor_remove_output(struct weston_output *output)
&output->paint_node_list, output_link) {
weston_paint_node_destroy(pnode);
}
assert(wl_list_empty(&output->paint_node_z_order_list));
wl_list_for_each(view, &compositor->view_list, link) {
if (view->output_mask & (1u << output->id))
@ -6579,6 +6608,7 @@ weston_output_enable(struct weston_output *output)
wl_list_init(&output->animation_list);
wl_list_init(&output->feedback_list);
wl_list_init(&output->paint_node_list);
wl_list_init(&output->paint_node_z_order_list);
/* Enable the output (set up the crtc or create a
* window representing the output, set up the

@ -398,6 +398,8 @@ weston_drm_format_get_modifiers(const struct weston_drm_format *format,
* A generic data structure unique for surface-view-output combination.
*/
struct weston_paint_node {
/* Immutable members: */
/* struct weston_surface::paint_node_list */
struct wl_list surface_link;
struct weston_surface *surface;
@ -409,6 +411,11 @@ struct weston_paint_node {
/* struct weston_output::paint_node_list */
struct wl_list output_link;
struct weston_output *output;
/* Mutable members: */
/* struct weston_output::paint_node_z_order_list */
struct wl_list z_order_link;
};
struct weston_paint_node *

Loading…
Cancel
Save