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:
parent
6330acfaa2
commit
7f93004809
@ -77,6 +77,7 @@ maybe_assign_primary_plane (MetaCompositor *compositor)
|
|||||||
MetaSurfaceActor *surface_actor;
|
MetaSurfaceActor *surface_actor;
|
||||||
MetaSurfaceActorWayland *surface_actor_wayland;
|
MetaSurfaceActorWayland *surface_actor_wayland;
|
||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
|
int geometry_scale;
|
||||||
MetaWaylandSurface *old_candidate =
|
MetaWaylandSurface *old_candidate =
|
||||||
compositor_native->current_scanout_candidate;
|
compositor_native->current_scanout_candidate;
|
||||||
MetaWaylandSurface *new_candidate = NULL;
|
MetaWaylandSurface *new_candidate = NULL;
|
||||||
@ -122,6 +123,11 @@ maybe_assign_primary_plane (MetaCompositor *compositor)
|
|||||||
if (!surface)
|
if (!surface)
|
||||||
goto done;
|
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;
|
new_candidate = surface;
|
||||||
|
|
||||||
onscreen = COGL_ONSCREEN (framebuffer);
|
onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
|
@ -2189,3 +2189,68 @@ meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
|||||||
g_object_notify_by_pspec (G_OBJECT (surface),
|
g_object_notify_by_pspec (G_OBJECT (surface),
|
||||||
obj_props[PROP_SCANOUT_CANDIDATE]);
|
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;
|
||||||
|
}
|
||||||
|
@ -368,6 +368,11 @@ MetaCrtc * meta_wayland_surface_get_scanout_candidate (MetaWaylandSurface *surfa
|
|||||||
void meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
void meta_wayland_surface_set_scanout_candidate (MetaWaylandSurface *surface,
|
||||||
MetaCrtc *crtc);
|
MetaCrtc *crtc);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_surface_can_scanout_untransformed (MetaWaylandSurface *surface,
|
||||||
|
MetaRendererView *view,
|
||||||
|
int geometry_scale);
|
||||||
|
|
||||||
static inline GNode *
|
static inline GNode *
|
||||||
meta_get_next_subsurface_sibling (GNode *n)
|
meta_get_next_subsurface_sibling (GNode *n)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user