kms: Allow update passing with failed plane assignments

This will later make it possible to pass cursor plane assignments,
together with a complete update including the primary plane, but not
failing the whole update if just processing the cursor plane failed.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-10-02 15:45:28 +02:00 committed by Marge Bot
parent a2b8668544
commit 411ec5fd18
5 changed files with 55 additions and 74 deletions

View File

@ -306,7 +306,7 @@ set_crtc_cursor (MetaCursorRendererNative *native,
.height = cursor_height, .height = cursor_height,
}; };
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE; flags = META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL;
crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms); crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
if (!priv->hw_state_invalidated && buffer == crtc_buffer) if (!priv->hw_state_invalidated && buffer == crtc_buffer)
flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED; flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
@ -593,19 +593,18 @@ update_hw_cursor (MetaCursorRendererNative *native,
MetaKmsDevice *kms_device = l->data; MetaKmsDevice *kms_device = l->data;
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
g_autoptr (MetaKmsFeedback) feedback = NULL; g_autoptr (MetaKmsFeedback) feedback = NULL;
GList *l_feedback;
kms_update = meta_kms_get_pending_update (kms, kms_device); kms_update = meta_kms_get_pending_update (kms, kms_device);
if (!kms_update) if (!kms_update)
continue; continue;
feedback = meta_kms_post_pending_update_sync (kms, kms_device); feedback = meta_kms_post_pending_update_sync (kms, kms_device);
if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED) for (l_feedback = meta_kms_feedback_get_failed_planes (feedback);
l_feedback;
l_feedback = l_feedback->next)
{ {
GList *k; MetaKmsPlaneFeedback *plane_feedback = l_feedback->data;
for (k = meta_kms_feedback_get_failed_planes (feedback); k; k = k->next)
{
MetaKmsPlaneFeedback *plane_feedback = k->data;
if (!g_error_matches (plane_feedback->error, if (!g_error_matches (plane_feedback->error,
G_IO_ERROR, G_IO_ERROR,
@ -618,7 +617,6 @@ update_hw_cursor (MetaCursorRendererNative *native,
priv->has_hw_cursor = FALSE; priv->has_hw_cursor = FALSE;
} }
}
priv->hw_state_invalidated = FALSE; priv->hw_state_invalidated = FALSE;

View File

@ -950,11 +950,12 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
g_assert_not_reached (); g_assert_not_reached ();
} }
static GList * static gboolean
process_plane_assignments (MetaKmsImplDevice *impl_device, process_plane_assignments (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update) MetaKmsUpdate *update,
GList **failed_planes,
GError **error)
{ {
GList *failed_planes = NULL;
GList *l; GList *l;
for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next) for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next)
@ -964,46 +965,31 @@ process_plane_assignments (MetaKmsImplDevice *impl_device,
if (!process_plane_assignment (impl_device, update, plane_assignment, if (!process_plane_assignment (impl_device, update, plane_assignment,
&plane_feedback)) &plane_feedback))
failed_planes = g_list_prepend (failed_planes, plane_feedback); {
if (g_error_matches (plane_feedback->error,
G_IO_ERROR,
G_IO_ERROR_PERMISSION_DENIED))
{
g_propagate_error (error,
g_steal_pointer (&plane_feedback->error));
meta_kms_plane_feedback_free (plane_feedback);
return FALSE;
} }
return failed_planes; *failed_planes = g_list_prepend (*failed_planes, plane_feedback);
} if (plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL)
static GList *
generate_all_failed_feedbacks (MetaKmsUpdate *update)
{ {
GList *failed_planes = NULL;
GList *l;
for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next)
{
MetaKmsPlaneAssignment *plane_assignment = l->data;
MetaKmsPlane *plane;
MetaKmsPlaneType plane_type;
MetaKmsPlaneFeedback *plane_feedback;
plane = plane_assignment->plane;
plane_type = meta_kms_plane_get_plane_type (plane);
switch (plane_type)
{
case META_KMS_PLANE_TYPE_PRIMARY:
continue; continue;
case META_KMS_PLANE_TYPE_CURSOR: }
case META_KMS_PLANE_TYPE_OVERLAY: else
break; {
g_propagate_error (error, g_error_copy (plane_feedback->error));
return FALSE;
}
}
} }
plane_feedback = return TRUE;
meta_kms_plane_feedback_new_take_error (plane_assignment->plane,
plane_assignment->crtc,
g_error_new (G_IO_ERROR,
G_IO_ERROR_FAILED,
"Discarded"));
failed_planes = g_list_prepend (failed_planes, plane_feedback);
}
return failed_planes;
} }
static MetaKmsFeedback * static MetaKmsFeedback *
@ -1011,50 +997,42 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update) MetaKmsUpdate *update)
{ {
GError *error = NULL; GError *error = NULL;
GList *failed_planes; GList *failed_planes = NULL;
if (!process_entries (impl_device, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_connector_updates (update), meta_kms_update_get_connector_updates (update),
process_connector_update, process_connector_update,
&error)) &error))
goto err_planes_not_assigned; goto err;
if (!process_entries (impl_device, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_mode_sets (update), meta_kms_update_get_mode_sets (update),
process_mode_set, process_mode_set,
&error)) &error))
goto err_planes_not_assigned; goto err;
if (!process_entries (impl_device, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_crtc_gammas (update), meta_kms_update_get_crtc_gammas (update),
process_crtc_gamma, process_crtc_gamma,
&error)) &error))
goto err_planes_not_assigned; goto err;
failed_planes = process_plane_assignments (impl_device, update); if (!process_plane_assignments (impl_device, update, &failed_planes, &error))
if (failed_planes) goto err;
{
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to assign one or more planes");
goto err_planes_assigned;
}
if (!process_entries (impl_device, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_page_flips (update), meta_kms_update_get_page_flips (update),
process_page_flip, process_page_flip,
&error)) &error))
goto err_planes_assigned; goto err;
return meta_kms_feedback_new_passed (); return meta_kms_feedback_new_passed (failed_planes);
err_planes_not_assigned: err:
failed_planes = generate_all_failed_feedbacks (update);
err_planes_assigned:
return meta_kms_feedback_new_failed (failed_planes, error); return meta_kms_feedback_new_failed (failed_planes, error);
} }

