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:
Simon Ser 2023-04-14 20:41:27 +02:00
parent fe84bfc8d9
commit 67447d6cb4
3 changed files with 48 additions and 14 deletions

View file

@ -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);
}
}

View file

@ -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);
}