compositor: replace surface_state->buffer with a buffer_ref

Use a buffer_ref here to allow us to remove the subsurface
cached_buffer_ref and keep it in the surface state struct instead.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2025-07-15 15:36:16 -05:00
parent 760ca22e8f
commit ed1edb7b5c
4 changed files with 22 additions and 60 deletions

View file

@ -1664,8 +1664,7 @@ struct weston_surface_state {
enum weston_surface_status status;
/* wl_surface.attach */
struct weston_buffer *buffer;
struct wl_listener buffer_destroy_listener;
struct weston_buffer_reference buffer_ref;
struct weston_coord_surface buf_offset;
@ -1902,7 +1901,6 @@ struct weston_subsurface {
} position;
struct weston_surface_state cached;
struct weston_buffer_reference cached_buffer_ref;
bool synchronized;
bool effectively_synchronized;

View file

@ -4433,7 +4433,8 @@ surface_attach(struct wl_client *client,
/* Attach, attach, without commit in between does not send
* wl_buffer.release. */
weston_surface_state_set_buffer(&surface->pending, buffer);
weston_buffer_reference(&surface->pending.buffer_ref, buffer,
BUFFER_WILL_NOT_BE_ACCESSED);
surface->pending.status |= WESTON_SURFACE_DIRTY_BUFFER;
}
@ -4605,11 +4606,13 @@ weston_surface_is_pending_viewport_source_valid(
if ((pend->status & WESTON_SURFACE_DIRTY_BUFFER) ||
(pend->status & WESTON_SURFACE_DIRTY_SIZE)) {
if (pend->buffer) {
if (pend->buffer_ref.buffer) {
struct weston_buffer *buf = pend->buffer_ref.buffer;
convert_size_by_transform_scale(&width_from_buffer,
&height_from_buffer,
pend->buffer->width,
pend->buffer->height,
buf->width,
buf->height,
vp->buffer.transform,
vp->buffer.scale);
} else {
@ -4697,7 +4700,7 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
if (surface->pending.acquire_fence_fd >= 0) {
assert(surface->synchronization_resource);
if (!surface->pending.buffer) {
if (!surface->pending.buffer_ref.buffer) {
fd_clear(&surface->pending.acquire_fence_fd);
wl_resource_post_error(surface->synchronization_resource,
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_BUFFER,
@ -4706,7 +4709,7 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
return;
}
if (surface->pending.buffer->type == WESTON_BUFFER_SHM) {
if (surface->pending.buffer_ref.buffer->type == WESTON_BUFFER_SHM) {
fd_clear(&surface->pending.acquire_fence_fd);
wl_resource_post_error(surface->synchronization_resource,
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_UNSUPPORTED_BUFFER,
@ -4717,7 +4720,7 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
}
if (surface->pending.buffer_release_ref.buffer_release &&
!surface->pending.buffer) {
!surface->pending.buffer_ref.buffer) {
assert(surface->synchronization_resource);
wl_resource_post_error(surface->synchronization_resource,
@ -5395,8 +5398,6 @@ weston_subsurface_destroy(struct weston_subsurface *sub)
weston_subsurface_unlink_parent(sub);
weston_surface_state_fini(&sub->cached);
weston_buffer_reference(&sub->cached_buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
sub->surface->committed = NULL;
sub->surface->committed_private = NULL;
@ -5447,7 +5448,6 @@ weston_subsurface_create(uint32_t id, struct weston_surface *surface,
weston_subsurface_link_surface(sub, surface);
weston_subsurface_link_parent(sub, parent);
weston_surface_state_init(surface, &sub->cached);
sub->cached_buffer_ref.buffer = NULL;
sub->synchronized = true;
sub->effectively_synchronized = true;

View file

@ -744,10 +744,6 @@ region_init_infinite(pixman_region32_t *region)
UINT32_MAX, UINT32_MAX);
}
void
weston_surface_state_set_buffer(struct weston_surface_state *state,
struct weston_buffer *buffer);
struct weston_subsurface *
weston_surface_to_subsurface(struct weston_surface *surface);

View file

@ -54,24 +54,12 @@ weston_surface_dirty_paint_nodes(struct weston_surface *surface,
}
}
static void
surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
{
struct weston_surface_state *state =
container_of(listener, struct weston_surface_state,
buffer_destroy_listener);
state->buffer = NULL;
}
void
weston_surface_state_init(struct weston_surface *surface,
struct weston_surface_state *state)
{
state->status = WESTON_SURFACE_CLEAN;
state->buffer = NULL;
state->buffer_destroy_listener.notify =
surface_state_handle_buffer_destroy;
state->buffer_ref.buffer = NULL;
state->buf_offset = weston_coord_surface(0, 0, surface);
pixman_region32_init(&state->damage_surface);
@ -111,9 +99,8 @@ weston_surface_state_fini(struct weston_surface_state *state)
pixman_region32_fini(&state->damage_surface);
pixman_region32_fini(&state->damage_buffer);
if (state->buffer)
wl_list_remove(&state->buffer_destroy_listener.link);
state->buffer = NULL;
weston_buffer_reference(&state->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
fd_clear(&state->acquire_fence_fd);
weston_buffer_release_reference(&state->buffer_release_ref, NULL);
@ -123,28 +110,13 @@ weston_surface_state_fini(struct weston_surface_state *state)
state->render_intent = NULL;
}
void
weston_surface_state_set_buffer(struct weston_surface_state *state,
struct weston_buffer *buffer)
{
if (state->buffer == buffer)
return;
if (state->buffer)
wl_list_remove(&state->buffer_destroy_listener.link);
state->buffer = buffer;
if (state->buffer)
wl_signal_add(&state->buffer->destroy_signal,
&state->buffer_destroy_listener);
}
static enum weston_surface_status
weston_surface_attach(struct weston_surface *surface,
struct weston_surface_state *state,
enum weston_surface_status status)
{
WESTON_TRACE_FUNC_FLOW(&surface->flow_id);
struct weston_buffer *buffer = state->buffer;
struct weston_buffer *buffer = state->buffer_ref.buffer;
struct weston_buffer *old_buffer = surface->buffer_ref.buffer;
if (!buffer) {
@ -316,7 +288,8 @@ weston_surface_apply_state(struct weston_surface *surface,
status |= weston_surface_attach(surface, state, status);
}
weston_surface_state_set_buffer(state, NULL);
weston_buffer_reference(&state->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
assert(state->acquire_fence_fd == -1);
assert(state->buffer_release_ref.buffer_release == NULL);
@ -427,8 +400,6 @@ weston_subsurface_apply_from_cache(struct weston_subsurface *sub)
enum weston_surface_status status;
status = weston_surface_apply(surface, &sub->cached);
weston_buffer_reference(&sub->cached_buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
return status;
}
@ -479,7 +450,6 @@ weston_surface_apply(struct weston_surface *surface,
static void
weston_surface_state_merge_from(struct weston_surface_state *dst,
struct weston_surface_state *src,
struct weston_buffer_reference *buffer_ref,
struct weston_surface *surface)
{
WESTON_TRACE_FUNC();
@ -511,11 +481,9 @@ weston_surface_state_merge_from(struct weston_surface_state *dst,
weston_color_profile_ref(src->color_profile);
if (src->status & WESTON_SURFACE_DIRTY_BUFFER) {
weston_surface_state_set_buffer(dst,
src->buffer);
weston_buffer_reference(buffer_ref,
src->buffer,
src->buffer ?
weston_buffer_reference(&dst->buffer_ref,
src->buffer_ref.buffer,
src->buffer_ref.buffer ?
BUFFER_MAY_BE_ACCESSED :
BUFFER_WILL_NOT_BE_ACCESSED);
weston_presentation_feedback_discard_list(
@ -537,7 +505,8 @@ weston_surface_state_merge_from(struct weston_surface_state *dst,
dst->buffer_viewport.buffer = src->buffer_viewport.buffer;
dst->buffer_viewport.surface = src->buffer_viewport.surface;
weston_surface_state_set_buffer(&surface->pending, NULL);
weston_buffer_reference(&src->buffer_ref,
NULL, BUFFER_WILL_NOT_BE_ACCESSED);
src->buf_offset = weston_coord_surface(0, 0, surface);
@ -564,7 +533,6 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
weston_surface_state_merge_from(&sub->cached,
&surface->pending,
&sub->cached_buffer_ref,
surface);
}