View File

@ -99,7 +99,7 @@ MetaKmsPlaneFeedback * meta_kms_plane_feedback_new_take_error (MetaKmsPlane *pla
MetaKmsCrtc *crtc, MetaKmsCrtc *crtc,
GError *error); GError *error);
MetaKmsFeedback * meta_kms_feedback_new_passed (void); MetaKmsFeedback * meta_kms_feedback_new_passed (GList *failed_planes);
MetaKmsFeedback * meta_kms_feedback_new_failed (GList *failed_planes, MetaKmsFeedback * meta_kms_feedback_new_failed (GList *failed_planes,
GError *error); GError *error);

View File

@ -70,13 +70,14 @@ meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane,
} }
MetaKmsFeedback * MetaKmsFeedback *
meta_kms_feedback_new_passed (void) meta_kms_feedback_new_passed (GList *failed_planes)
{ {
MetaKmsFeedback *feedback; MetaKmsFeedback *feedback;
feedback = g_new0 (MetaKmsFeedback, 1); feedback = g_new0 (MetaKmsFeedback, 1);
*feedback = (MetaKmsFeedback) { *feedback = (MetaKmsFeedback) {
.result = META_KMS_FEEDBACK_PASSED, .result = META_KMS_FEEDBACK_PASSED,
.failed_planes = failed_planes,
}; };
return feedback; return feedback;
@ -152,6 +153,9 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update,
g_assert (!meta_kms_update_is_sealed (update)); g_assert (!meta_kms_update_is_sealed (update));
g_assert (meta_kms_crtc_get_device (crtc) == update->device); g_assert (meta_kms_crtc_get_device (crtc) == update->device);
g_assert (meta_kms_plane_get_device (plane) == update->device); g_assert (meta_kms_plane_get_device (plane) == update->device);
g_assert (meta_kms_plane_get_plane_type (plane) !=
META_KMS_PLANE_TYPE_PRIMARY ||
!(flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL));
plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1); plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
*plane_assignment = (MetaKmsPlaneAssignment) { *plane_assignment = (MetaKmsPlaneAssignment) {

View File

@ -40,6 +40,7 @@ typedef enum _MetaKmsAssignPlaneFlag
{ {
META_KMS_ASSIGN_PLANE_FLAG_NONE = 0, META_KMS_ASSIGN_PLANE_FLAG_NONE = 0,
META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED = 1 << 0, META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED = 1 << 0,
META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
} MetaKmsAssignPlaneFlag; } MetaKmsAssignPlaneFlag;
struct _MetaKmsPageFlipFeedback struct _MetaKmsPageFlipFeedback