From 2d1198e4fbbecd378e92bb71e3652c11276151a7 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Thu, 22 Jun 2023 13:02:08 -0500 Subject: [PATCH] libweston: Add a paint node content dirty bit This replaces the horribly broken surface damage code we have now. Signed-off-by: Derek Foreman --- libweston/compositor.c | 41 ++++++++++------------------------ libweston/libweston-internal.h | 3 ++- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index 1c553efd..6733187b 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -202,6 +202,7 @@ paint_node_update_late(struct weston_paint_node *pnode) { bool vis_dirty = pnode->status & PAINT_NODE_VISIBILITY_DIRTY; bool plane_dirty = pnode->status & PAINT_NODE_PLANE_DIRTY; + bool content_dirty = pnode->status & PAINT_NODE_CONTENT_DIRTY; /* The geoemtry may be shrinking, so we shouldn't just * add the old visible region to our damage region, because @@ -231,6 +232,10 @@ paint_node_update_late(struct weston_paint_node *pnode) if (pnode->plane && (vis_dirty || plane_dirty)) pixman_region32_copy(&pnode->damage, &pnode->visible); + if (content_dirty && pnode->plane) + pixman_region32_union(&pnode->damage, + &pnode->damage, &pnode->visible); + if (plane_dirty) { assert(pnode->plane_next); @@ -239,7 +244,8 @@ paint_node_update_late(struct weston_paint_node *pnode) } pnode->status &= ~(PAINT_NODE_VISIBILITY_DIRTY | - PAINT_NODE_PLANE_DIRTY); + PAINT_NODE_PLANE_DIRTY | + PAINT_NODE_CONTENT_DIRTY); /* Nothing should be able to flip "early" bits between * the early and late updates. @@ -1768,22 +1774,13 @@ weston_view_schedule_repaint(struct weston_view *view) weston_output_schedule_repaint(output); } -/** - * XXX: This function does it the wrong way. - * surface->damage is the damage from the client, and causes - * surface_flush_damage() to copy pixels. No window management action can - * cause damage to the client-provided content, warranting re-upload! - * - * Instead of surface->damage, this function should record the damage - * with all the views for this surface to avoid extraneous texture - * uploads. - */ WL_EXPORT void weston_surface_damage(struct weston_surface *surface) { - pixman_region32_union_rect(&surface->damage, &surface->damage, - 0, 0, surface->width, - surface->height); + struct weston_paint_node *pnode; + + wl_list_for_each(pnode, &surface->paint_node_list, surface_link) + pnode->status |= PAINT_NODE_CONTENT_DIRTY; weston_surface_schedule_repaint(surface); } @@ -2970,27 +2967,13 @@ paint_node_add_damage(struct weston_paint_node *node) pixman_region32_fini(&damage); } -/* FIXME: note that we don't flush any damage when the core wants us to - * do so as it will sometimes ask for a flush not necessarily at the - * right time. - * - * A (more) proper way is to handle correctly damage whenever there's - * compositor side damage. See the comment for weston_surface_damage(). - */ -static bool -buffer_can_be_accessed_BANDAID_XXX(struct weston_buffer_reference buffer_ref) -{ - return buffer_ref.type == BUFFER_MAY_BE_ACCESSED; -} - static void surface_flush_damage(struct weston_surface *surface, struct weston_output *output) { struct weston_buffer *buffer = surface->buffer_ref.buffer; struct weston_paint_node *node; - if (buffer->type == WESTON_BUFFER_SHM && - buffer_can_be_accessed_BANDAID_XXX(surface->buffer_ref)) + if (buffer->type == WESTON_BUFFER_SHM) surface->compositor->renderer->flush_damage(surface, buffer); if (!pixman_region32_not_empty(&surface->damage)) diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index cc798574..5fde652b 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -510,7 +510,8 @@ enum paint_node_status { PAINT_NODE_VIEW_DIRTY = 1 << 1, PAINT_NODE_VISIBILITY_DIRTY = 1 << 2, PAINT_NODE_PLANE_DIRTY = 1 << 3, - PAINT_NODE_ALL_DIRTY = (1 << 4) - 1, + PAINT_NODE_CONTENT_DIRTY = 1 << 4, + PAINT_NODE_ALL_DIRTY = (1 << 5) - 1, }; /**