diff options
| -rw-r--r-- | include/wlr/types/wlr_presentation_time.h | 20 | ||||
| -rw-r--r-- | types/scene/surface.c | 20 | ||||
| -rw-r--r-- | types/wlr_presentation_time.c | 22 | 
3 files changed, 48 insertions, 14 deletions
| diff --git a/include/wlr/types/wlr_presentation_time.h b/include/wlr/types/wlr_presentation_time.h index 817730b3..a8df292d 100644 --- a/include/wlr/types/wlr_presentation_time.h +++ b/include/wlr/types/wlr_presentation_time.h @@ -33,11 +33,12 @@ struct wlr_presentation {  struct wlr_presentation_feedback {  	struct wl_list resources; // wl_resource_get_link() -	// Only when the wlr_presentation_surface_sampled_on_output() helper has -	// been called. +	// Only when the wlr_presentation_surface_textured_on_output() or +	// wlr_presentation_surface_scanned_out_on_output() helper has been called.  	struct wlr_output *output;  	bool output_committed;  	uint32_t output_commit_seq; +	bool zero_copy;  	struct wl_listener output_commit;  	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);  /** - * 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   * struct wlr_presentation_feedback itself, the compositor can call this function   * 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_output *output); diff --git a/types/scene/surface.c b/types/scene/surface.c index afefb917..1b585e8c 100644 --- a/types/scene/surface.c +++ b/types/scene/surface.c @@ -42,15 +42,21 @@ static void handle_scene_buffer_output_sample(  		wl_container_of(listener, surface, output_sample);  	const struct wlr_scene_output_sample_event *event = data;  	struct wlr_scene_output *scene_output = event->output; +	if (surface->buffer->primary_output != scene_output) { +		return; +	} -	if (surface->buffer->primary_output == scene_output) { -		struct wlr_scene *root = scene_node_get_root(&surface->buffer->node); -		struct wlr_presentation *presentation = root->presentation; +	struct wlr_scene *root = scene_node_get_root(&surface->buffer->node); +	if (!root->presentation) { +		return; +	} -		if (presentation) { -			wlr_presentation_surface_sampled_on_output( -				presentation, surface->surface, scene_output->output); -		} +	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);  	}  } diff --git a/types/wlr_presentation_time.c b/types/wlr_presentation_time.c index 2a6610f4..f13f3179 100644 --- a/types/wlr_presentation_time.c +++ b/types/wlr_presentation_time.c @@ -295,6 +295,9 @@ static void feedback_handle_output_present(struct wl_listener *listener,  	if (output_event->presented) {  		struct wlr_presentation_event event = {0};  		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_destroy(feedback); @@ -307,9 +310,9 @@ static void feedback_handle_output_destroy(struct wl_listener *listener,  	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_output *output) { +		struct wlr_output *output, bool zero_copy) {  	struct wlr_presentation_feedback *feedback =  		wlr_presentation_surface_sampled(presentation, surface);  	if (feedback == NULL) { @@ -318,6 +321,7 @@ void wlr_presentation_surface_sampled_on_output(  	assert(feedback->output == NULL);  	feedback->output = output; +	feedback->zero_copy = zero_copy;  	feedback->output_commit.notify = feedback_handle_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;  	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); +} | 
