cursor-renderer-native: Handle lack of cursor planes gracefully

While we will always have cursor planes, as we'll currently create fake
ones when real ones are missing (See #1058), eventually we will run into
situations where we can't create fake ones, for example for atomic KMS
drivers that don't advertise any cursor planes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079
This commit is contained in:
Jonas Ådahl 2020-02-21 12:08:34 +01:00 committed by Florian Müllner
parent 227eea1e31
commit 6e966e47f2

View File

@ -308,15 +308,16 @@ unset_crtc_cursor (MetaCursorRendererNative *native,
MetaKmsDevice *kms_device;
MetaKmsPlane *cursor_plane;
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
kms_device = meta_kms_crtc_get_device (kms_crtc);
cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
g_return_if_fail (cursor_plane);
if (!priv->hw_state_invalidated && !crtc->cursor_renderer_private)
return;
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
kms_device = meta_kms_crtc_get_device (kms_crtc);
cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
if (cursor_plane)
meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
crtc->cursor_renderer_private = NULL;
}
@ -645,6 +646,67 @@ get_current_relative_transform (MetaCursorSprite *cursor_sprite)
return cursor_priv->preprocess_state.current_relative_transform;
}
static void
has_cursor_plane (MetaLogicalMonitor *logical_monitor,
MetaMonitor *monitor,
MetaOutput *output,
MetaCrtc *crtc,
gpointer user_data)
{
gboolean *has_cursor_planes = user_data;
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
*has_cursor_planes &= !!meta_kms_device_get_cursor_plane_for (kms_device,
kms_crtc);
}
static gboolean
crtcs_has_cursor_planes (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNative *cursor_renderer_native =
META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaBackend *backend = priv->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
graphene_rect_t cursor_rect;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
MetaRectangle logical_monitor_layout;
graphene_rect_t logical_monitor_rect;
gboolean has_cursor_planes;
logical_monitor_layout =
meta_logical_monitor_get_layout (logical_monitor);
logical_monitor_rect =
meta_rectangle_to_graphene_rect (&logical_monitor_layout);
if (!graphene_rect_intersection (&cursor_rect, &logical_monitor_rect,
NULL))
continue;
has_cursor_planes = TRUE;
meta_logical_monitor_foreach_crtc (logical_monitor,
has_cursor_plane,
&has_cursor_planes);
if (!has_cursor_planes)
return FALSE;
}
return TRUE;
}
static gboolean
get_common_crtc_sprite_scale_for_logical_monitors (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
@ -784,6 +846,9 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
return FALSE;
}
if (!crtcs_has_cursor_planes (renderer, cursor_sprite))
return FALSE;
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return FALSE;