mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-14 08:22:25 -04:00
output-layers: change semantics of wlr_output_state.layers
Previously, we were requiring all layers to be included in wlr_output_state.layers and wlr_output_layer_state.buffer to be set to NULL to disable a layer. This commit changes these semantics: disabled layers are left out of wlr_output_state.layers, and wlr_output_layer_state.buffer is required to be non-NULL. This new API should make it easier for callers to populate the layers, at the cost of some additional complexity in backends, mostly addressed by introducing a new wlr_output_state_is_layer_enabled() helper.
This commit is contained in:
parent
f42920c414
commit
b931ac9ac0
8 changed files with 120 additions and 71 deletions
|
|
@ -498,29 +498,29 @@ static bool output_test(struct wlr_output *wlr_output,
|
|||
bool supported = output->backend->subcompositor != NULL;
|
||||
for (ssize_t i = state->layers_len - 1; i >= 0; i--) {
|
||||
struct wlr_output_layer_state *layer_state = &state->layers[i];
|
||||
if (layer_state->buffer != NULL) {
|
||||
int x = layer_state->dst_box.x;
|
||||
int y = layer_state->dst_box.y;
|
||||
int width = layer_state->dst_box.width;
|
||||
int height = layer_state->dst_box.height;
|
||||
bool needs_viewport = width != layer_state->buffer->width ||
|
||||
height != layer_state->buffer->height;
|
||||
if (!wlr_fbox_empty(&layer_state->src_box)) {
|
||||
needs_viewport = needs_viewport ||
|
||||
layer_state->src_box.x != 0 ||
|
||||
layer_state->src_box.y != 0 ||
|
||||
layer_state->src_box.width != width ||
|
||||
layer_state->src_box.height != height;
|
||||
}
|
||||
if (x < 0 || y < 0 ||
|
||||
x + width > wlr_output->width ||
|
||||
y + height > wlr_output->height ||
|
||||
(output->backend->viewporter == NULL && needs_viewport)) {
|
||||
supported = false;
|
||||
}
|
||||
supported = supported &&
|
||||
test_buffer(output->backend, layer_state->buffer);
|
||||
|
||||
int x = layer_state->dst_box.x;
|
||||
int y = layer_state->dst_box.y;
|
||||
int width = layer_state->dst_box.width;
|
||||
int height = layer_state->dst_box.height;
|
||||
bool needs_viewport = width != layer_state->buffer->width ||
|
||||
height != layer_state->buffer->height;
|
||||
if (!wlr_fbox_empty(&layer_state->src_box)) {
|
||||
needs_viewport = needs_viewport ||
|
||||
layer_state->src_box.x != 0 ||
|
||||
layer_state->src_box.y != 0 ||
|
||||
layer_state->src_box.width != width ||
|
||||
layer_state->src_box.height != height;
|
||||
}
|
||||
if (x < 0 || y < 0 ||
|
||||
x + width > wlr_output->width ||
|
||||
y + height > wlr_output->height ||
|
||||
(output->backend->viewporter == NULL && needs_viewport)) {
|
||||
supported = false;
|
||||
}
|
||||
supported = supported &&
|
||||
test_buffer(output->backend, layer_state->buffer);
|
||||
|
||||
layer_state->accepted = supported;
|
||||
}
|
||||
}
|
||||
|
|
@ -584,19 +584,23 @@ static struct wlr_wl_output_layer *get_or_create_output_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) {
|
||||
// Iterate over all enabled layers, check whether the list of all existing
|
||||
// layers has the same ordering
|
||||
struct wl_list *cur = output->wlr_output.layers.next;
|
||||
for (size_t i = 0; i < layers_len; i++) {
|
||||
bool found = false;
|
||||
while (cur != &output->wlr_output.layers) {
|
||||
struct wlr_output_layer *layer = wl_container_of(cur, layer, link);
|
||||
if (layer == layers[i].layer) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
if (!found) {
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
assert(i == layers_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -635,11 +639,6 @@ static bool output_layer_commit(struct wlr_wl_output *output,
|
|||
wl_subsurface_set_position(layer->subsurface, state->dst_box.x, state->dst_box.y);
|
||||
}
|
||||
|
||||
if (state->buffer == NULL) {
|
||||
output_layer_unmap(layer);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct wlr_wl_buffer *buffer =
|
||||
get_or_create_wl_buffer(output->backend, state->buffer);
|
||||
if (buffer == NULL) {
|
||||
|
|
@ -677,22 +676,23 @@ static bool output_layer_commit(struct wlr_wl_output *output,
|
|||
}
|
||||
|
||||
static bool commit_layers(struct wlr_wl_output *output,
|
||||
struct wlr_output_layer_state *layers, size_t layers_len) {
|
||||
if (output->backend->subcompositor == NULL) {
|
||||
const struct wlr_output_state *state) {
|
||||
if (!(state->committed & WLR_OUTPUT_STATE_LAYERS) ||
|
||||
output->backend->subcompositor == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reordered = has_layers_order_changed(output, layers, layers_len);
|
||||
bool reordered = has_layers_order_changed(output, state->layers, state->layers_len);
|
||||
|
||||
struct wlr_wl_output_layer *prev_layer = NULL;
|
||||
for (size_t i = 0; i < layers_len; i++) {
|
||||
for (size_t i = 0; i < state->layers_len; i++) {
|
||||
struct wlr_wl_output_layer *layer =
|
||||
get_or_create_output_layer(output, layers[i].layer);
|
||||
get_or_create_output_layer(output, state->layers[i].layer);
|
||||
if (layer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!layers[i].accepted) {
|
||||
if (!state->layers[i].accepted) {
|
||||
output_layer_unmap(layer);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -702,13 +702,25 @@ static bool commit_layers(struct wlr_wl_output *output,
|
|||
prev_layer->surface);
|
||||
}
|
||||
|
||||
if (!output_layer_commit(output, layer, &layers[i])) {
|
||||
if (!output_layer_commit(output, layer, &state->layers[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
prev_layer = layer;
|
||||
}
|
||||
|
||||
struct wlr_output_layer *wlr_layer;
|
||||
wl_list_for_each(wlr_layer, &output->wlr_output.layers, link) {
|
||||
if (wlr_output_state_is_layer_enabled(state, wlr_layer)) {
|
||||
continue;
|
||||
}
|
||||
struct wlr_wl_output_layer *layer =
|
||||
get_or_create_output_layer(output, wlr_layer);
|
||||
if (layer != NULL) {
|
||||
output_layer_unmap(layer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -851,8 +863,7 @@ static bool output_commit(struct wlr_output *wlr_output, const struct wlr_output
|
|||
}
|
||||
}
|
||||
|
||||
if ((state->committed & WLR_OUTPUT_STATE_LAYERS) &&
|
||||
!commit_layers(output, state->layers, state->layers_len)) {
|
||||
if (!commit_layers(output, state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue