mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
compositor: Add support for direct scanout of Wayland surfaces
Try to bypass compositing if there is a fullscreen toplevel window with a buffer compatible with the primary plane of the monitor it is fullscreen on. Only non-mirrored is currently supported; as well as fullscreened on a single monitor. It should be possible to extend with more cases, but this starts small. It does this by introducing a new MetaCompositor sub type MetaCompositorNative specific to the native backend, which derives from MetaCompositorServer, containing functionality only relevant for when running on top of the native backend. https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
This commit is contained in:
parent
b51c468c0f
commit
65a6c4c361
@ -418,8 +418,7 @@ clutter_stage_view_assign_next_scanout (ClutterStageView *view,
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
g_clear_object (&priv->next_scanout);
|
||||
priv->next_scanout = scanout;
|
||||
g_set_object (&priv->next_scanout, scanout);
|
||||
}
|
||||
|
||||
CoglScanout *
|
||||
|
148
src/compositor/meta-compositor-native.c
Normal file
148
src/compositor/meta-compositor-native.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "compositor/meta-compositor-native.h"
|
||||
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
|
||||
struct _MetaCompositorNative
|
||||
{
|
||||
MetaCompositorServer parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
|
||||
META_TYPE_COMPOSITOR_SERVER)
|
||||
|
||||
static MetaRendererView *
|
||||
get_window_view (MetaRenderer *renderer,
|
||||
MetaWindow *window)
|
||||
{
|
||||
GList *l;
|
||||
MetaRendererView *view_found = NULL;
|
||||
|
||||
for (l = meta_renderer_get_views (renderer); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *stage_view = l->data;
|
||||
MetaRectangle view_layout;
|
||||
|
||||
clutter_stage_view_get_layout (stage_view, &view_layout);
|
||||
|
||||
if (meta_rectangle_equal (&window->buffer_rect,
|
||||
&view_layout))
|
||||
{
|
||||
if (view_found)
|
||||
return NULL;
|
||||
view_found = META_RENDERER_VIEW (stage_view);
|
||||
}
|
||||
}
|
||||
|
||||
return view_found;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_assign_primary_plane (MetaCompositor *compositor)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaWindowActor *window_actor;
|
||||
MetaWindow *window;
|
||||
MetaRendererView *view;
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglOnscreen *onscreen;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaSurfaceActorWayland *surface_actor_wayland;
|
||||
g_autoptr (CoglScanout) scanout = NULL;
|
||||
|
||||
if (meta_compositor_is_unredirect_inhibited (compositor))
|
||||
return;
|
||||
|
||||
window_actor = meta_compositor_get_top_window_actor (compositor);
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
if (meta_window_actor_effect_in_progress (window_actor))
|
||||
return;
|
||||
|
||||
if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
|
||||
return;
|
||||
|
||||
if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
|
||||
return;
|
||||
|
||||
window = meta_window_actor_get_meta_window (window_actor);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
view = get_window_view (renderer, window);
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
|
||||
if (!cogl_is_onscreen (framebuffer))
|
||||
return;
|
||||
|
||||
surface_actor = meta_window_actor_get_surface (window_actor);
|
||||
if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
|
||||
return;
|
||||
|
||||
surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor);
|
||||
onscreen = COGL_ONSCREEN (framebuffer);
|
||||
scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
|
||||
onscreen);
|
||||
if (!scanout)
|
||||
return;
|
||||
|
||||
clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_compositor_native_pre_paint (MetaCompositor *compositor)
|
||||
{
|
||||
MetaCompositorClass *parent_class;
|
||||
|
||||
maybe_assign_primary_plane (compositor);
|
||||
|
||||
parent_class = META_COMPOSITOR_CLASS (meta_compositor_native_parent_class);
|
||||
parent_class->pre_paint (compositor);
|
||||
}
|
||||
|
||||
MetaCompositorNative *
|
||||
meta_compositor_native_new (MetaDisplay *display)
|
||||
{
|
||||
return g_object_new (META_TYPE_COMPOSITOR_NATIVE,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
|
||||
{
|
||||
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
|
||||
|
||||
compositor_class->pre_paint = meta_compositor_native_pre_paint;
|
||||
}
|
32
src/compositor/meta-compositor-native.h
Normal file
32
src/compositor/meta-compositor-native.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef META_COMPOSITOR_NATIVE_H
|
||||
#define META_COMPOSITOR_NATIVE_H
|
||||
|
||||
#include "compositor/meta-compositor-server.h"
|
||||
|
||||
#define META_TYPE_COMPOSITOR_NATIVE (meta_compositor_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCompositorNative, meta_compositor_native,
|
||||
META, COMPOSITOR_NATIVE, MetaCompositor)
|
||||
|
||||
MetaCompositorNative * meta_compositor_native_new (MetaDisplay *display);
|
||||
|
||||
#endif /* META_COMPOSITOR_NATIVE_H */
|
@ -22,11 +22,6 @@
|
||||
|
||||
#include "compositor/meta-compositor-server.h"
|
||||
|
||||
struct _MetaCompositorServer
|
||||
{
|
||||
MetaCompositor parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaCompositorServer, meta_compositor_server, META_TYPE_COMPOSITOR)
|
||||
|
||||
static gboolean
|
||||
|
@ -24,8 +24,13 @@
|
||||
#include "compositor/compositor-private.h"
|
||||
|
||||
#define META_TYPE_COMPOSITOR_SERVER (meta_compositor_server_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCompositorServer, meta_compositor_server,
|
||||
META, COMPOSITOR_SERVER, MetaCompositor)
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaCompositorServer, meta_compositor_server,
|
||||
META, COMPOSITOR_SERVER, MetaCompositor)
|
||||
|
||||
struct _MetaCompositorServerClass
|
||||
{
|
||||
MetaCompositorClass parent_class;
|
||||
};
|
||||
|
||||
MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display);
|
||||
|
||||
|
@ -79,6 +79,40 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
|
||||
return meta_shaped_texture_is_opaque (stex);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_frame_callbacks (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandCompositor *wayland_compositor;
|
||||
|
||||
if (!self->surface)
|
||||
return;
|
||||
|
||||
if (meta_surface_actor_is_obscured (META_SURFACE_ACTOR (self)))
|
||||
return;
|
||||
|
||||
wayland_compositor = self->surface->compositor;
|
||||
wl_list_insert_list (&wayland_compositor->frame_callbacks,
|
||||
&self->frame_callback_list);
|
||||
wl_list_init (&self->frame_callback_list);
|
||||
}
|
||||
|
||||
CoglScanout *
|
||||
meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||
CoglOnscreen *onscreen)
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
CoglScanout *scanout;
|
||||
|
||||
surface = meta_surface_actor_wayland_get_surface (self);
|
||||
scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
|
||||
if (!scanout)
|
||||
return NULL;
|
||||
|
||||
queue_frame_callbacks (self);
|
||||
|
||||
return scanout;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks)
|
||||
@ -92,14 +126,7 @@ meta_surface_actor_wayland_paint (ClutterActor *actor,
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
|
||||
if (self->surface &&
|
||||
!meta_surface_actor_is_obscured (META_SURFACE_ACTOR (actor)))
|
||||
{
|
||||
MetaWaylandCompositor *compositor = self->surface->compositor;
|
||||
|
||||
wl_list_insert_list (&compositor->frame_callbacks, &self->frame_callback_list);
|
||||
wl_list_init (&self->frame_callback_list);
|
||||
}
|
||||
queue_frame_callbacks (self);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor,
|
||||
paint_context);
|
||||
|
@ -52,6 +52,9 @@ void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *se
|
||||
void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks);
|
||||
|
||||
CoglScanout * meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||
CoglOnscreen *onscreen);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/meta-event-x11.h"
|
||||
#include "backends/x11/cm/meta-backend-x11-cm.h"
|
||||
#include "backends/x11/nested/meta-backend-x11-nested.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "compositor/compositor-private.h"
|
||||
#include "compositor/meta-compositor-x11.h"
|
||||
@ -81,6 +82,7 @@
|
||||
#include "x11/xprops.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "compositor/meta-compositor-native.h"
|
||||
#include "compositor/meta-compositor-server.h"
|
||||
#include "wayland/meta-xwayland-private.h"
|
||||
#include "wayland/meta-wayland-tablet-seat.h"
|
||||
@ -572,11 +574,16 @@ static MetaCompositor *
|
||||
create_compositor (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
return META_COMPOSITOR (meta_compositor_server_new (display));
|
||||
else
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
return META_COMPOSITOR (meta_compositor_native_new (display));
|
||||
#endif
|
||||
return META_COMPOSITOR (meta_compositor_x11_new (display));
|
||||
if (META_IS_BACKEND_X11_NESTED (backend))
|
||||
return META_COMPOSITOR (meta_compositor_server_new (display));
|
||||
#endif
|
||||
return META_COMPOSITOR (meta_compositor_x11_new (display));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -291,6 +291,8 @@ mutter_sources = [
|
||||
'compositor/meta-background-group.c',
|
||||
'compositor/meta-background-image.c',
|
||||
'compositor/meta-background-private.h',
|
||||
'compositor/meta-compositor-server.c',
|
||||
'compositor/meta-compositor-server.h',
|
||||
'compositor/meta-compositor-x11.c',
|
||||
'compositor/meta-compositor-x11.h',
|
||||
'compositor/meta-cullable.c',
|
||||
@ -477,8 +479,6 @@ if have_wayland
|
||||
'compositor/meta-surface-actor-wayland.h',
|
||||
'compositor/meta-window-actor-wayland.c',
|
||||
'compositor/meta-window-actor-wayland.h',
|
||||
'compositor/meta-compositor-server.c',
|
||||
'compositor/meta-compositor-server.h',
|
||||
'wayland/meta-cursor-sprite-wayland.c',
|
||||
'wayland/meta-cursor-sprite-wayland.h',
|
||||
'wayland/meta-pointer-confinement-wayland.c',
|
||||
@ -676,6 +676,8 @@ if have_native_backend
|
||||
'backends/native/meta-virtual-input-device-native.h',
|
||||
'backends/native/meta-xkb-utils.c',
|
||||
'backends/native/meta-xkb-utils.h',
|
||||
'compositor/meta-compositor-native.c',
|
||||
'compositor/meta-compositor-native.h',
|
||||
]
|
||||
endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user