From bf0e031e4aaccf1f30027ea05fc1b261a2f3bd00 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 17 Dec 2014 16:20:41 +0200 Subject: [PATCH] compositor, drm: set per-surface Presentation feedback flags PRESENTATION_FEEDBACK_KIND_ZERO_COPY is a flag that needs to be set for each surface separately. Some surfaces may be zero-copy (as defined by Presentation feedback) while some are not. A complication with Weston is that a surface may have multiple views on screen. All copies (views) of the surface are required to be zero-copy for the ZERO_COPY flag to be set. Backends set per-view feedback flags during the assing_planes hook, and then Weston core collects the flags from all views of a surface. Signed-off-by: Pekka Paalanen Reviewed-by: Mario Kleiner Tested-by: Mario Kleiner --- src/compositor-drm.c | 13 +++++++++++++ src/compositor.c | 43 ++++++++++++++++++++++++++++++++++++------- src/compositor.h | 3 +++ 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 86adfee1..209f2ae4 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1130,11 +1130,24 @@ drm_assign_planes(struct weston_output *output_base) next_plane = drm_output_prepare_overlay_view(output, ev); if (next_plane == NULL) next_plane = primary; + weston_view_move_to_plane(ev, next_plane); + if (next_plane == primary) pixman_region32_union(&overlap, &overlap, &ev->transform.boundingbox); + if (next_plane == primary || + next_plane == &output->cursor_plane) { + /* cursor plane involves a copy */ + ev->psf_flags = 0; + } else { + /* All other planes are a direct scanout of a + * single client buffer. + */ + ev->psf_flags = PRESENTATION_FEEDBACK_KIND_ZERO_COPY; + } + pixman_region32_fini(&surface_overlap); } pixman_region32_fini(&overlap); diff --git a/src/compositor.c b/src/compositor.c index 8085b055..c2c975d5 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -470,6 +470,9 @@ struct weston_presentation_feedback { /* XXX: could use just wl_resource_get_link() instead */ struct wl_list link; + + /* The per-surface feedback flags */ + uint32_t psf_flags; }; static void @@ -515,7 +518,7 @@ weston_presentation_feedback_present( ts->tv_nsec, refresh_nsec, seq >> 32, seq & 0xffffffff, - flags); + flags | feedback->psf_flags); wl_resource_destroy(feedback->resource); } @@ -2000,6 +2003,31 @@ weston_compositor_build_view_list(struct weston_compositor *compositor) surface_free_unused_subsurface_views(view->surface); } +static void +weston_output_take_feedback_list(struct weston_output *output, + struct weston_surface *surface) +{ + struct weston_view *view; + struct weston_presentation_feedback *feedback; + uint32_t flags = 0xffffffff; + + if (wl_list_empty(&surface->feedback_list)) + return; + + /* All views must have the flag for the flag to survive. */ + wl_list_for_each(view, &surface->views, surface_link) { + /* ignore views that are not on this output at all */ + if (view->output_mask & (1u << output->id)) + flags &= view->psf_flags; + } + + wl_list_for_each(feedback, &surface->feedback_list, link) + feedback->psf_flags = flags; + + wl_list_insert_list(&output->feedback_list, &surface->feedback_list); + wl_list_init(&surface->feedback_list); +} + static int weston_output_repaint(struct weston_output *output) { @@ -2019,11 +2047,14 @@ weston_output_repaint(struct weston_output *output) /* Rebuild the surface list and update surface transforms up front. */ weston_compositor_build_view_list(ec); - if (output->assign_planes && !output->disable_planes) + if (output->assign_planes && !output->disable_planes) { output->assign_planes(output); - else - wl_list_for_each(ev, &ec->view_list, link) + } else { + wl_list_for_each(ev, &ec->view_list, link) { weston_view_move_to_plane(ev, &ec->primary_plane); + ev->psf_flags = 0; + } + } wl_list_init(&frame_callback_list); wl_list_for_each(ev, &ec->view_list, link) { @@ -2035,9 +2066,7 @@ weston_output_repaint(struct weston_output *output) &ev->surface->frame_callback_list); wl_list_init(&ev->surface->frame_callback_list); - wl_list_insert_list(&output->feedback_list, - &ev->surface->feedback_list); - wl_list_init(&ev->surface->feedback_list); + weston_output_take_feedback_list(output, ev->surface); } } diff --git a/src/compositor.h b/src/compositor.h index 3a266356..aa87ec0b 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -815,6 +815,9 @@ struct weston_view { * displayed on. */ uint32_t output_mask; + + /* Per-surface Presentation feedback flags, controlled by backend. */ + uint32_t psf_flags; }; struct weston_surface_state {