window-actor/wayland: Update scanout candidate check

In a following commit we will start supporting scaled and croped
surfaces, thus, in preparation, update the logic to three common cases:
1. only one surface, fullscreen (most apps)
2. a content surface and a black background surface which the client
   does not want to unmap, fullscreen
3. top-level subsurface covers the whole window and is opaque (Firefox)

The remaining currently supported cases should be fairly uncommen and
and harder to compute.

Note that we already check that the window cover the stage view in
MetaCompositorView.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3177>
This commit is contained in:
Robert Mader 2023-12-19 23:30:58 +01:00 committed by Marge Bot
parent 50f8f1e8b3
commit ed50cbbfe4

View File

@ -25,6 +25,8 @@
#include "compositor/meta-surface-actor-wayland.h" #include "compositor/meta-surface-actor-wayland.h"
#include "compositor/meta-window-actor-wayland.h" #include "compositor/meta-window-actor-wayland.h"
#include "meta/meta-window-actor.h" #include "meta/meta-window-actor.h"
#include "wayland/meta-wayland-buffer.h"
#include "wayland/meta-wayland-single-pixel-buffer.h"
#include "wayland/meta-wayland-surface-private.h" #include "wayland/meta-wayland-surface-private.h"
#include "wayland/meta-window-wayland.h" #include "wayland/meta-window-wayland.h"
@ -348,8 +350,10 @@ meta_window_actor_wayland_get_scanout_candidate (MetaWindowActor *actor)
ClutterActor *child_actor; ClutterActor *child_actor;
ClutterActorIter iter; ClutterActorIter iter;
MetaSurfaceActor *topmost_surface_actor = NULL; MetaSurfaceActor *topmost_surface_actor = NULL;
MetaWindow *window;
int n_mapped_surfaces = 0; int n_mapped_surfaces = 0;
MetaWindow *window;
ClutterActorBox window_box;
ClutterActorBox surface_box;
if (clutter_actor_get_last_child (CLUTTER_ACTOR (self)) != surface_container) if (clutter_actor_get_last_child (CLUTTER_ACTOR (self)) != surface_container)
{ {
@ -376,15 +380,52 @@ meta_window_actor_wayland_get_scanout_candidate (MetaWindowActor *actor)
} }
window = meta_window_actor_get_meta_window (actor); window = meta_window_actor_get_meta_window (actor);
if (!meta_surface_actor_is_opaque (topmost_surface_actor) && if (meta_window_is_fullscreen (window) && n_mapped_surfaces == 1)
!(meta_window_is_fullscreen (window) && n_mapped_surfaces == 1)) return topmost_surface_actor;
if (meta_window_is_fullscreen (window) && n_mapped_surfaces == 2)
{ {
meta_topic (META_DEBUG_RENDER, MetaSurfaceActorWayland *bg_surface_actor = NULL;
"Window-actor is not opaque"); MetaWaylandSurface *bg_surface;
return NULL; MetaWaylandBuffer *buffer;
clutter_actor_iter_init (&iter, surface_container);
while (clutter_actor_iter_next (&iter, &child_actor))
{
if (!clutter_actor_is_mapped (child_actor))
continue;
bg_surface_actor = META_SURFACE_ACTOR_WAYLAND (child_actor);
break;
}
g_assert (bg_surface_actor);
bg_surface = meta_surface_actor_wayland_get_surface (bg_surface_actor);
buffer = meta_wayland_surface_get_buffer (bg_surface);
if (buffer->type == META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL)
{
MetaWaylandSinglePixelBuffer *sp_buffer;
sp_buffer = meta_wayland_single_pixel_buffer_from_buffer (buffer);
if (sp_buffer &&
meta_wayland_single_pixel_buffer_is_opaque_black (sp_buffer))
return topmost_surface_actor;
}
} }
if (meta_surface_actor_is_opaque (topmost_surface_actor) &&
clutter_actor_get_paint_box (CLUTTER_ACTOR (actor), &window_box) &&
clutter_actor_get_paint_box (CLUTTER_ACTOR (topmost_surface_actor),
&surface_box) &&
G_APPROX_VALUE (window_box.x1, surface_box.x1, CLUTTER_COORDINATE_EPSILON) &&
G_APPROX_VALUE (window_box.y1, surface_box.y1, CLUTTER_COORDINATE_EPSILON) &&
G_APPROX_VALUE (window_box.x2, surface_box.x2, CLUTTER_COORDINATE_EPSILON) &&
G_APPROX_VALUE (window_box.y2, surface_box.y2, CLUTTER_COORDINATE_EPSILON))
return topmost_surface_actor; return topmost_surface_actor;
meta_topic (META_DEBUG_RENDER,
"Could not find suitable scanout candidate for window-actor");
return NULL;
} }
static void static void