libweston: Track visibility in paint nodes

Now that we have visibility for views, we can clip that to an output
and store it in paint nodes.

This requires us to split the paint_node_update() function into two,
one for things that need to be done before assign_planes() and
one for after.

This will eventually be useful for tracking damage with paint nodes,
as we'll need to damage a paint node's entire visible area for
some operations.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2023-06-15 13:52:53 -05:00
parent 3791e370d4
commit 8d00cf7a96
4 changed files with 47 additions and 7 deletions

View file

@ -120,7 +120,8 @@ weston_view_dirty_paint_nodes(struct weston_view *view)
wl_list_for_each(node, &view->paint_node_list, view_link) {
assert(node->surface == view->surface);
node->status |= PAINT_NODE_VIEW_DIRTY;
node->status |= PAINT_NODE_VIEW_DIRTY |
PAINT_NODE_VISIBILITY_DIRTY;
}
}
@ -148,8 +149,14 @@ weston_output_dirty_paint_nodes(struct weston_output *output)
}
}
/* Paint nodes contain filter and transform information that needs to be
* up to date before assign_planes() is called. But there are also
* damage related bits that must be updated after assign_planes()
* completes.
* The early update handles just the pre-assign_planes() data.
*/
static void
paint_node_update(struct weston_paint_node *pnode)
paint_node_update_early(struct weston_paint_node *pnode)
{
struct weston_matrix *mat = &pnode->buffer_to_output_matrix;
bool view_dirty = pnode->status & PAINT_NODE_VIEW_DIRTY;
@ -165,8 +172,29 @@ paint_node_update(struct weston_paint_node *pnode)
&pnode->transform);
}
pnode->status = PAINT_NODE_CLEAN;
pnode->status &= ~(PAINT_NODE_VIEW_DIRTY | PAINT_NODE_OUTPUT_DIRTY);
}
/* Update all the paint node data that needs to be handled after
* assign_planes() completes.
*/
static void
paint_node_update_late(struct weston_paint_node *pnode)
{
/* Even if our geometry didn't change, our visible region may
* have been updated by some other node changing. Keep the
* visible region up to date.
*/
pixman_region32_intersect(&pnode->visible,
&pnode->view->visible,
&pnode->output->region);
pnode->status &= ~(PAINT_NODE_VISIBILITY_DIRTY);
/* Nothing should be able to flip "early" bits between
* the early and late updates.
*/
assert(pnode->status == PAINT_NODE_CLEAN);
}
static struct weston_paint_node *
@ -209,6 +237,9 @@ weston_paint_node_create(struct weston_surface *surface,
wl_list_init(&pnode->z_order_link);
pixman_region32_init(&pnode->visible);
pixman_region32_copy(&pnode->visible, &view->visible);
pnode->status = PAINT_NODE_ALL_DIRTY;
return pnode;
@ -224,6 +255,7 @@ weston_paint_node_destroy(struct weston_paint_node *pnode)
wl_list_remove(&pnode->z_order_link);
assert(pnode->surf_xform_valid || !pnode->surf_xform.transform);
weston_surface_color_transform_fini(&pnode->surf_xform);
pixman_region32_fini(&pnode->visible);
free(pnode);
}
@ -498,6 +530,7 @@ weston_view_create_internal(struct weston_surface *surface)
pixman_region32_init(&view->transform.boundingbox);
view->transform.dirty = 1;
weston_view_update_transform(view);
pixman_region32_copy(&view->visible, &view->transform.boundingbox);
return view;
}
@ -3251,7 +3284,7 @@ weston_output_repaint(struct weston_output *output)
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link)
paint_node_update(pnode);
paint_node_update_early(pnode);
if (output->assign_planes && !output->disable_planes) {
output->assign_planes(output);
@ -3280,6 +3313,10 @@ weston_output_repaint(struct weston_output *output)
output_update_visibility(output);
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link)
paint_node_update_late(pnode);
output_accumulate_damage(output);
pixman_region32_init(&output_damage);

View file

@ -508,7 +508,8 @@ enum paint_node_status {
PAINT_NODE_CLEAN = 0,
PAINT_NODE_OUTPUT_DIRTY = 1 << 0,
PAINT_NODE_VIEW_DIRTY = 1 << 1,
PAINT_NODE_ALL_DIRTY = (1 << 2) - 1,
PAINT_NODE_VISIBILITY_DIRTY = 1 << 2,
PAINT_NODE_ALL_DIRTY = (1 << 3) - 1,
};
/**
@ -544,6 +545,8 @@ struct weston_paint_node {
/* struct weston_output::paint_node_z_order_list */
struct wl_list z_order_link;
pixman_region32_t visible;
struct weston_surface_color_transform surf_xform;
bool surf_xform_valid;

View file

@ -514,7 +514,7 @@ draw_paint_node(struct weston_paint_node *pnode,
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint,
&pnode->view->visible, damage);
&pnode->visible, damage);
if (!pixman_region32_not_empty(&repaint))
goto out;

View file

@ -1257,7 +1257,7 @@ draw_paint_node(struct weston_paint_node *pnode,
return;
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint, &pnode->view->visible, damage);
pixman_region32_intersect(&repaint, &pnode->visible, damage);
if (!pixman_region32_not_empty(&repaint))
goto out;