libweston: Track plane in paint node instead of view

Tracking the view's plane in the paint node in this way is a step towards
inflicting plane damage from paint node update during the output repaint,
instead of manually doing weston_view_damage_below().

We remove view->plane entirely and do all access through pnodes.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2023-06-15 14:22:37 -05:00
parent ab6c6429df
commit fe2b5db01e
7 changed files with 84 additions and 46 deletions

View file

@ -1649,7 +1649,6 @@ struct weston_view {
struct wl_list link; /* weston_compositor::view_list */
struct weston_layer_entry layer_link; /* part of geometry */
struct weston_plane *plane;
/* For weston_layer inheritance from another view */
struct weston_view *parent_view;

View file

@ -1055,11 +1055,11 @@ drm_assign_planes(struct weston_output *output_base)
drm_debug(b, "\t[repaint] view %p on %s plane %lu\n",
ev, plane_type_enums[target_plane->type].name,
(unsigned long) target_plane->plane_id);
weston_view_move_to_plane(ev, &target_plane->base);
weston_paint_node_move_to_plane(pnode, &target_plane->base);
} else {
drm_debug(b, "\t[repaint] view %p using renderer "
"composition\n", ev);
weston_view_move_to_plane(ev, primary);
weston_paint_node_move_to_plane(pnode, primary);
}
if (!target_plane ||

View file

@ -449,7 +449,8 @@ vnc_client_cleanup(struct nvnc_client *client)
}
static struct weston_pointer *
vnc_output_get_pointer(struct vnc_output *output)
vnc_output_get_pointer(struct vnc_output *output,
struct weston_paint_node **pointer_pnode)
{
struct weston_pointer *pointer = NULL;
struct weston_paint_node *pnode;
@ -464,8 +465,10 @@ vnc_output_get_pointer(struct vnc_output *output)
return NULL;
wl_list_for_each(pnode, &output->base.paint_node_z_order_list, z_order_link) {
if (pnode->view == pointer->sprite)
if (pnode->view == pointer->sprite) {
*pointer_pnode = pnode;
return pointer;
}
}
return NULL;
@ -476,6 +479,7 @@ vnc_output_update_cursor(struct vnc_output *output)
{
struct vnc_backend *backend = output->backend;
struct weston_pointer *pointer;
struct weston_paint_node *pointer_pnode = NULL;
struct weston_view *view;
struct weston_buffer *buffer;
struct nvnc_fb *fb;
@ -484,7 +488,7 @@ vnc_output_update_cursor(struct vnc_output *output)
uint8_t *src, *dst;
int i;
pointer = vnc_output_get_pointer(output);
pointer = vnc_output_get_pointer(output, &pointer_pnode);
if (!pointer)
return;
@ -500,7 +504,9 @@ vnc_output_update_cursor(struct vnc_output *output)
if (format != WL_SHM_FORMAT_ARGB8888)
return;
weston_view_move_to_plane(view, &output->cursor_plane);
assert(pointer_pnode);
weston_paint_node_move_to_plane(pointer_pnode, &output->cursor_plane);
if (view->surface == output->cursor_surface &&
!pixman_region32_not_empty(&view->surface->damage))
@ -1050,7 +1056,7 @@ vnc_output_assign_planes(struct weston_output *base)
assert(view->output_mask & (1u << output->base.id));
/* Skip cursor view */
if (view->plane == &output->cursor_plane)
if (pnode->plane == &output->cursor_plane)
continue;
if (topmost &&
@ -1061,7 +1067,7 @@ vnc_output_assign_planes(struct weston_output *base)
pixman_region32_t local_damage;
pixman_region16_t nvnc_damage;
weston_view_move_to_plane(view, &output->scanout_plane);
weston_paint_node_move_to_plane(pnode, &output->scanout_plane);
/* Convert to local coordinates */
pixman_region32_init(&local_damage);
@ -1083,7 +1089,7 @@ vnc_output_assign_planes(struct weston_output *base)
nvnc_fb_unref(fb);
} else {
weston_view_move_to_plane(view, primary);
weston_paint_node_move_to_plane(pnode, primary);
}
topmost = false;

View file

@ -181,6 +181,8 @@ paint_node_update_early(struct weston_paint_node *pnode)
static void
paint_node_update_late(struct weston_paint_node *pnode)
{
bool plane_dirty = pnode->status & PAINT_NODE_PLANE_DIRTY;
/* 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.
@ -189,7 +191,15 @@ paint_node_update_late(struct weston_paint_node *pnode)
&pnode->view->visible,
&pnode->output->region);
pnode->status &= ~(PAINT_NODE_VISIBILITY_DIRTY);
if (plane_dirty) {
assert(pnode->plane_next);
pnode->plane = pnode->plane_next;
pnode->plane_next = NULL;
}
pnode->status &= ~(PAINT_NODE_VISIBILITY_DIRTY |
PAINT_NODE_PLANE_DIRTY);
/* Nothing should be able to flip "early" bits between
* the early and late updates.
@ -240,7 +250,10 @@ weston_paint_node_create(struct weston_surface *surface,
pixman_region32_init(&pnode->visible);
pixman_region32_copy(&pnode->visible, &view->visible);
pnode->status = PAINT_NODE_ALL_DIRTY;
pnode->plane = &pnode->surface->compositor->primary_plane;
pnode->plane_next = NULL;
pnode->status = PAINT_NODE_ALL_DIRTY & ~PAINT_NODE_PLANE_DIRTY;
return pnode;
}
@ -503,7 +516,6 @@ weston_view_create_internal(struct weston_surface *surface)
return NULL;
view->surface = surface;
view->plane = &surface->compositor->primary_plane;
/* Assign to surface */
wl_list_insert(&surface->views, &view->surface_link);
@ -984,15 +996,20 @@ weston_view_buffer_to_output_matrix(const struct weston_view *view,
}
WL_EXPORT void
weston_view_move_to_plane(struct weston_view *view,
struct weston_plane *plane)
weston_paint_node_move_to_plane(struct weston_paint_node *pnode,
struct weston_plane *plane)
{
if (view->plane == plane)
assert(plane);
if (pnode->plane == plane)
return;
weston_view_damage_below(view);
view->plane = plane;
weston_surface_damage(view->surface);
weston_view_damage_below(pnode->view);
pnode->plane_next = plane;
weston_surface_damage(pnode->view->surface);
pnode->status |= PAINT_NODE_PLANE_DIRTY |
PAINT_NODE_VISIBILITY_DIRTY;
}
/** Inflict damage on the plane where the view is visible.
@ -1014,14 +1031,18 @@ weston_view_move_to_plane(struct weston_view *view,
WL_EXPORT void
weston_view_damage_below(struct weston_view *view)
{
struct weston_paint_node *pnode;
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_subtract(&damage, &view->transform.boundingbox,
&view->clip);
if (view->plane)
pixman_region32_union(&view->plane->damage,
&view->plane->damage, &damage);
wl_list_for_each(pnode, &view->paint_node_list, view_link) {
assert(pnode->plane);
pixman_region32_union(&pnode->plane->damage,
&pnode->plane->damage, &damage);
}
pixman_region32_fini(&damage);
weston_view_schedule_repaint(view);
}
@ -2242,7 +2263,6 @@ weston_view_unmap(struct weston_view *view)
weston_view_damage_below(view);
weston_view_set_output(view, NULL);
view->plane = NULL;
view->is_mapped = false;
weston_layer_entry_remove(&view->layer_link);
wl_list_remove(&view->link);
@ -2942,6 +2962,7 @@ surface_flush_damage(struct weston_surface *surface, struct weston_output *outpu
static void
view_accumulate_damage(struct weston_view *view)
{
struct weston_paint_node *pnode;
pixman_region32_t damage;
assert(!view->transform.dirty);
@ -2960,8 +2981,11 @@ view_accumulate_damage(struct weston_view *view)
}
pixman_region32_intersect(&damage, &damage, &view->visible);
pixman_region32_union(&view->plane->damage,
&view->plane->damage, &damage);
wl_list_for_each(pnode, &view->paint_node_list, view_link) {
pixman_region32_union(&pnode->plane->damage,
&pnode->plane->damage, &damage);
}
pixman_region32_fini(&damage);
}
@ -2995,7 +3019,7 @@ output_update_visibility(struct weston_output *output)
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane != plane)
if (pnode->plane != plane)
continue;
view_update_clip_and_visible(pnode->view, &opaque);
@ -3018,7 +3042,7 @@ output_accumulate_damage(struct weston_output *output)
wl_list_for_each(plane, &ec->plane_list, link) {
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane != plane)
if (pnode->plane != plane)
continue;
view_accumulate_damage(pnode->view);
@ -3300,7 +3324,7 @@ weston_output_repaint(struct weston_output *output)
} else {
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
weston_view_move_to_plane(pnode->view, &ec->primary_plane);
weston_paint_node_move_to_plane(pnode, &ec->primary_plane);
pnode->view->psf_flags = 0;
}
}
@ -5658,18 +5682,24 @@ weston_plane_init(struct weston_plane *plane, struct weston_compositor *ec)
WL_EXPORT void
weston_plane_release(struct weston_plane *plane)
{
struct weston_view *view;
struct weston_output *output;
pixman_region32_fini(&plane->damage);
pixman_region32_fini(&plane->clip);
/*
* Can't use paint node list here, weston_plane is not specific to an
* output.
*/
wl_list_for_each(view, &plane->compositor->view_list, link) {
if (view->plane == plane)
view->plane = NULL;
wl_list_for_each(output, &plane->compositor->output_list, link) {
struct weston_paint_node *node;
wl_list_for_each(node, &output->paint_node_z_order_list,
z_order_link) {
if (node->plane != plane)
continue;
node->plane = NULL;
node->plane_next = &output->compositor->primary_plane;
node->status |= PAINT_NODE_PLANE_DIRTY |
PAINT_NODE_VISIBILITY_DIRTY;
}
}
wl_list_remove(&plane->link);

View file

@ -418,8 +418,8 @@ weston_view_takes_input_at_point(struct weston_view *view,
struct weston_coord_surface surf_pos);
void
weston_view_move_to_plane(struct weston_view *view,
struct weston_plane *plane);
weston_paint_node_move_to_plane(struct weston_paint_node *pnode,
struct weston_plane *plane);
void
weston_view_buffer_to_output_matrix(const struct weston_view *view,
const struct weston_output *output,
@ -509,7 +509,8 @@ enum paint_node_status {
PAINT_NODE_OUTPUT_DIRTY = 1 << 0,
PAINT_NODE_VIEW_DIRTY = 1 << 1,
PAINT_NODE_VISIBILITY_DIRTY = 1 << 2,
PAINT_NODE_ALL_DIRTY = (1 << 3) - 1,
PAINT_NODE_PLANE_DIRTY = 1 << 3,
PAINT_NODE_ALL_DIRTY = (1 << 4) - 1,
};
/**
@ -546,6 +547,8 @@ struct weston_paint_node {
struct wl_list z_order_link;
pixman_region32_t visible;
struct weston_plane *plane;
struct weston_plane *plane_next;
struct weston_surface_color_transform surf_xform;
bool surf_xform_valid;

View file

@ -550,7 +550,7 @@ repaint_surfaces(struct weston_output *output, pixman_region32_t *damage)
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane == &compositor->primary_plane)
if (pnode->plane == &compositor->primary_plane)
draw_paint_node(pnode, damage);
}
}

View file

@ -1338,7 +1338,7 @@ repaint_views(struct weston_output *output, pixman_region32_t *damage)
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane == &compositor->primary_plane)
if (pnode->plane == &compositor->primary_plane)
draw_paint_node(pnode, damage);
}
@ -1365,7 +1365,7 @@ update_buffer_release_fences(struct weston_compositor *compositor,
struct weston_buffer_release *buffer_release;
int fence_fd;
if (view->plane != &compositor->primary_plane)
if (pnode->plane != &compositor->primary_plane)
continue;
gs = get_surface_state(view->surface);
@ -1861,7 +1861,7 @@ gl_renderer_repaint_output(struct weston_output *output,
* which surfaces were used in this output repaint. */
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane == &compositor->primary_plane) {
if (pnode->plane == &compositor->primary_plane) {
struct gl_surface_state *gs =
get_surface_state(pnode->view->surface);
gs->used_in_output_repaint = false;
@ -2075,7 +2075,7 @@ gl_renderer_flush_damage(struct weston_surface *surface,
&surface->compositor->test_data.test_quirks;
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = gs->buffer;
struct weston_view *view;
struct weston_paint_node *pnode;
bool texture_used;
pixman_box32_t *rectangles;
uint8_t *data;
@ -2098,8 +2098,8 @@ gl_renderer_flush_damage(struct weston_surface *surface,
* migrates back to the primary plane.
*/
texture_used = false;
wl_list_for_each(view, &surface->views, surface_link) {
if (view->plane == &surface->compositor->primary_plane) {
wl_list_for_each(pnode, &surface->paint_node_list, surface_link) {
if (pnode->plane == &surface->compositor->primary_plane) {
texture_used = true;
break;
}