mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-02 03:45:58 +01:00
output: add wlr_output_commit_state
Same as wlr_output_commit, but takes a wlr_output_state.
This commit is contained in:
parent
501ac5398d
commit
d483dd2f4c
2 changed files with 41 additions and 26 deletions
|
@ -428,6 +428,8 @@ bool wlr_output_commit(struct wlr_output *output);
|
||||||
void wlr_output_rollback(struct wlr_output *output);
|
void wlr_output_rollback(struct wlr_output *output);
|
||||||
bool wlr_output_test_state(struct wlr_output *output,
|
bool wlr_output_test_state(struct wlr_output *output,
|
||||||
const struct wlr_output_state *state);
|
const struct wlr_output_state *state);
|
||||||
|
bool wlr_output_commit_state(struct wlr_output *output,
|
||||||
|
const struct wlr_output_state *state);
|
||||||
/**
|
/**
|
||||||
* Manually schedules a `frame` event. If a `frame` event is already pending,
|
* Manually schedules a `frame` event. If a `frame` event is already pending,
|
||||||
* it is a no-op.
|
* it is a no-op.
|
||||||
|
|
|
@ -397,6 +397,12 @@ static void output_state_finish(struct wlr_output_state *state) {
|
||||||
free(state->gamma_lut);
|
free(state->gamma_lut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void output_state_move(struct wlr_output_state *dst,
|
||||||
|
struct wlr_output_state *src) {
|
||||||
|
*dst = *src;
|
||||||
|
output_state_init(src);
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
||||||
const struct wlr_output_impl *impl, struct wl_display *display) {
|
const struct wlr_output_impl *impl, struct wl_display *display) {
|
||||||
assert(impl->commit);
|
assert(impl->commit);
|
||||||
|
@ -673,7 +679,7 @@ bool wlr_output_test_state(struct wlr_output *output,
|
||||||
const struct wlr_output_state *state) {
|
const struct wlr_output_state *state) {
|
||||||
bool had_buffer = state->committed & WLR_OUTPUT_STATE_BUFFER;
|
bool had_buffer = state->committed & WLR_OUTPUT_STATE_BUFFER;
|
||||||
|
|
||||||
// Duplicate the satte because we might mutate it in output_ensure_buffer
|
// Duplicate the state because we might mutate it in output_ensure_buffer
|
||||||
struct wlr_output_state pending = *state;
|
struct wlr_output_state pending = *state;
|
||||||
if (!output_basic_test(output, &pending)) {
|
if (!output_basic_test(output, &pending)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -696,17 +702,20 @@ bool wlr_output_test(struct wlr_output *output) {
|
||||||
return wlr_output_test_state(output, &output->pending);
|
return wlr_output_test_state(output, &output->pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_output_commit(struct wlr_output *output) {
|
bool wlr_output_commit_state(struct wlr_output *output,
|
||||||
if (!output_basic_test(output, &output->pending)) {
|
const struct wlr_output_state *state) {
|
||||||
|
if (!output_basic_test(output, state)) {
|
||||||
wlr_log(WLR_ERROR, "Basic output test failed for %s", output->name);
|
wlr_log(WLR_ERROR, "Basic output test failed for %s", output->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output_ensure_buffer(output, &output->pending)) {
|
// Duplicate the state because we might mutate it in output_ensure_buffer
|
||||||
|
struct wlr_output_state pending = *state;
|
||||||
|
if (!output_ensure_buffer(output, &pending)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
|
if ((pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
|
||||||
output->idle_frame != NULL) {
|
output->idle_frame != NULL) {
|
||||||
wl_event_source_remove(output->idle_frame);
|
wl_event_source_remove(output->idle_frame);
|
||||||
output->idle_frame = NULL;
|
output->idle_frame = NULL;
|
||||||
|
@ -718,7 +727,7 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
struct wlr_output_event_precommit pre_event = {
|
struct wlr_output_event_precommit pre_event = {
|
||||||
.output = output,
|
.output = output,
|
||||||
.when = &now,
|
.when = &now,
|
||||||
.state = &output->pending,
|
.state = &pending,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->events.precommit, &pre_event);
|
wlr_signal_emit_safe(&output->events.precommit, &pre_event);
|
||||||
|
|
||||||
|
@ -727,19 +736,18 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
// implicit rendering synchronization point. The backend needs it to avoid
|
// implicit rendering synchronization point. The backend needs it to avoid
|
||||||
// displaying a buffer when asynchronous GPU work isn't finished.
|
// displaying a buffer when asynchronous GPU work isn't finished.
|
||||||
struct wlr_buffer *back_buffer = NULL;
|
struct wlr_buffer *back_buffer = NULL;
|
||||||
if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
|
if ((pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
|
||||||
output->back_buffer != NULL) {
|
output->back_buffer != NULL) {
|
||||||
back_buffer = wlr_buffer_lock(output->back_buffer);
|
back_buffer = wlr_buffer_lock(output->back_buffer);
|
||||||
output_clear_back_buffer(output);
|
output_clear_back_buffer(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output->impl->commit(output, &output->pending)) {
|
if (!output->impl->commit(output, &pending)) {
|
||||||
wlr_buffer_unlock(back_buffer);
|
wlr_buffer_unlock(back_buffer);
|
||||||
output_state_clear(&output->pending);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
if (pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
struct wlr_output_cursor *cursor;
|
struct wlr_output_cursor *cursor;
|
||||||
wl_list_for_each(cursor, &output->cursors, link) {
|
wl_list_for_each(cursor, &output->cursors, link) {
|
||||||
if (!cursor->enabled || !cursor->visible || cursor->surface == NULL) {
|
if (!cursor->enabled || !cursor->visible || cursor->surface == NULL) {
|
||||||
|
@ -749,27 +757,27 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
if (pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
||||||
output->render_format = output->pending.render_format;
|
output->render_format = pending.render_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->pending.committed & WLR_OUTPUT_STATE_SUBPIXEL) {
|
if (pending.committed & WLR_OUTPUT_STATE_SUBPIXEL) {
|
||||||
output->subpixel = output->pending.subpixel;
|
output->subpixel = pending.subpixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->commit_seq++;
|
output->commit_seq++;
|
||||||
|
|
||||||
bool scale_updated = output->pending.committed & WLR_OUTPUT_STATE_SCALE;
|
bool scale_updated = pending.committed & WLR_OUTPUT_STATE_SCALE;
|
||||||
if (scale_updated) {
|
if (scale_updated) {
|
||||||
output->scale = output->pending.scale;
|
output->scale = pending.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->pending.committed & WLR_OUTPUT_STATE_TRANSFORM) {
|
if (pending.committed & WLR_OUTPUT_STATE_TRANSFORM) {
|
||||||
output->transform = output->pending.transform;
|
output->transform = pending.transform;
|
||||||
output_update_matrix(output);
|
output_update_matrix(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool geometry_updated = output->pending.committed &
|
bool geometry_updated = pending.committed &
|
||||||
(WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_TRANSFORM |
|
(WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_TRANSFORM |
|
||||||
WLR_OUTPUT_STATE_SUBPIXEL);
|
WLR_OUTPUT_STATE_SUBPIXEL);
|
||||||
if (geometry_updated || scale_updated) {
|
if (geometry_updated || scale_updated) {
|
||||||
|
@ -786,15 +794,14 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the swapchains when an output is disabled
|
// Destroy the swapchains when an output is disabled
|
||||||
if ((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) &&
|
if ((pending.committed & WLR_OUTPUT_STATE_ENABLED) && !pending.enabled) {
|
||||||
!output->pending.enabled) {
|
|
||||||
wlr_swapchain_destroy(output->swapchain);
|
wlr_swapchain_destroy(output->swapchain);
|
||||||
output->swapchain = NULL;
|
output->swapchain = NULL;
|
||||||
wlr_swapchain_destroy(output->cursor_swapchain);
|
wlr_swapchain_destroy(output->cursor_swapchain);
|
||||||
output->cursor_swapchain = NULL;
|
output->cursor_swapchain = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
if (pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
output->frame_pending = true;
|
output->frame_pending = true;
|
||||||
output->needs_frame = false;
|
output->needs_frame = false;
|
||||||
}
|
}
|
||||||
|
@ -803,12 +810,9 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
wlr_swapchain_set_buffer_submitted(output->swapchain, back_buffer);
|
wlr_swapchain_set_buffer_submitted(output->swapchain, back_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t committed = output->pending.committed;
|
|
||||||
output_state_clear(&output->pending);
|
|
||||||
|
|
||||||
struct wlr_output_event_commit event = {
|
struct wlr_output_event_commit event = {
|
||||||
.output = output,
|
.output = output,
|
||||||
.committed = committed,
|
.committed = pending.committed,
|
||||||
.when = &now,
|
.when = &now,
|
||||||
.buffer = back_buffer,
|
.buffer = back_buffer,
|
||||||
};
|
};
|
||||||
|
@ -821,6 +825,15 @@ bool wlr_output_commit(struct wlr_output *output) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wlr_output_commit(struct wlr_output *output) {
|
||||||
|
// Make sure the pending state is cleared before the output is committed
|
||||||
|
struct wlr_output_state state = {0};
|
||||||
|
output_state_move(&state, &output->pending);
|
||||||
|
bool ok = wlr_output_commit_state(output, &state);
|
||||||
|
output_state_finish(&state);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_output_rollback(struct wlr_output *output) {
|
void wlr_output_rollback(struct wlr_output *output) {
|
||||||
output_clear_back_buffer(output);
|
output_clear_back_buffer(output);
|
||||||
output_state_clear(&output->pending);
|
output_state_clear(&output->pending);
|
||||||
|
|
Loading…
Reference in a new issue