Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use backend commits for wlr-output-management-unstable-v1 #7986

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/sway/config.h
Expand Up @@ -684,7 +684,8 @@ void merge_output_config(struct output_config *dst, struct output_config *src);

bool apply_output_config(struct output_config *oc, struct sway_output *output);

bool test_output_config(struct output_config *oc, struct sway_output *output);
void queue_output_config(struct output_config *oc,
struct sway_output *output, struct wlr_output_state *pending);

struct output_config *store_output_config(struct output_config *oc);

Expand Down
13 changes: 2 additions & 11 deletions sway/config/output.c
Expand Up @@ -384,7 +384,7 @@ static const uint32_t *bit_depth_preferences[] = {
},
};

static void queue_output_config(struct output_config *oc,
void queue_output_config(struct output_config *oc,
struct sway_output *output, struct wlr_output_state *pending) {
if (output == root->fallback_output) {
return;
Expand Down Expand Up @@ -515,6 +515,7 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
output->enabling = (!oc || oc->enabled);

struct wlr_output_state pending = {0};
wlr_output_state_init(&pending, output->wlr_output);
queue_output_config(oc, output, &pending);

sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
Expand Down Expand Up @@ -593,16 +594,6 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
return true;
}

bool test_output_config(struct output_config *oc, struct sway_output *output) {
if (output == root->fallback_output) {
return false;
}

struct wlr_output_state pending = {0};
queue_output_config(oc, output, &pending);
return wlr_output_test_state(output->wlr_output, &pending);
}

static void default_output_config(struct output_config *oc,
struct wlr_output *wlr_output) {
oc->enabled = 1;
Expand Down
108 changes: 60 additions & 48 deletions sway/desktop/output.c
Expand Up @@ -238,7 +238,7 @@ static int output_repaint_timer_handler(void *data) {

if (output->gamma_lut_changed) {
struct wlr_output_state pending;
wlr_output_state_init(&pending);
wlr_output_state_init(&pending, output->wlr_output);
if (!wlr_scene_output_build_state(output->scene_output, &pending, NULL)) {
return 0;
}
Expand Down Expand Up @@ -545,74 +545,86 @@ void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
wlr_output_schedule_frame(output->wlr_output);
}

static struct output_config *output_manager_create_config(struct sway_output *output,
struct wlr_output_configuration_head_v1 *config_head) {
sway_assert(output != root->fallback_output, "Tried configuring fallback output");

struct output_config *oc = new_output_config(output->wlr_output->name);
oc->enabled = config_head->state.enabled;
if (!oc->enabled) {
return oc;
}

if (config_head->state.mode != NULL) {
struct wlr_output_mode *mode = config_head->state.mode;
oc->width = mode->width;
oc->height = mode->height;
oc->refresh_rate = mode->refresh / 1000.f;
} else {
oc->width = config_head->state.custom_mode.width;
oc->height = config_head->state.custom_mode.height;
oc->refresh_rate =
config_head->state.custom_mode.refresh / 1000.f;
}
oc->x = config_head->state.x;
oc->y = config_head->state.y;
oc->transform = config_head->state.transform;
oc->scale = config_head->state.scale;
oc->adaptive_sync = config_head->state.adaptive_sync_enabled;

return oc;
}

static void output_manager_apply(struct sway_server *server,
struct wlr_output_configuration_v1 *config, bool test_only) {
// TODO: perform atomic tests on the whole backend atomically

size_t states_len = wl_list_length(&config->heads);
struct wlr_output_state *states = calloc(states_len, sizeof(states[0]));
struct output_config **configs = calloc(states_len, sizeof(configs[0]));

size_t i = 0;
struct wlr_output_configuration_head_v1 *config_head;
// First disable outputs we need to disable
bool ok = true;
wl_list_for_each(config_head, &config->heads, link) {
struct wlr_output *wlr_output = config_head->state.output;
struct sway_output *output = wlr_output->data;
if (!output->enabled || config_head->state.enabled) {
continue;
}
struct output_config *oc = new_output_config(output->wlr_output->name);
oc->enabled = false;

if (test_only) {
ok &= test_output_config(oc, output);
} else {
oc = store_output_config(oc);
ok &= apply_output_config(oc, output);
}
struct output_config *oc = output_manager_create_config(output, config_head);
queue_output_config(oc, output, &states[i]);
// TODO: populate buffer if output is enabled
configs[i] = oc;
i++;
}

// Then enable outputs that need to
wl_list_for_each(config_head, &config->heads, link) {
struct wlr_output *wlr_output = config_head->state.output;
struct sway_output *output = wlr_output->data;
if (!config_head->state.enabled) {
continue;
}
struct output_config *oc = new_output_config(output->wlr_output->name);
oc->enabled = true;
if (config_head->state.mode != NULL) {
struct wlr_output_mode *mode = config_head->state.mode;
oc->width = mode->width;
oc->height = mode->height;
oc->refresh_rate = mode->refresh / 1000.f;
} else {
oc->width = config_head->state.custom_mode.width;
oc->height = config_head->state.custom_mode.height;
oc->refresh_rate =
config_head->state.custom_mode.refresh / 1000.f;
}
oc->x = config_head->state.x;
oc->y = config_head->state.y;
oc->transform = config_head->state.transform;
oc->scale = config_head->state.scale;
oc->adaptive_sync = config_head->state.adaptive_sync_enabled;

if (test_only) {
ok &= test_output_config(oc, output);
} else {
oc = store_output_config(oc);
ok &= apply_output_config(oc, output);
}
bool ok = wlr_backend_test(server->backend, states, states_len);
if (!ok || test_only) {
goto out;
}

ok = wlr_backend_commit(server->backend, states, states_len);

out:
if (ok) {
wlr_output_configuration_v1_send_succeeded(config);
} else {
wlr_output_configuration_v1_send_failed(config);
}
wlr_output_configuration_v1_destroy(config);

if (!test_only) {
if (ok && !test_only) {
for (size_t i = 0; i < states_len; i++) {
struct output_config *oc = store_output_config(configs[i]);
apply_output_config(oc, states[i].output->data);
}

update_output_manager_config(server);
}

for (size_t i = 0; i < states_len; i++) {
wlr_output_state_finish(&states[i]);
}
free(states);

free(configs);
}

void handle_output_manager_apply(struct wl_listener *listener, void *data) {
Expand Down