1
0
Fork 0

compositor/native: Check that the surface can be scanned out untransformed

Before scanning out the surface of a native client we have
to check the following attributes that influence the
relationship between buffer and the defined result on screen:
 - buffer scale
 - buffer transform
 - viewport

In the future we can loose these checks again in cases where the
display hardware supports the required operations (scaling, cropping
and rotating).

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2276>
This commit is contained in:
Robert Mader 2022-02-08 20:23:27 +01:00 committed by Marge Bot
parent 6330acfaa2
commit 7f93004809
3 changed files with 76 additions and 0 deletions

View file

@ -77,6 +77,7 @@ maybe_assign_primary_plane (MetaCompositor *compositor)
MetaSurfaceActor *surface_actor;
MetaSurfaceActorWayland *surface_actor_wayland;
MetaWaylandSurface *surface;
int geometry_scale;
MetaWaylandSurface *old_candidate =
compositor_native->current_scanout_candidate;
MetaWaylandSurface *new_candidate = NULL;
@ -122,6 +123,11 @@ maybe_assign_primary_plane (MetaCompositor *compositor)
if (!surface)
goto done;
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
if (!meta_wayland_surface_can_scanout_untransformed (surface, view,
geometry_scale))
goto done;
new_candidate = surface;
onscreen = COGL_ONSCREEN (framebuffer);

View file

@ -2189,3 +2189,68 @@ meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
g_object_notify_by_pspec (G_OBJECT (surface),
obj_props[PROP_SCANOUT_CANDIDATE]);
}
gboolean
meta_wayland_surface_can_scanout_untransformed (MetaWaylandSurface *surface,
MetaRendererView *view,
int geometry_scale)
{
if (meta_renderer_view_get_transform (view) != surface->buffer_transform)
return FALSE;
if (surface->viewport.has_dst_size)
{
MetaRectangle view_layout;
float view_scale;
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
view_scale = clutter_stage_view_get_scale (CLUTTER_STAGE_VIEW (view));
if (!G_APPROX_VALUE (view_layout.width, surface->viewport.dst_width,
FLT_EPSILON) ||
!G_APPROX_VALUE (view_layout.height, surface->viewport.dst_height,
FLT_EPSILON) ||
!G_APPROX_VALUE (view_layout.width * view_scale,
get_buffer_width (surface),
FLT_EPSILON) ||
!G_APPROX_VALUE (view_layout.height * view_scale,
get_buffer_height (surface),
FLT_EPSILON))
return FALSE;
}
else
{
if (meta_is_stage_views_scaled ())
{
float view_scale;
view_scale = clutter_stage_view_get_scale (CLUTTER_STAGE_VIEW (view));
if (!G_APPROX_VALUE (view_scale, surface->scale, FLT_EPSILON))
return FALSE;
}
else
{
if (geometry_scale != surface->scale)
return FALSE;
}
}
if (surface->viewport.has_src_rect)
{
if (!G_APPROX_VALUE (surface->viewport.src_rect.origin.x, 0.0,
FLT_EPSILON) ||
!G_APPROX_VALUE (surface->viewport.src_rect.origin.y, 0.0,
FLT_EPSILON) ||
!G_APPROX_VALUE (surface->viewport.src_rect.size.width *
surface->scale,
get_buffer_width (surface),
FLT_EPSILON) ||
!G_APPROX_VALUE (surface->viewport.src_rect.size.height *
surface->scale,
get_buffer_height (surface),
FLT_EPSILON))
return FALSE;
}
return TRUE;
}

View file

@ -368,6 +368,11 @@ MetaCrtc * meta_wayland_surface_get_scanout_candidate (MetaWaylandSurface *surfa
void meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
MetaCrtc *crtc);
gboolean
meta_wayland_surface_can_scanout_untransformed (MetaWaylandSurface *surface,
MetaRendererView *view,
int geometry_scale);
static inline GNode *
meta_get_next_subsurface_sibling (GNode *n)
{