From 1619a4a1e5365ae02d8690dcb3eda495d9060d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Wed, 31 Jul 2024 18:29:35 +0200 Subject: [PATCH] libweston: Let renderers manage renderbuffers' damage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the responsibility for damaging the entire area of new renderbuffers from backends to renderers. There's one little drawback: VNC damage logging can't log the accumulated renderbuffer damage anymore, but I guess this should somehow be done as an option in the renderers. Signed-off-by: Loïc Molinari --- libweston/backend-drm/drm.c | 6 ------ libweston/backend-rdp/rdp.c | 3 --- libweston/backend-vnc/vnc.c | 17 ++++----------- libweston/backend-wayland/wayland.c | 5 +---- libweston/libweston-internal.h | 1 - libweston/pixman-renderer.c | 27 +++++++++++------------ libweston/renderer-gl/gl-renderer.c | 33 +++++++++++++++-------------- 7 files changed, 36 insertions(+), 56 deletions(-) diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index 8a872327f..3be250876 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -1630,12 +1630,6 @@ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b) output->dumb[i]->strides[0]); if (!output->renderbuffer[i]) goto err; - - pixman_region32_init_rect(&output->renderbuffer[i]->damage, - output->base.pos.c.x, - output->base.pos.c.y, - output->base.width, - output->base.height); } weston_log("DRM: output %s %s shadow framebuffer.\n", output->base.name, diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 0059b4189..dddf987ff 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -384,9 +384,6 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode) default: unreachable("cannot have auto renderer at runtime"); } - pixman_image_composite32(PIXMAN_OP_SRC, rdpOutput->shadow_surface, - 0, new_image, 0, 0, 0, 0, 0, 0, - mode->width, mode->height); weston_renderbuffer_unref(rdpOutput->renderbuffer); rdpOutput->renderbuffer = new_renderbuffer; pixman_image_unref(rdpOutput->shadow_surface); diff --git a/libweston/backend-vnc/vnc.c b/libweston/backend-vnc/vnc.c index 6cea3988e..5d950d68d 100644 --- a/libweston/backend-vnc/vnc.c +++ b/libweston/backend-vnc/vnc.c @@ -653,8 +653,7 @@ vnc_log_scope_print_region(struct weston_log_scope *log, pixman_region32_t *regi } static void -vnc_log_damage(struct vnc_backend *backend, pixman_region32_t *buffer_damage, - pixman_region32_t *update_damage) +vnc_log_damage(struct vnc_backend *backend, pixman_region32_t *damage) { char timestr[128]; @@ -663,12 +662,8 @@ vnc_log_damage(struct vnc_backend *backend, pixman_region32_t *buffer_damage, weston_log_scope_timestamp(backend->debug, timestr, sizeof timestr); - weston_log_scope_printf(backend->debug, "%s buffer damage:", timestr); - vnc_log_scope_print_region(backend->debug, buffer_damage); - weston_log_scope_printf(backend->debug, "\n"); - - weston_log_scope_printf(backend->debug, "%s update damage:", timestr); - vnc_log_scope_print_region(backend->debug, update_damage); + weston_log_scope_printf(backend->debug, "%s damage:", timestr); + vnc_log_scope_print_region(backend->debug, damage); weston_log_scope_printf(backend->debug, "\n\n"); } @@ -719,15 +714,11 @@ vnc_update_buffer(struct nvnc_display *display, struct pixman_region32 *damage) unreachable("cannot have auto renderer at runtime"); } - /* This is a new buffer, so the whole surface is damaged. */ - pixman_region32_copy(&renderbuffer->damage, - &output->base.region); - nvnc_set_userdata(fb, renderbuffer, (nvnc_cleanup_fn)weston_renderbuffer_unref); } - vnc_log_damage(backend, &renderbuffer->damage, damage); + vnc_log_damage(backend, damage); ec->renderer->repaint_output(&output->base, damage, renderbuffer); diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c index 8b5d96197..509455058 100644 --- a/libweston/backend-wayland/wayland.c +++ b/libweston/backend-wayland/wayland.c @@ -395,15 +395,12 @@ wayland_output_get_shm_buffer(struct wayland_output *output) pixman = renderer->pixman; /* Address only the interior, excluding output decorations */ - if (renderer->type == WESTON_RENDERER_PIXMAN) { + if (renderer->type == WESTON_RENDERER_PIXMAN) sb->renderbuffer = pixman->create_image_from_ptr(&output->base, pfmt, area.width, area.height, (uint32_t *)(data + area.y * stride) + area.x, stride); - pixman_region32_copy(&sb->renderbuffer->damage, - &output->base.region); - } return sb; } diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index 0cdb9e2d7..1c7218d68 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -47,7 +47,6 @@ /* compositor <-> renderer interface */ struct weston_renderbuffer { - pixman_region32_t damage; int refcount; void (*destroy)(struct weston_renderbuffer *renderbuffer); diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index 15401eb51..74552574d 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -66,6 +66,7 @@ struct pixman_surface_state { struct pixman_renderbuffer { struct weston_renderbuffer base; + pixman_region32_t damage; pixman_image_t *image; struct wl_list link; }; @@ -651,6 +652,11 @@ pixman_renderer_repaint_output(struct weston_output *output, assert(renderbuffer); + /* Accumulate damage in all renderbuffers */ + wl_list_for_each(rb, &po->renderbuffer_list, link) { + pixman_region32_union(&rb->damage, &rb->damage, output_damage); + } + rb = to_pixman_renderbuffer(renderbuffer); pixman_renderer_output_set_buffer(output, rb->image); @@ -661,26 +667,19 @@ pixman_renderer_repaint_output(struct weston_output *output, if (!po->hw_buffer) return; - /* Accumulate damage in all renderbuffers */ - wl_list_for_each(rb, &po->renderbuffer_list, link) { - pixman_region32_union(&rb->base.damage, - &rb->base.damage, - output_damage); - } - if (po->shadow_image) { repaint_surfaces(output, output_damage); pixman_renderer_do_capture_tasks(output, WESTON_OUTPUT_CAPTURE_SOURCE_BLENDING, po->shadow_image, po->shadow_format); - copy_to_hw_buffer(output, &renderbuffer->damage); + copy_to_hw_buffer(output, &rb->damage); } else { - repaint_surfaces(output, &renderbuffer->damage); + repaint_surfaces(output, &rb->damage); } pixman_renderer_do_capture_tasks(output, WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER, po->hw_buffer, po->hw_format); - pixman_region32_clear(&renderbuffer->damage); + pixman_region32_clear(&rb->damage); wl_signal_emit(&output->frame_signal, output_damage); @@ -1177,7 +1176,8 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output, return NULL; } - pixman_region32_init(&renderbuffer->base.damage); + pixman_region32_init(&renderbuffer->damage); + pixman_region32_copy(&renderbuffer->damage, &output->region); renderbuffer->base.refcount = 2; renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy; wl_list_insert(&po->renderbuffer_list, &renderbuffer->link); @@ -1205,7 +1205,8 @@ pixman_renderer_create_image(struct weston_output *output, return NULL; } - pixman_region32_init(&renderbuffer->base.damage); + pixman_region32_init(&renderbuffer->damage); + pixman_region32_copy(&renderbuffer->damage, &output->region); renderbuffer->base.refcount = 2; renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy; wl_list_insert(&po->renderbuffer_list, &renderbuffer->link); @@ -1219,7 +1220,7 @@ pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer) struct pixman_renderbuffer *rb = to_pixman_renderbuffer(renderbuffer); pixman_image_unref(rb->image); - pixman_region32_fini(&rb->base.damage); + pixman_region32_fini(&rb->damage); free(rb); } diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 970a34015..e0c85ee67 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -104,6 +104,7 @@ struct gl_fbo_texture { struct gl_renderbuffer { struct weston_renderbuffer base; + pixman_region32_t damage; enum gl_border_status border_damage; /* The fbo value zero represents the default surface framebuffer. */ GLuint fbo; @@ -695,7 +696,7 @@ gl_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer) glDeleteFramebuffers(1, &rb->fbo); glDeleteRenderbuffers(1, &rb->rb); - pixman_region32_fini(&rb->base.damage); + pixman_region32_fini(&rb->damage); free(rb); } @@ -709,8 +710,8 @@ gl_renderer_create_dummy_renderbuffer(struct weston_output *output) renderbuffer->fbo = 0; - pixman_region32_init(&renderbuffer->base.damage); - pixman_region32_copy(&renderbuffer->base.damage, &output->region); + pixman_region32_init(&renderbuffer->damage); + pixman_region32_copy(&renderbuffer->damage, &output->region); renderbuffer->border_damage = BORDER_ALL_DIRTY; /* * A single reference is kept on the renderbuffer_list, @@ -775,7 +776,8 @@ gl_renderer_create_fbo(struct weston_output *output, renderbuffer->pixels = pixels; - pixman_region32_init(&renderbuffer->base.damage); + pixman_region32_init(&renderbuffer->damage); + pixman_region32_copy(&renderbuffer->damage, &output->region); /* * One reference is kept on the renderbuffer_list, * the other is returned to the calling backend. @@ -2153,7 +2155,7 @@ output_get_dummy_renderbuffer(struct weston_output *output) BUFFER_DAMAGE_COUNT : 1; if ((buffer_age == 0 || buffer_age - 1 > BUFFER_DAMAGE_COUNT) && count >= max_buffers) { - pixman_region32_copy(&oldest_rb->base.damage, &output->region); + pixman_region32_copy(&oldest_rb->damage, &output->region); oldest_rb->border_damage = BORDER_ALL_DIRTY; oldest_rb->age = 0; return oldest_rb; @@ -2355,9 +2357,7 @@ gl_renderer_repaint_output(struct weston_output *output, /* Accumulate damage in all renderbuffers */ wl_list_for_each(rb, &go->renderbuffer_list, link) { - pixman_region32_union(&rb->base.damage, - &rb->base.damage, - output_damage); + pixman_region32_union(&rb->damage, &rb->damage, output_damage); rb->border_damage |= go->border_status; } @@ -2410,7 +2410,7 @@ gl_renderer_repaint_output(struct weston_output *output, if (gr->debug_clear) { pixman_region32_t undamaged; pixman_region32_t *damaged = - shadow_exists(go) ? output_damage : &rb->base.damage; + shadow_exists(go) ? output_damage : &rb->damage; int debug_mode = gr->debug_mode; pixman_region32_init(&undamaged); @@ -2429,7 +2429,7 @@ gl_renderer_repaint_output(struct weston_output *output, /* For partial_update, we need to pass the region which has * changed since we last rendered into this specific buffer. */ - pixman_region_to_egl(output, &rb->base.damage, + pixman_region_to_egl(output, &rb->damage, &egl_rects, &n_egl_rects); gr->set_damage_region(gr->egl_display, go->egl_surface, egl_rects, n_egl_rects); @@ -2447,9 +2447,9 @@ gl_renderer_repaint_output(struct weston_output *output, glViewport(go->area.x, area_y, go->area.width, go->area.height); blit_shadow_to_output(output, gr->debug_clear ? - &output->region : &rb->base.damage); + &output->region : &rb->damage); } else { - repaint_views(output, &rb->base.damage); + repaint_views(output, &rb->damage); } draw_output_borders(output, rb->border_damage); @@ -2518,7 +2518,7 @@ gl_renderer_repaint_output(struct weston_output *output, }; extents = weston_matrix_transform_rect(&output->matrix, - rb->base.damage.extents); + rb->damage.extents); if (gr->debug_clear) { rect.y = go->area.y; @@ -2543,7 +2543,7 @@ gl_renderer_repaint_output(struct weston_output *output, glPixelStorei(GL_PACK_ROW_LENGTH, 0); } - pixman_region32_clear(&rb->base.damage); + pixman_region32_clear(&rb->damage); gl_renderer_garbage_collect_programs(gr); } @@ -4208,7 +4208,7 @@ gl_renderer_dmabuf_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer glDeleteFramebuffers(1, &gl_renderbuffer->fbo); glDeleteRenderbuffers(1, &gl_renderbuffer->rb); - pixman_region32_fini(&gl_renderbuffer->base.damage); + pixman_region32_fini(&gl_renderbuffer->damage); gr->destroy_image(gr->egl_display, dmabuf_renderbuffer->image); @@ -4272,7 +4272,8 @@ gl_renderer_create_renderbuffer_dmabuf(struct weston_output *output, rb->gr = gr; rb->dmabuf = dmabuf; - pixman_region32_init(&rb->base.base.damage); + pixman_region32_init(&renderbuffer->damage); + pixman_region32_copy(&renderbuffer->damage, &output->region); /* * One reference is kept on the renderbuffer_list, * the other is returned to the calling backend.