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,
};
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);
if (!priv->hw_state_invalidated && buffer == crtc_buffer)
flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
@ -593,31 +593,29 @@ update_hw_cursor (MetaCursorRendererNative *native,
MetaKmsDevice *kms_device = l->data;
MetaKmsUpdate *kms_update;
g_autoptr (MetaKmsFeedback) feedback = NULL;
GList *l_feedback;
kms_update = meta_kms_get_pending_update (kms, kms_device);
if (!kms_update)
continue;
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)
if (!g_error_matches (plane_feedback->error,
G_IO_ERROR,
G_IO_ERROR_PERMISSION_DENIED))
{
MetaKmsPlaneFeedback *plane_feedback = k->data;
if (!g_error_matches (plane_feedback->error,
G_IO_ERROR,
G_IO_ERROR_PERMISSION_DENIED))
{
disable_hw_cursor_for_crtc (plane_feedback->crtc,
plane_feedback->error);
}
disable_hw_cursor_for_crtc (plane_feedback->crtc,
plane_feedback->error);
}
priv->has_hw_cursor = FALSE;
}
priv->has_hw_cursor = FALSE;
}
priv->hw_state_invalidated = FALSE;

View File

@ -950,11 +950,12 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
g_assert_not_reached ();
}
static GList *
process_plane_assignments (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update)
static gboolean
process_plane_assignments (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update,
GList **failed_planes,
GError **error)
{
GList *failed_planes = NULL;
GList *l;
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,
&plane_feedback))
failed_planes = g_list_prepend (failed_planes, plane_feedback);
}
return failed_planes;
}
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;
case META_KMS_PLANE_TYPE_CURSOR:
case META_KMS_PLANE_TYPE_OVERLAY:
break;
}
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;
}
plane_feedback =
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);
*failed_planes = g_list_prepend (*failed_planes, plane_feedback);
if (plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL)
{
continue;
}
else
{
g_propagate_error (error, g_error_copy (plane_feedback->error));
return FALSE;
}
}
}
return failed_planes;
return TRUE;
}
static MetaKmsFeedback *
@ -1011,50 +997,42 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update)
{
GError *error = NULL;
GList *failed_planes;
GList *failed_planes = NULL;
if (!process_entries (impl_device,
update,
meta_kms_update_get_connector_updates (update),
process_connector_update,
&error))
goto err_planes_not_assigned;
goto err;
if (!process_entries (impl_device,
update,
meta_kms_update_get_mode_sets (update),
process_mode_set,
&error))
goto err_planes_not_assigned;
goto err;
if (!process_entries (impl_device,
update,
meta_kms_update_get_crtc_gammas (update),
process_crtc_gamma,
&error))
goto err_planes_not_assigned;
goto err;
failed_planes = process_plane_assignments (impl_device, update);
if (failed_planes)
{
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to assign one or more planes");
goto err_planes_assigned;
}
if (!process_plane_assignments (impl_device, update, &failed_planes, &error))
goto err;
if (!process_entries (impl_device,
update,
meta_kms_update_get_page_flips (update),
process_page_flip,
&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:
failed_planes = generate_all_failed_feedbacks (update);
err_planes_assigned:
err:
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,
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,
GError *error);

View File

@ -70,13 +70,14 @@ meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane,
}
MetaKmsFeedback *
meta_kms_feedback_new_passed (void)
meta_kms_feedback_new_passed (GList *failed_planes)
{
MetaKmsFeedback *feedback;
feedback = g_new0 (MetaKmsFeedback, 1);
*feedback = (MetaKmsFeedback) {
.result = META_KMS_FEEDBACK_PASSED,
.failed_planes = failed_planes,
};
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_crtc_get_device (crtc) == 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 = (MetaKmsPlaneAssignment) {

View File

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