From 27cf4f4baad09e7b626445c7e1d36b24cfa678e6 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Thu, 20 Jul 2023 00:25:27 -0400 Subject: [PATCH] backend/wayland: Linearly allocate output layers Instaed of tracking the allocated wayland surface as part of the output layer, just allocate them linearly. If this is acceptable and the drm backend is also changed, we can get rid of wlr_output.layers and wlr_output_layer completely. --- backend/wayland/output.c | 81 +++++++++++++++------------------------ include/backend/wayland.h | 4 +- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 18502ec9e..d8ae63a90 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -322,10 +322,8 @@ static bool output_test(struct wlr_output *wlr_output, return true; } -static void output_layer_handle_addon_destroy(struct wlr_addon *addon) { - struct wlr_wl_output_layer *layer = wl_container_of(addon, layer, addon); - - wlr_addon_finish(&layer->addon); +static void output_layer_destroy(struct wlr_wl_output_layer *layer) { + wl_list_remove(&layer->link); if (layer->viewport != NULL) { wp_viewport_destroy(layer->viewport); } @@ -334,30 +332,15 @@ static void output_layer_handle_addon_destroy(struct wlr_addon *addon) { free(layer); } -static const struct wlr_addon_interface output_layer_addon_impl = { - .name = "wlr_wl_output_layer", - .destroy = output_layer_handle_addon_destroy, -}; - -static struct wlr_wl_output_layer *get_or_create_output_layer( - struct wlr_wl_output *output, struct wlr_output_layer *wlr_layer) { +static struct wlr_wl_output_layer *output_layer_create(struct wlr_wl_output *output) { assert(output->backend->subcompositor != NULL); - struct wlr_wl_output_layer *layer; - struct wlr_addon *addon = wlr_addon_find(&wlr_layer->addons, output, - &output_layer_addon_impl); - if (addon != NULL) { - layer = wl_container_of(addon, layer, addon); - return layer; - } - - layer = calloc(1, sizeof(*layer)); + struct wlr_wl_output_layer *layer = calloc(1, sizeof(*layer)); if (layer == NULL) { return NULL; } - wlr_addon_init(&layer->addon, &wlr_layer->addons, output, - &output_layer_addon_impl); + wl_list_insert(&output->layers, &layer->link); layer->surface = wl_compositor_create_surface(output->backend->compositor); layer->subsurface = wl_subcompositor_get_subsurface( @@ -376,24 +359,6 @@ static struct wlr_wl_output_layer *get_or_create_output_layer( return layer; } -static bool has_layers_order_changed(struct wlr_wl_output *output, - struct wlr_output_layer_state *layers, size_t layers_len) { - // output_basic_check() ensures that layers_len equals the number of - // registered output layers - size_t i = 0; - struct wlr_output_layer *layer; - wl_list_for_each(layer, &output->wlr_output.layers, link) { - assert(i < layers_len); - const struct wlr_output_layer_state *layer_state = &layers[i]; - if (layer_state->layer != layer) { - return true; - } - i++; - } - assert(i == layers_len); - return false; -} - static void output_layer_unmap(struct wlr_wl_output_layer *layer) { if (!layer->mapped) { return; @@ -476,14 +441,19 @@ static bool commit_layers(struct wlr_wl_output *output, return true; } - bool reordered = has_layers_order_changed(output, layers, layers_len); + struct wl_list *current_layer = output->layers.next; - struct wlr_wl_output_layer *prev_layer = NULL; for (size_t i = 0; i < layers_len; i++) { - struct wlr_wl_output_layer *layer = - get_or_create_output_layer(output, layers[i].layer); - if (layer == NULL) { - return false; + struct wlr_wl_output_layer *layer; + + if (current_layer == &output->layers) { + layer = output_layer_create(output); + if (layer == NULL) { + return false; + } + } else { + current_layer = current_layer->next; + layer = wl_container_of(current_layer, layer, link); } if (!layers[i].accepted) { @@ -491,16 +461,19 @@ static bool commit_layers(struct wlr_wl_output *output, continue; } - if (prev_layer != NULL && reordered) { - wl_subsurface_place_above(layer->subsurface, - prev_layer->surface); - } - if (!output_layer_commit(output, layer, &layers[i])) { return false; } } + // destroy unused subsurface + while (current_layer != &output->layers) { + struct wlr_wl_output_layer *layer = + wl_container_of(current_layer, layer, link); + current_layer = current_layer->next; + output_layer_destroy(layer); + } + return true; } @@ -636,6 +609,11 @@ static void output_destroy(struct wlr_output *wlr_output) { wl_list_remove(&output->link); + struct wlr_wl_output_layer *layer, *tmp_layer; + wl_list_for_each_safe(layer, tmp_layer, &output->layers, link) { + output_layer_destroy(layer); + } + if (output->cursor.surface) { wl_surface_destroy(output->cursor.surface); } @@ -768,6 +746,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *wlr_backend) { output->backend = backend; wl_list_init(&output->presentation_feedbacks); + wl_list_init(&output->layers); output->surface = wl_compositor_create_surface(backend->compositor); if (!output->surface) { diff --git a/include/backend/wayland.h b/include/backend/wayland.h index fd0564030..bcbaa66a6 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -68,7 +68,7 @@ struct wlr_wl_presentation_feedback { }; struct wlr_wl_output_layer { - struct wlr_addon addon; + struct wl_list link; // struct wlr_wl_output.layers struct wl_surface *surface; struct wl_subsurface *subsurface; @@ -96,6 +96,8 @@ struct wlr_wl_output { struct wl_surface *surface; int32_t hotspot_x, hotspot_y; } cursor; + + struct wl_list layers; // struct wlr_wl_output_layer.link }; struct wlr_wl_pointer {