From 71079ffd1a4e71a29b297e5c403a8c48eccc9f83 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 5 Jun 2024 14:24:26 -0500 Subject: [PATCH] renderers: Make flush_damage take a weston_paint_node Currently we're passing in a surface, a buffer, and an output. All of these things are available in the paint node. Further, if we pass in the paint node directly, we don't have to walk a list of paint nodes to figure out if the texture is used in the upcoming repaint. Signed-off-by: Derek Foreman --- libweston/compositor.c | 3 +- libweston/libweston-internal.h | 4 +-- libweston/noop-renderer.c | 4 +-- libweston/pixman-renderer.c | 4 +-- libweston/renderer-gl/gl-renderer.c | 49 ++++++++++++++--------------- 5 files changed, 28 insertions(+), 36 deletions(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index eb858be5f..f96092bba 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -3220,8 +3220,7 @@ paint_node_flush_surface_damage(struct weston_paint_node *pnode) struct weston_paint_node *walk_node; if (buffer->type == WESTON_BUFFER_SHM) - surface->compositor->renderer->flush_damage(surface, buffer, - output); + surface->compositor->renderer->flush_damage(pnode); if (!pixman_region32_not_empty(&surface->damage)) return; diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index 3629e2fd9..c54b66816 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -79,9 +79,7 @@ struct weston_renderer { const struct weston_size *fb_size, const struct weston_geometry *area); - void (*flush_damage)(struct weston_surface *surface, - struct weston_buffer *buffer, - struct weston_output *output); + void (*flush_damage)(struct weston_paint_node *pnode); void (*attach)(struct weston_surface *es, struct weston_buffer *buffer); void (*destroy)(struct weston_compositor *ec); diff --git a/libweston/noop-renderer.c b/libweston/noop-renderer.c index 11c72311b..b878d7c2f 100644 --- a/libweston/noop-renderer.c +++ b/libweston/noop-renderer.c @@ -62,9 +62,7 @@ noop_renderer_resize_output(struct weston_output *output, } static void -noop_renderer_flush_damage(struct weston_surface *surface, - struct weston_buffer *buffer, - struct weston_output *output) +noop_renderer_flush_damage(struct weston_paint_node *pnode) { } diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index 3415ddc68..b9053ff68 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -688,9 +688,7 @@ pixman_renderer_repaint_output(struct weston_output *output, } static void -pixman_renderer_flush_damage(struct weston_surface *surface, - struct weston_buffer *buffer, - struct weston_output *output) +pixman_renderer_flush_damage(struct weston_paint_node *pnode) { /* No-op for pixman renderer */ } diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 87080cef3..e59eee967 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -2394,16 +2394,14 @@ gl_format_from_internal(GLenum internal_format) } static void -gl_renderer_flush_damage(struct weston_surface *surface, - struct weston_buffer *buffer, - struct weston_output *output) +gl_renderer_flush_damage_internal(struct weston_surface *surface, + bool just_accumulate) { const struct weston_testsuite_quirks *quirks = &surface->compositor->test_data.test_quirks; + struct weston_buffer *buffer = surface->buffer_ref.buffer; struct gl_surface_state *gs = get_surface_state(surface); struct gl_buffer_state *gb = gs->buffer; - struct weston_paint_node *pnode; - bool texture_used; pixman_box32_t *rectangles; uint8_t *data; int i, j, n; @@ -2413,31 +2411,15 @@ gl_renderer_flush_damage(struct weston_surface *surface, pixman_region32_union(&gb->texture_damage, &gb->texture_damage, &surface->damage); + if (just_accumulate) + return; + /* This can happen if a SHM wl_buffer gets destroyed before we flush * damage, because wayland-server just nukes the wl_shm_buffer from * underneath us */ if (!buffer->shm_buffer) return; - /* Avoid upload, if the texture won't be used this time. - * We still accumulate the damage in texture_damage, and - * hold the reference to the buffer, in case the surface - * migrates back to the primary plane. - * - * When called from gl_renderer_surface_copy_content() - * or gl_renderer_create_surface(), output is NULL. - * In that case, always upload. - */ - texture_used = false; - wl_list_for_each(pnode, &surface->paint_node_list, surface_link) { - if (!output || pnode->plane == &output->primary_plane) { - texture_used = true; - break; - } - } - if (!texture_used) - return; - if (!pixman_region32_not_empty(&gb->texture_damage) && !gb->needs_full_upload) goto done; @@ -2509,6 +2491,23 @@ done: weston_buffer_release_reference(&gs->buffer_release_ref, NULL); } +static void +gl_renderer_flush_damage(struct weston_paint_node *pnode) +{ + bool just_accumulate = false; + + /* Avoid upload, if the texture won't be used this time. + * We still accumulate the damage in texture_damage, and + * hold the reference to the buffer, in case the surface + * migrates back to the primary plane. + */ + if (pnode->plane != &pnode->output->primary_plane) + just_accumulate = true; + + gl_renderer_flush_damage_internal(pnode->surface, + just_accumulate); +} + static void destroy_buffer_state(struct gl_buffer_state *gb) { @@ -3613,7 +3612,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface, *(uint32_t *)target = pack_color(format, gb->color); return 0; case WESTON_BUFFER_SHM: - gl_renderer_flush_damage(surface, buffer, NULL); + gl_renderer_flush_damage_internal(surface, false); /* fall through */ case WESTON_BUFFER_DMABUF: case WESTON_BUFFER_RENDERER_OPAQUE: