mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	desktop/output: use detached output state for page-flips
This avoids relying on the implicit wlr_output.pending state.
This commit is contained in:
		
							parent
							
								
									b1b3563d54
								
							
						
					
					
						commit
						f3b8c9feee
					
				
					 1 changed files with 26 additions and 22 deletions
				
			
		| 
						 | 
					@ -458,7 +458,7 @@ static void count_surface_iterator(struct sway_output *output,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool scan_out_fullscreen_view(struct sway_output *output,
 | 
					static bool scan_out_fullscreen_view(struct sway_output *output,
 | 
				
			||||||
		struct sway_view *view) {
 | 
							struct wlr_output_state *pending, struct sway_view *view) {
 | 
				
			||||||
	struct wlr_output *wlr_output = output->wlr_output;
 | 
						struct wlr_output *wlr_output = output->wlr_output;
 | 
				
			||||||
	struct sway_workspace *workspace = output->current.active_workspace;
 | 
						struct sway_workspace *workspace = output->current.active_workspace;
 | 
				
			||||||
	if (!sway_assert(workspace, "Expected an active workspace")) {
 | 
						if (!sway_assert(workspace, "Expected an active workspace")) {
 | 
				
			||||||
| 
						 | 
					@ -524,15 +524,16 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output_attach_buffer(wlr_output, &surface->buffer->base);
 | 
						wlr_output_state_set_buffer(pending, &surface->buffer->base);
 | 
				
			||||||
	if (!wlr_output_test(wlr_output)) {
 | 
					
 | 
				
			||||||
 | 
						if (!wlr_output_test_state(wlr_output, pending)) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_presentation_surface_sampled_on_output(server.presentation, surface,
 | 
						wlr_presentation_surface_sampled_on_output(server.presentation, surface,
 | 
				
			||||||
		wlr_output);
 | 
							wlr_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return wlr_output_commit(wlr_output);
 | 
						return wlr_output_commit_state(wlr_output, pending);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void get_frame_damage(struct sway_output *output,
 | 
					static void get_frame_damage(struct sway_output *output,
 | 
				
			||||||
| 
						 | 
					@ -580,29 +581,30 @@ static int output_repaint_timer_handler(void *data) {
 | 
				
			||||||
		fullscreen_con = workspace->current.fullscreen;
 | 
							fullscreen_con = workspace->current.fullscreen;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_output_state pending = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (output->gamma_lut_changed) {
 | 
						if (output->gamma_lut_changed) {
 | 
				
			||||||
		struct wlr_gamma_control_v1 *gamma_control =
 | 
							struct wlr_gamma_control_v1 *gamma_control =
 | 
				
			||||||
			wlr_gamma_control_manager_v1_get_control(
 | 
								wlr_gamma_control_manager_v1_get_control(
 | 
				
			||||||
			server.gamma_control_manager_v1, wlr_output);
 | 
								server.gamma_control_manager_v1, wlr_output);
 | 
				
			||||||
		if (!wlr_gamma_control_v1_apply(gamma_control, &wlr_output->pending)) {
 | 
							if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
 | 
				
			||||||
			return 0;
 | 
								goto out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!wlr_output_test(wlr_output)) {
 | 
							if (!wlr_output_test_state(wlr_output, &pending)) {
 | 
				
			||||||
			wlr_output_rollback(wlr_output);
 | 
								wlr_output_state_finish(&pending);
 | 
				
			||||||
 | 
								pending = (struct wlr_output_state){0};
 | 
				
			||||||
			wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
 | 
								wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pixman_region32_t frame_damage;
 | 
						pending.committed |= WLR_OUTPUT_STATE_BUFFER;
 | 
				
			||||||
	get_frame_damage(output, &frame_damage);
 | 
						get_frame_damage(output, &pending.damage);
 | 
				
			||||||
	wlr_output_set_damage(wlr_output, &frame_damage);
 | 
					 | 
				
			||||||
	pixman_region32_fini(&frame_damage);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
 | 
						if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
 | 
				
			||||||
		// Try to scan-out the fullscreen view
 | 
							// Try to scan-out the fullscreen view
 | 
				
			||||||
		static bool last_scanned_out = false;
 | 
							static bool last_scanned_out = false;
 | 
				
			||||||
		bool scanned_out =
 | 
							bool scanned_out =
 | 
				
			||||||
			scan_out_fullscreen_view(output, fullscreen_con->view);
 | 
								scan_out_fullscreen_view(output, &pending, fullscreen_con->view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (scanned_out && !last_scanned_out) {
 | 
							if (scanned_out && !last_scanned_out) {
 | 
				
			||||||
			sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s",
 | 
								sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s",
 | 
				
			||||||
| 
						 | 
					@ -616,25 +618,25 @@ static int output_repaint_timer_handler(void *data) {
 | 
				
			||||||
		last_scanned_out = scanned_out;
 | 
							last_scanned_out = scanned_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (scanned_out) {
 | 
							if (scanned_out) {
 | 
				
			||||||
			return 0;
 | 
								goto out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!wlr_output_configure_primary_swapchain(wlr_output, NULL, &wlr_output->swapchain)) {
 | 
						if (!wlr_output_configure_primary_swapchain(wlr_output, &pending, &wlr_output->swapchain)) {
 | 
				
			||||||
		return false;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int buffer_age;
 | 
						int buffer_age;
 | 
				
			||||||
	struct wlr_buffer *buffer = wlr_swapchain_acquire(wlr_output->swapchain, &buffer_age);
 | 
						struct wlr_buffer *buffer = wlr_swapchain_acquire(wlr_output->swapchain, &buffer_age);
 | 
				
			||||||
	if (buffer == NULL) {
 | 
						if (buffer == NULL) {
 | 
				
			||||||
		return false;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_render_pass *render_pass = wlr_renderer_begin_buffer_pass(
 | 
						struct wlr_render_pass *render_pass = wlr_renderer_begin_buffer_pass(
 | 
				
			||||||
		wlr_output->renderer, buffer, NULL);
 | 
							wlr_output->renderer, buffer, NULL);
 | 
				
			||||||
	if (render_pass == NULL) {
 | 
						if (render_pass == NULL) {
 | 
				
			||||||
		wlr_buffer_unlock(buffer);
 | 
							wlr_buffer_unlock(buffer);
 | 
				
			||||||
		return false;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pixman_region32_t damage;
 | 
						pixman_region32_t damage;
 | 
				
			||||||
| 
						 | 
					@ -663,19 +665,21 @@ static int output_repaint_timer_handler(void *data) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!wlr_render_pass_submit(render_pass)) {
 | 
						if (!wlr_render_pass_submit(render_pass)) {
 | 
				
			||||||
		wlr_buffer_unlock(buffer);
 | 
							wlr_buffer_unlock(buffer);
 | 
				
			||||||
		return false;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output_attach_buffer(wlr_output, buffer);
 | 
						wlr_output_state_set_buffer(&pending, buffer);
 | 
				
			||||||
	wlr_buffer_unlock(buffer);
 | 
						wlr_buffer_unlock(buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!wlr_output_commit(wlr_output)) {
 | 
						if (!wlr_output_commit_state(wlr_output, &pending)) {
 | 
				
			||||||
		return 0;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_damage_ring_rotate(&output->damage_ring);
 | 
						wlr_damage_ring_rotate(&output->damage_ring);
 | 
				
			||||||
	output->last_frame = now;
 | 
						output->last_frame = now;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						wlr_output_state_finish(&pending);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue