mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	presentation-time: add separate helper for zero-copy
The backend is not able to tell whether a surface is being presented via direct scan-out or not. The backend will set ZERO_COPY if the buffer submitted via the output commit was presented in a zero-copy fashion, but will no know whether the buffer comes from the compositor or the client.
This commit is contained in:
		
							parent
							
								
									fe84bfc8d9
								
							
						
					
					
						commit
						67447d6cb4
					
				
					 3 changed files with 48 additions and 14 deletions
				
			
		| 
						 | 
					@ -33,11 +33,12 @@ struct wlr_presentation {
 | 
				
			||||||
struct wlr_presentation_feedback {
 | 
					struct wlr_presentation_feedback {
 | 
				
			||||||
	struct wl_list resources; // wl_resource_get_link()
 | 
						struct wl_list resources; // wl_resource_get_link()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Only when the wlr_presentation_surface_sampled_on_output() helper has
 | 
						// Only when the wlr_presentation_surface_textured_on_output() or
 | 
				
			||||||
	// been called.
 | 
						// wlr_presentation_surface_scanned_out_on_output() helper has been called.
 | 
				
			||||||
	struct wlr_output *output;
 | 
						struct wlr_output *output;
 | 
				
			||||||
	bool output_committed;
 | 
						bool output_committed;
 | 
				
			||||||
	uint32_t output_commit_seq;
 | 
						uint32_t output_commit_seq;
 | 
				
			||||||
 | 
						bool zero_copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener output_commit;
 | 
						struct wl_listener output_commit;
 | 
				
			||||||
	struct wl_listener output_present;
 | 
						struct wl_listener output_present;
 | 
				
			||||||
| 
						 | 
					@ -85,14 +86,23 @@ void wlr_presentation_event_from_output(struct wlr_presentation_event *event,
 | 
				
			||||||
		const struct wlr_output_event_present *output_event);
 | 
							const struct wlr_output_event_present *output_event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Mark the current surface's buffer as sampled on the given output.
 | 
					 * Mark the current surface's buffer as textured on the given output.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Instead of calling wlr_presentation_surface_sampled() and managing the
 | 
					 * Instead of calling wlr_presentation_surface_sampled() and managing the
 | 
				
			||||||
 * struct wlr_presentation_feedback itself, the compositor can call this function
 | 
					 * struct wlr_presentation_feedback itself, the compositor can call this function
 | 
				
			||||||
 * before a wlr_output_commit() call to indicate that the surface's current
 | 
					 * before a wlr_output_commit() call to indicate that the surface's current
 | 
				
			||||||
 * contents will be displayed on the output.
 | 
					 * contents have been copied to a buffer which will be displayed on the output.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void wlr_presentation_surface_sampled_on_output(
 | 
					void wlr_presentation_surface_textured_on_output(
 | 
				
			||||||
 | 
						struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
				
			||||||
 | 
						struct wlr_output *output);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Mark the current surface's buffer as scanned out on the given output.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Same as wlr_presentation_surface_textured_on_output(), but indicates direct
 | 
				
			||||||
 | 
					 * scan-out.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_presentation_surface_scanned_out_on_output(
 | 
				
			||||||
	struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
						struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
				
			||||||
	struct wlr_output *output);
 | 
						struct wlr_output *output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,15 +42,21 @@ static void handle_scene_buffer_output_sample(
 | 
				
			||||||
		wl_container_of(listener, surface, output_sample);
 | 
							wl_container_of(listener, surface, output_sample);
 | 
				
			||||||
	const struct wlr_scene_output_sample_event *event = data;
 | 
						const struct wlr_scene_output_sample_event *event = data;
 | 
				
			||||||
	struct wlr_scene_output *scene_output = event->output;
 | 
						struct wlr_scene_output *scene_output = event->output;
 | 
				
			||||||
 | 
						if (surface->buffer->primary_output != scene_output) {
 | 
				
			||||||
	if (surface->buffer->primary_output == scene_output) {
 | 
							return;
 | 
				
			||||||
		struct wlr_scene *root = scene_node_get_root(&surface->buffer->node);
 | 
					 | 
				
			||||||
		struct wlr_presentation *presentation = root->presentation;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (presentation) {
 | 
					 | 
				
			||||||
			wlr_presentation_surface_sampled_on_output(
 | 
					 | 
				
			||||||
				presentation, surface->surface, scene_output->output);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_scene *root = scene_node_get_root(&surface->buffer->node);
 | 
				
			||||||
 | 
						if (!root->presentation) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (event->direct_scanout) {
 | 
				
			||||||
 | 
							wlr_presentation_surface_scanned_out_on_output(
 | 
				
			||||||
 | 
								root->presentation, surface->surface, scene_output->output);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_presentation_surface_textured_on_output(
 | 
				
			||||||
 | 
								root->presentation, surface->surface, scene_output->output);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,6 +295,9 @@ static void feedback_handle_output_present(struct wl_listener *listener,
 | 
				
			||||||
	if (output_event->presented) {
 | 
						if (output_event->presented) {
 | 
				
			||||||
		struct wlr_presentation_event event = {0};
 | 
							struct wlr_presentation_event event = {0};
 | 
				
			||||||
		wlr_presentation_event_from_output(&event, output_event);
 | 
							wlr_presentation_event_from_output(&event, output_event);
 | 
				
			||||||
 | 
							if (!feedback->zero_copy) {
 | 
				
			||||||
 | 
								event.flags &= ~WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		wlr_presentation_feedback_send_presented(feedback, &event);
 | 
							wlr_presentation_feedback_send_presented(feedback, &event);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wlr_presentation_feedback_destroy(feedback);
 | 
						wlr_presentation_feedback_destroy(feedback);
 | 
				
			||||||
| 
						 | 
					@ -307,9 +310,9 @@ static void feedback_handle_output_destroy(struct wl_listener *listener,
 | 
				
			||||||
	wlr_presentation_feedback_destroy(feedback);
 | 
						wlr_presentation_feedback_destroy(feedback);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_presentation_surface_sampled_on_output(
 | 
					static void presentation_surface_queued_on_output(
 | 
				
			||||||
		struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
							struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
				
			||||||
		struct wlr_output *output) {
 | 
							struct wlr_output *output, bool zero_copy) {
 | 
				
			||||||
	struct wlr_presentation_feedback *feedback =
 | 
						struct wlr_presentation_feedback *feedback =
 | 
				
			||||||
		wlr_presentation_surface_sampled(presentation, surface);
 | 
							wlr_presentation_surface_sampled(presentation, surface);
 | 
				
			||||||
	if (feedback == NULL) {
 | 
						if (feedback == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -318,6 +321,7 @@ void wlr_presentation_surface_sampled_on_output(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert(feedback->output == NULL);
 | 
						assert(feedback->output == NULL);
 | 
				
			||||||
	feedback->output = output;
 | 
						feedback->output = output;
 | 
				
			||||||
 | 
						feedback->zero_copy = zero_copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	feedback->output_commit.notify = feedback_handle_output_commit;
 | 
						feedback->output_commit.notify = feedback_handle_output_commit;
 | 
				
			||||||
	wl_signal_add(&output->events.commit, &feedback->output_commit);
 | 
						wl_signal_add(&output->events.commit, &feedback->output_commit);
 | 
				
			||||||
| 
						 | 
					@ -326,3 +330,17 @@ void wlr_presentation_surface_sampled_on_output(
 | 
				
			||||||
	feedback->output_destroy.notify = feedback_handle_output_destroy;
 | 
						feedback->output_destroy.notify = feedback_handle_output_destroy;
 | 
				
			||||||
	wl_signal_add(&output->events.destroy, &feedback->output_destroy);
 | 
						wl_signal_add(&output->events.destroy, &feedback->output_destroy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_presentation_surface_textured_on_output(
 | 
				
			||||||
 | 
							struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
				
			||||||
 | 
							struct wlr_output *output) {
 | 
				
			||||||
 | 
						return presentation_surface_queued_on_output(presentation, surface,
 | 
				
			||||||
 | 
							output, false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_presentation_surface_scanned_out_on_output(
 | 
				
			||||||
 | 
							struct wlr_presentation *presentation, struct wlr_surface *surface,
 | 
				
			||||||
 | 
							struct wlr_output *output) {
 | 
				
			||||||
 | 
						return presentation_surface_queued_on_output(presentation, surface,
 | 
				
			||||||
 | 
							output, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue