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; struct wl_list animation_list;
int32_t x, y, width, height; 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 */ /** Output area in global coordinates, simple rect */
pixman_region32_t region; pixman_region32_t region;

@ -121,6 +121,8 @@ weston_paint_node_create(struct weston_surface *surface,
pnode->output = output; pnode->output = output;
wl_list_insert(&output->paint_node_list, &pnode->output_link); wl_list_insert(&output->paint_node_list, &pnode->output_link);
wl_list_init(&pnode->z_order_link);
return pnode; 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->surface_link);
wl_list_remove(&pnode->view_link); wl_list_remove(&pnode->view_link);
wl_list_remove(&pnode->output_link); wl_list_remove(&pnode->output_link);
wl_list_remove(&pnode->z_order_link);
free(pnode); 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); 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 static void
view_list_add_subsurface_view(struct weston_compositor *compositor, view_list_add_subsurface_view(struct weston_compositor *compositor,
struct weston_subsurface *sub, struct weston_subsurface *sub,
@ -2684,6 +2699,7 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
{ {
struct weston_subsurface *child; struct weston_subsurface *child;
struct weston_view *view = NULL, *iv; struct weston_view *view = NULL, *iv;
struct weston_paint_node *pnode;
if (!weston_surface_is_mapped(sub->surface)) if (!weston_surface_is_mapped(sub->surface))
return; return;
@ -2710,18 +2726,21 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
view->parent_view = parent; view->parent_view = parent;
weston_view_update_transform(view); weston_view_update_transform(view);
view->is_mapped = true; 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)) { if (wl_list_empty(&sub->surface->subsurface_list)) {
wl_list_insert(compositor->view_list.prev, &view->link); wl_list_insert(compositor->view_list.prev, &view->link);
add_to_z_order_list(output, pnode);
return; return;
} }
wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) { 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); 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); view_list_add_subsurface_view(compositor, child, view, output);
}
} }
} }
@ -2736,21 +2755,25 @@ view_list_add(struct weston_compositor *compositor,
struct weston_view *view, struct weston_view *view,
struct weston_output *output) struct weston_output *output)
{ {
struct weston_paint_node *pnode;
struct weston_subsurface *sub; struct weston_subsurface *sub;
weston_view_update_transform(view); 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)) { if (wl_list_empty(&view->surface->subsurface_list)) {
wl_list_insert(compositor->view_list.prev, &view->link); wl_list_insert(compositor->view_list.prev, &view->link);
add_to_z_order_list(output, pnode);
return; return;
} }
wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) { 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); 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); view_list_add_subsurface_view(compositor, sub, view, output);
}
} }
} }
@ -2761,6 +2784,11 @@ weston_compositor_build_view_list(struct weston_compositor *compositor,
struct weston_view *view, *tmp; struct weston_view *view, *tmp;
struct weston_layer *layer; 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(layer, &compositor->layer_list, link)
wl_list_for_each(view, &layer->view_list.link, layer_link.link) wl_list_for_each(view, &layer->view_list.link, layer_link.link)
surface_stash_subsurface_views(view->surface); surface_stash_subsurface_views(view->surface);
@ -6227,6 +6255,7 @@ weston_compositor_remove_output(struct weston_output *output)
&output->paint_node_list, output_link) { &output->paint_node_list, output_link) {
weston_paint_node_destroy(pnode); weston_paint_node_destroy(pnode);
} }
assert(wl_list_empty(&output->paint_node_z_order_list));
wl_list_for_each(view, &compositor->view_list, link) { wl_list_for_each(view, &compositor->view_list, link) {
if (view->output_mask & (1u << output->id)) 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->animation_list);
wl_list_init(&output->feedback_list); wl_list_init(&output->feedback_list);
wl_list_init(&output->paint_node_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 /* Enable the output (set up the crtc or create a
* window representing the output, set up the * 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. * A generic data structure unique for surface-view-output combination.
*/ */
struct weston_paint_node { struct weston_paint_node {
/* Immutable members: */
/* struct weston_surface::paint_node_list */ /* struct weston_surface::paint_node_list */
struct wl_list surface_link; struct wl_list surface_link;
struct weston_surface *surface; struct weston_surface *surface;
@ -409,6 +411,11 @@ struct weston_paint_node {
/* struct weston_output::paint_node_list */ /* struct weston_output::paint_node_list */
struct wl_list output_link; struct wl_list output_link;
struct weston_output *output; struct weston_output *output;
/* Mutable members: */
/* struct weston_output::paint_node_z_order_list */
struct wl_list z_order_link;
}; };
struct weston_paint_node * struct weston_paint_node *

Loading…
Cancel
Save