mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 13:22:15 +00:00
compositor/native: Track what Wayland surface is a scanout candidate
For the current candidate, set the candidate CRTC on that surface. This will later be used to send DMA buffer feedback for direct scanout purposes. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1959>
This commit is contained in:
parent
9a47766a96
commit
43161c6660
@ -23,11 +23,14 @@
|
|||||||
#include "compositor/meta-compositor-native.h"
|
#include "compositor/meta-compositor-native.h"
|
||||||
|
|
||||||
#include "backends/meta-logical-monitor.h"
|
#include "backends/meta-logical-monitor.h"
|
||||||
|
#include "backends/native/meta-crtc-kms.h"
|
||||||
#include "compositor/meta-surface-actor-wayland.h"
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
|
|
||||||
struct _MetaCompositorNative
|
struct _MetaCompositorNative
|
||||||
{
|
{
|
||||||
MetaCompositorServer parent;
|
MetaCompositorServer parent;
|
||||||
|
|
||||||
|
MetaWaylandSurface *current_scanout_candidate;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
|
G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
|
||||||
@ -62,57 +65,88 @@ get_window_view (MetaRenderer *renderer,
|
|||||||
static void
|
static void
|
||||||
maybe_assign_primary_plane (MetaCompositor *compositor)
|
maybe_assign_primary_plane (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
|
MetaCompositorNative *compositor_native = META_COMPOSITOR_NATIVE (compositor);
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||||
MetaWindowActor *window_actor;
|
MetaWindowActor *window_actor;
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaRendererView *view;
|
MetaRendererView *view;
|
||||||
|
MetaCrtc *crtc;
|
||||||
CoglFramebuffer *framebuffer;
|
CoglFramebuffer *framebuffer;
|
||||||
CoglOnscreen *onscreen;
|
CoglOnscreen *onscreen;
|
||||||
MetaSurfaceActor *surface_actor;
|
MetaSurfaceActor *surface_actor;
|
||||||
MetaSurfaceActorWayland *surface_actor_wayland;
|
MetaSurfaceActorWayland *surface_actor_wayland;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
MetaWaylandSurface *old_candidate =
|
||||||
|
compositor_native->current_scanout_candidate;
|
||||||
|
MetaWaylandSurface *new_candidate = NULL;
|
||||||
g_autoptr (CoglScanout) scanout = NULL;
|
g_autoptr (CoglScanout) scanout = NULL;
|
||||||
|
|
||||||
if (meta_compositor_is_unredirect_inhibited (compositor))
|
if (meta_compositor_is_unredirect_inhibited (compositor))
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
window_actor = meta_compositor_get_top_window_actor (compositor);
|
window_actor = meta_compositor_get_top_window_actor (compositor);
|
||||||
if (!window_actor)
|
if (!window_actor)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
if (meta_window_actor_effect_in_progress (window_actor))
|
if (meta_window_actor_effect_in_progress (window_actor))
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
|
if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
|
if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
window = meta_window_actor_get_meta_window (window_actor);
|
window = meta_window_actor_get_meta_window (window_actor);
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
view = get_window_view (renderer, window);
|
view = get_window_view (renderer, window);
|
||||||
if (!view)
|
if (!view)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
|
crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (view));
|
||||||
|
if (!META_IS_CRTC_KMS (crtc))
|
||||||
|
goto done;
|
||||||
|
|
||||||
framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
|
framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
|
||||||
if (!COGL_IS_ONSCREEN (framebuffer))
|
if (!COGL_IS_ONSCREEN (framebuffer))
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
surface_actor = meta_window_actor_get_surface (window_actor);
|
surface_actor = meta_window_actor_get_surface (window_actor);
|
||||||
if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
|
if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
|
||||||
return;
|
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;
|
||||||
|
|
||||||
|
new_candidate = surface;
|
||||||
|
|
||||||
onscreen = COGL_ONSCREEN (framebuffer);
|
onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
|
scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
|
||||||
onscreen);
|
onscreen);
|
||||||
if (!scanout)
|
if (!scanout)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
|
clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
if (old_candidate && old_candidate != new_candidate)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_set_scanout_candidate (old_candidate, NULL);
|
||||||
|
g_clear_weak_pointer (&compositor_native->current_scanout_candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_candidate)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_set_scanout_candidate (surface, crtc);
|
||||||
|
g_set_weak_pointer (&compositor_native->current_scanout_candidate,
|
||||||
|
surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -137,6 +171,16 @@ meta_compositor_native_new (MetaDisplay *display,
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_compositor_native_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaCompositorNative *compositor_native = META_COMPOSITOR_NATIVE (object);
|
||||||
|
|
||||||
|
g_clear_weak_pointer (&compositor_native->current_scanout_candidate);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_compositor_native_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
||||||
{
|
{
|
||||||
@ -145,7 +189,10 @@ meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
|||||||
static void
|
static void
|
||||||
meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
|
meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
|
||||||
{
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
|
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_compositor_native_finalize;
|
||||||
|
|
||||||
compositor_class->before_paint = meta_compositor_native_before_paint;
|
compositor_class->before_paint = meta_compositor_native_before_paint;
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,7 @@ meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
surface = meta_surface_actor_wayland_get_surface (self);
|
surface = meta_surface_actor_wayland_get_surface (self);
|
||||||
if (!surface)
|
g_return_val_if_fail (surface, NULL);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
|
scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
|
||||||
if (!scanout)
|
if (!scanout)
|
||||||
|
@ -77,6 +77,17 @@ typedef struct _MetaWaylandSurfaceRolePrivate
|
|||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
} MetaWaylandSurfaceRolePrivate;
|
} MetaWaylandSurfaceRolePrivate;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_SCANOUT_CANDIDATE,
|
||||||
|
|
||||||
|
N_PROPS
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *obj_props[N_PROPS];
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
|
||||||
@ -1412,6 +1423,7 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||||||
|
|
||||||
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
|
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
|
||||||
|
|
||||||
|
g_clear_object (&surface->scanout_candidate);
|
||||||
g_clear_object (&surface->role);
|
g_clear_object (&surface->role);
|
||||||
|
|
||||||
if (surface->unassigned.buffer)
|
if (surface->unassigned.buffer)
|
||||||
@ -1693,11 +1705,41 @@ meta_wayland_surface_init (MetaWaylandSurface *surface)
|
|||||||
g_node_prepend_data (surface->subsurface_branch_node, surface);
|
g_node_prepend_data (surface->subsurface_branch_node, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
MetaWaylandSurface *surface = META_WAYLAND_SURFACE (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SCANOUT_CANDIDATE:
|
||||||
|
g_value_set_object (value, surface->scanout_candidate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
|
meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->get_property = meta_wayland_surface_get_property;
|
||||||
|
|
||||||
|
obj_props[PROP_SCANOUT_CANDIDATE] =
|
||||||
|
g_param_spec_object ("scanout-candidate",
|
||||||
|
"scanout-candidate",
|
||||||
|
"Scanout candidate for given CRTC",
|
||||||
|
META_TYPE_CRTC,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||||
|
|
||||||
surface_signals[SURFACE_DESTROY] =
|
surface_signals[SURFACE_DESTROY] =
|
||||||
g_signal_new ("destroy",
|
g_signal_new ("destroy",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
@ -2100,3 +2142,21 @@ meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
|
|||||||
|
|
||||||
return scanout;
|
return scanout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaCrtc *
|
||||||
|
meta_wayland_surface_get_scanout_candidate (MetaWaylandSurface *surface)
|
||||||
|
{
|
||||||
|
return surface->scanout_candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
||||||
|
MetaCrtc *crtc)
|
||||||
|
{
|
||||||
|
if (surface->scanout_candidate == crtc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_set_object (&surface->scanout_candidate, crtc);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (surface),
|
||||||
|
obj_props[PROP_SCANOUT_CANDIDATE]);
|
||||||
|
}
|
||||||
|
@ -247,6 +247,9 @@ struct _MetaWaylandSurface
|
|||||||
*/
|
*/
|
||||||
uint64_t sequence;
|
uint64_t sequence;
|
||||||
} presentation_time;
|
} presentation_time;
|
||||||
|
|
||||||
|
/* dma-buf feedback */
|
||||||
|
MetaCrtc *scanout_candidate;
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_wayland_shell_init (MetaWaylandCompositor *compositor);
|
void meta_wayland_shell_init (MetaWaylandCompositor *compositor);
|
||||||
@ -363,6 +366,11 @@ int meta_wayland_surface_get_height (MetaWaylandSurface *surface
|
|||||||
CoglScanout * meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
|
CoglScanout * meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
|
||||||
CoglOnscreen *onscreen);
|
CoglOnscreen *onscreen);
|
||||||
|
|
||||||
|
MetaCrtc * meta_wayland_surface_get_scanout_candidate (MetaWaylandSurface *surface);
|
||||||
|
|
||||||
|
void meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
||||||
|
MetaCrtc *crtc);
|
||||||
|
|
||||||
static inline GNode *
|
static inline GNode *
|
||||||
meta_get_next_subsurface_sibling (GNode *n)
|
meta_get_next_subsurface_sibling (GNode *n)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user