From 9c8948fc047b8b99908a548a390f2acd1ccf8a55 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Wed, 11 May 2022 22:32:33 +0200 Subject: [PATCH] window-actor: Add API to get the surface actor candidate for scanout This replaces the API to get the topmost surface actor with an API to get the surface actor that could be a candidate for direct scanout. The advantage of this is that it allows X11 and Wayland specific restrictions for these actors. Part-of: --- src/compositor/meta-compositor-native.c | 8 +++----- src/compositor/meta-window-actor-private.h | 4 ++-- src/compositor/meta-window-actor-wayland.c | 19 +++++++++---------- src/compositor/meta-window-actor-x11.c | 18 ++++++++++++++++++ src/compositor/meta-window-actor.c | 12 ++++++------ 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/compositor/meta-compositor-native.c b/src/compositor/meta-compositor-native.c index 84e7a75d8..bc17704e1 100644 --- a/src/compositor/meta-compositor-native.c +++ b/src/compositor/meta-compositor-native.c @@ -114,13 +114,11 @@ maybe_assign_primary_plane (MetaCompositor *compositor) if (!COGL_IS_ONSCREEN (framebuffer)) goto done; - surface_actor = meta_window_actor_get_topmost_surface (window_actor); - if (!surface_actor || - CLUTTER_ACTOR (surface_actor) != - clutter_actor_get_last_child (CLUTTER_ACTOR (window_actor))) + surface_actor = meta_window_actor_get_scanout_candidate (window_actor); + if (!surface_actor) goto done; - surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor); + surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor); surface = meta_surface_actor_wayland_get_surface (surface_actor_wayland); if (!surface) goto done; diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 138ce2c83..8aa206bb8 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -15,7 +15,7 @@ struct _MetaWindowActorClass ClutterFrameInfo *frame_info, int64_t presentation_time); - MetaSurfaceActor * (*get_topmost_surface) (MetaWindowActor *actor); + MetaSurfaceActor * (*get_scanout_candidate) (MetaWindowActor *actor); void (*assign_surface_actor) (MetaWindowActor *actor, MetaSurfaceActor *surface_actor); @@ -80,7 +80,7 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); -MetaSurfaceActor * meta_window_actor_get_topmost_surface (MetaWindowActor *self); +MetaSurfaceActor *meta_window_actor_get_scanout_candidate (MetaWindowActor *self); void meta_window_actor_assign_surface_actor (MetaWindowActor *self, MetaSurfaceActor *surface_actor); diff --git a/src/compositor/meta-window-actor-wayland.c b/src/compositor/meta-window-actor-wayland.c index 468229751..4b87fd11f 100644 --- a/src/compositor/meta-window-actor-wayland.c +++ b/src/compositor/meta-window-actor-wayland.c @@ -89,19 +89,18 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor) } static MetaSurfaceActor * -meta_window_actor_wayland_get_topmost_surface (MetaWindowActor *actor) +meta_window_actor_wayland_get_scanout_candidate (MetaWindowActor *actor) { ClutterActor *child_actor; + MetaSurfaceActor *topmost_surface_actor; - for (child_actor = clutter_actor_get_last_child (CLUTTER_ACTOR (actor)); - child_actor; - child_actor = clutter_actor_get_previous_sibling (child_actor)) - { - if (META_IS_SURFACE_ACTOR_WAYLAND (child_actor)) - return META_SURFACE_ACTOR (child_actor); - } + child_actor = clutter_actor_get_last_child (CLUTTER_ACTOR (actor)); + if (!child_actor || !META_IS_SURFACE_ACTOR_WAYLAND (child_actor)) + return NULL; - return NULL; + topmost_surface_actor = META_SURFACE_ACTOR (child_actor); + + return topmost_surface_actor; } static void @@ -193,7 +192,7 @@ meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass) MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); - window_actor_class->get_topmost_surface = meta_window_actor_wayland_get_topmost_surface; + window_actor_class->get_scanout_candidate = meta_window_actor_wayland_get_scanout_candidate; window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor; window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete; window_actor_class->queue_frame_drawn = meta_window_actor_wayland_queue_frame_drawn; diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index 9e64462ea..d06855b51 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -431,6 +431,23 @@ meta_window_actor_x11_frame_complete (MetaWindowActor *actor, } } +static MetaSurfaceActor * +meta_window_actor_x11_get_scanout_candidate (MetaWindowActor *actor) +{ + MetaSurfaceActor *surface_actor; + + surface_actor = meta_window_actor_get_surface (actor); + + if (!surface_actor) + return NULL; + + if (CLUTTER_ACTOR (surface_actor) != + clutter_actor_get_last_child (CLUTTER_ACTOR (actor))) + return NULL; + + return surface_actor; +} + static void surface_size_changed (MetaSurfaceActor *actor, gpointer user_data) @@ -1681,6 +1698,7 @@ meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass) GParamSpec *pspec; window_actor_class->frame_complete = meta_window_actor_x11_frame_complete; + window_actor_class->get_scanout_candidate = meta_window_actor_x11_get_scanout_candidate; window_actor_class->assign_surface_actor = meta_window_actor_x11_assign_surface_actor; window_actor_class->queue_frame_drawn = meta_window_actor_x11_queue_frame_drawn; window_actor_class->before_paint = meta_window_actor_x11_before_paint; diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 9cee56a37..ae1fa4d90 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -107,7 +107,7 @@ static void meta_window_actor_get_property (GObject *object, GValue *value, GParamSpec *pspec); -static MetaSurfaceActor * meta_window_actor_real_get_topmost_surface (MetaWindowActor *self); +static MetaSurfaceActor * meta_window_actor_real_get_scanout_candidate (MetaWindowActor *self); static void meta_window_actor_real_assign_surface_actor (MetaWindowActor *self, MetaSurfaceActor *surface_actor); @@ -132,7 +132,7 @@ meta_window_actor_class_init (MetaWindowActorClass *klass) object_class->get_property = meta_window_actor_get_property; object_class->constructed = meta_window_actor_constructed; - klass->get_topmost_surface = meta_window_actor_real_get_topmost_surface; + klass->get_scanout_candidate = meta_window_actor_real_get_scanout_candidate; klass->assign_surface_actor = meta_window_actor_real_assign_surface_actor; /** @@ -560,15 +560,15 @@ meta_window_actor_get_surface (MetaWindowActor *self) } static MetaSurfaceActor * -meta_window_actor_real_get_topmost_surface (MetaWindowActor *self) +meta_window_actor_real_get_scanout_candidate (MetaWindowActor *self) { - return meta_window_actor_get_surface (self); + return NULL; } MetaSurfaceActor * -meta_window_actor_get_topmost_surface (MetaWindowActor *self) +meta_window_actor_get_scanout_candidate (MetaWindowActor *self) { - return META_WINDOW_ACTOR_GET_CLASS (self)->get_topmost_surface (self); + return META_WINDOW_ACTOR_GET_CLASS (self)->get_scanout_candidate (self); } /**