mirror of
https://github.com/brl/mutter.git
synced 2024-11-27 10:30:47 -05:00
df3f81e709
If a Wayland subsurface is the topmost actor, consider in for scanout as well. This will extend our scanout capabilities to apps like Firefox While on it, correct a unnessary type check to a NULL check. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2211>
198 lines
5.7 KiB
C
198 lines
5.7 KiB
C
/*
|
|
* 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 "backends/native/meta-crtc-kms.h"
|
|
#include "compositor/meta-surface-actor-wayland.h"
|
|
|
|
struct _MetaCompositorNative
|
|
{
|
|
MetaCompositorServer parent;
|
|
|
|
MetaWaylandSurface *current_scanout_candidate;
|
|
};
|
|
|
|
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)
|
|
{
|
|
MetaCompositorNative *compositor_native = META_COMPOSITOR_NATIVE (compositor);
|
|
MetaBackend *backend = meta_get_backend ();
|
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
|
MetaWindowActor *window_actor;
|
|
MetaWindow *window;
|
|
MetaRendererView *view;
|
|
MetaCrtc *crtc;
|
|
CoglFramebuffer *framebuffer;
|
|
CoglOnscreen *onscreen;
|
|
MetaSurfaceActor *surface_actor;
|
|
MetaSurfaceActorWayland *surface_actor_wayland;
|
|
MetaWaylandSurface *surface;
|
|
MetaWaylandSurface *old_candidate =
|
|
compositor_native->current_scanout_candidate;
|
|
MetaWaylandSurface *new_candidate = NULL;
|
|
g_autoptr (CoglScanout) scanout = NULL;
|
|
|
|
if (meta_compositor_is_unredirect_inhibited (compositor))
|
|
goto done;
|
|
|
|
window_actor = meta_compositor_get_top_window_actor (compositor);
|
|
if (!window_actor)
|
|
goto done;
|
|
|
|
if (meta_window_actor_effect_in_progress (window_actor))
|
|
goto done;
|
|
|
|
if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
|
|
goto done;
|
|
|
|
window = meta_window_actor_get_meta_window (window_actor);
|
|
if (!window)
|
|
goto done;
|
|
|
|
view = get_window_view (renderer, window);
|
|
if (!view)
|
|
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));
|
|
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)))
|
|
goto done;
|
|
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);
|
|
scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
|
|
onscreen);
|
|
if (!scanout)
|
|
goto done;
|
|
|
|
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
|
|
meta_compositor_native_before_paint (MetaCompositor *compositor,
|
|
ClutterStageView *stage_view)
|
|
{
|
|
MetaCompositorClass *parent_class;
|
|
|
|
maybe_assign_primary_plane (compositor);
|
|
|
|
parent_class = META_COMPOSITOR_CLASS (meta_compositor_native_parent_class);
|
|
parent_class->before_paint (compositor, stage_view);
|
|
}
|
|
|
|
MetaCompositorNative *
|
|
meta_compositor_native_new (MetaDisplay *display,
|
|
MetaBackend *backend)
|
|
{
|
|
return g_object_new (META_TYPE_COMPOSITOR_NATIVE,
|
|
"display", display,
|
|
"backend", backend,
|
|
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
|
|
meta_compositor_native_init (MetaCompositorNative *compositor_native)
|
|
{
|
|
}
|
|
|
|
static void
|
|
meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_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;
|
|
}
|