diff --git a/src/compositor/meta-compositor-native.c b/src/compositor/meta-compositor-native.c index dd77bb7ae..6a046060a 100644 --- a/src/compositor/meta-compositor-native.c +++ b/src/compositor/meta-compositor-native.c @@ -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); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index fcac0af4f..3bbe82456 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -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; +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index bd2cf6377..ccbbb7ed8 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -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) {