diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 96e032f35..4dc6f4a70 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -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; diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index da2df2d61..0e386c479 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -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); } diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 463aaf0cf..aa1f28ea5 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -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); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 527c6ef12..9ad87ac2e 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -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) { diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index afd82b3a0..b5123265e 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -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