diff options
| author | Simon Ser <contact@emersion.fr> | 2022-05-24 20:42:29 +0200 | 
|---|---|---|
| committer | Simon Ser <contact@emersion.fr> | 2022-05-30 11:40:34 +0200 | 
| commit | d483dd2f4caeeab97de97c4e8215f084945de63c (patch) | |
| tree | a1f861191ddd29679eed8dbf2ba474cc3e784142 | |
| parent | 501ac5398d6f9a85dfdeeb9bf60a342bcff35adc (diff) | |
| download | wlroots-d483dd2f4caeeab97de97c4e8215f084945de63c.tar.xz | |
output: add wlr_output_commit_state
Same as wlr_output_commit, but takes a wlr_output_state.
| -rw-r--r-- | include/wlr/types/wlr_output.h | 2 | ||||
| -rw-r--r-- | types/output/output.c | 65 | 
2 files changed, 41 insertions, 26 deletions
| diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 05275156..68f85ebb 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -428,6 +428,8 @@ bool wlr_output_commit(struct wlr_output *output);  void wlr_output_rollback(struct wlr_output *output);  bool wlr_output_test_state(struct wlr_output *output,  	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,   * it is a no-op. diff --git a/types/output/output.c b/types/output/output.c index cdfb48ff..6bcb2b87 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -397,6 +397,12 @@ static void output_state_finish(struct wlr_output_state *state) {  	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,  		const struct wlr_output_impl *impl, struct wl_display *display) {  	assert(impl->commit); @@ -673,7 +679,7 @@ bool wlr_output_test_state(struct wlr_output *output,  		const struct wlr_output_state *state) {  	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;  	if (!output_basic_test(output, &pending)) {  		return false; @@ -696,17 +702,20 @@ bool wlr_output_test(struct wlr_output *output) {  	return wlr_output_test_state(output, &output->pending);  } -bool wlr_output_commit(struct wlr_output *output) { -	if (!output_basic_test(output, &output->pending)) { +bool wlr_output_commit_state(struct wlr_output *output, +		const struct wlr_output_state *state) { +	if (!output_basic_test(output, state)) {  		wlr_log(WLR_ERROR, "Basic output test failed for %s", output->name);  		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;  	} -	if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) && +	if ((pending.committed & WLR_OUTPUT_STATE_BUFFER) &&  			output->idle_frame != NULL) {  		wl_event_source_remove(output->idle_frame);  		output->idle_frame = NULL; @@ -718,7 +727,7 @@ bool wlr_output_commit(struct wlr_output *output) {  	struct wlr_output_event_precommit pre_event = {  		.output = output,  		.when = &now, -		.state = &output->pending, +		.state = &pending,  	};  	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  	// displaying a buffer when asynchronous GPU work isn't finished.  	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) {  		back_buffer = wlr_buffer_lock(output->back_buffer);  		output_clear_back_buffer(output);  	} -	if (!output->impl->commit(output, &output->pending)) { +	if (!output->impl->commit(output, &pending)) {  		wlr_buffer_unlock(back_buffer); -		output_state_clear(&output->pending);  		return false;  	} -	if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) { +	if (pending.committed & WLR_OUTPUT_STATE_BUFFER) {  		struct wlr_output_cursor *cursor;  		wl_list_for_each(cursor, &output->cursors, link) {  			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) { -		output->render_format = output->pending.render_format; +	if (pending.committed & WLR_OUTPUT_STATE_RENDER_FORMAT) { +		output->render_format = pending.render_format;  	} -	if (output->pending.committed & WLR_OUTPUT_STATE_SUBPIXEL) { -		output->subpixel = output->pending.subpixel; +	if (pending.committed & WLR_OUTPUT_STATE_SUBPIXEL) { +		output->subpixel = pending.subpixel;  	}  	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) { -		output->scale = output->pending.scale; +		output->scale = pending.scale;  	} -	if (output->pending.committed & WLR_OUTPUT_STATE_TRANSFORM) { -		output->transform = output->pending.transform; +	if (pending.committed & WLR_OUTPUT_STATE_TRANSFORM) { +		output->transform = pending.transform;  		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_SUBPIXEL);  	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 -	if ((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) && -			!output->pending.enabled) { +	if ((pending.committed & WLR_OUTPUT_STATE_ENABLED) && !pending.enabled) {  		wlr_swapchain_destroy(output->swapchain);  		output->swapchain = NULL;  		wlr_swapchain_destroy(output->cursor_swapchain);  		output->cursor_swapchain = NULL;  	} -	if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) { +	if (pending.committed & WLR_OUTPUT_STATE_BUFFER) {  		output->frame_pending = true;  		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);  	} -	uint32_t committed = output->pending.committed; -	output_state_clear(&output->pending); -  	struct wlr_output_event_commit event = {  		.output = output, -		.committed = committed, +		.committed = pending.committed,  		.when = &now,  		.buffer = back_buffer,  	}; @@ -821,6 +825,15 @@ bool wlr_output_commit(struct wlr_output *output) {  	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) {  	output_clear_back_buffer(output);  	output_state_clear(&output->pending); | 
