From afd0a272cd9f13acca2d152f7bf68b1883190b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 2 Oct 2020 16:35:42 +0200 Subject: [PATCH] kms/update: Add way to receive result from later posted update Something might want to affect the next update that is going to be posted, but without posting it immediately. For example, changing the cursor might need to wait for mode setting. Make it possible to get feedback from posting the update, in order to gracefully handle any errors. Note, the API for notifiying about results take out the result listener from the update, and notifies them in an open coded for loop. The reason for this is that in the next commit we'll sometimes reuse updates, and we only want notify about the results once. Part-of: --- src/backends/native/meta-kms-update-private.h | 13 +++++++ src/backends/native/meta-kms-update.c | 39 +++++++++++++++++++ src/backends/native/meta-kms-update.h | 7 ++++ src/backends/native/meta-kms.c | 13 +++++++ 4 files changed, 72 insertions(+) diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 0cf1e85a4..a022e2864 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -93,6 +93,12 @@ typedef struct _MetaKmsPageFlipListener gpointer user_data; } MetaKmsPageFlipListener; +typedef struct _MetaKmsResultListener +{ + MetaKmsResultListenerFunc func; + gpointer user_data; +} MetaKmsResultListener; + void meta_kms_plane_feedback_free (MetaKmsPlaneFeedback *plane_feedback); MetaKmsPlaneFeedback * meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane, @@ -130,6 +136,13 @@ void meta_kms_update_get_custom_page_flip_func (MetaKmsUpdate *updat MetaKmsCustomPageFlipFunc *custom_page_flip_func, gpointer *custom_page_flip_user_data); +GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update); + +void meta_kms_result_listener_notify (MetaKmsResultListener *listener, + const MetaKmsFeedback *feedback); + +void meta_kms_result_listener_free (MetaKmsResultListener *listener); + G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsPlaneFeedback, meta_kms_plane_feedback_free) diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 00d8ec6bd..06bfc27c8 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -44,6 +44,7 @@ struct _MetaKmsUpdate gpointer custom_page_flip_user_data; GList *page_flip_listeners; + GList *result_listeners; }; void @@ -379,6 +380,42 @@ meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assi plane_assignment->cursor_hotspot.y = y; } +void +meta_kms_update_add_result_listener (MetaKmsUpdate *update, + MetaKmsResultListenerFunc func, + gpointer user_data) +{ + MetaKmsResultListener *listener; + + listener = g_new0 (MetaKmsResultListener, 1); + *listener = (MetaKmsResultListener) { + .func = func, + .user_data = user_data, + }; + + update->result_listeners = g_list_append (update->result_listeners, + listener); +} + +GList * +meta_kms_update_take_result_listeners (MetaKmsUpdate *update) +{ + return g_steal_pointer (&update->result_listeners); +} + +void +meta_kms_result_listener_notify (MetaKmsResultListener *listener, + const MetaKmsFeedback *feedback) +{ + listener->func (feedback, listener->user_data); +} + +void +meta_kms_result_listener_free (MetaKmsResultListener *listener) +{ + g_free (listener); +} + MetaKmsPlaneAssignment * meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update, MetaKmsCrtc *crtc) @@ -467,6 +504,8 @@ meta_kms_update_new (MetaKmsDevice *device) void meta_kms_update_free (MetaKmsUpdate *update) { + g_list_free_full (update->result_listeners, + (GDestroyNotify) meta_kms_result_listener_free); g_list_free_full (update->plane_assignments, (GDestroyNotify) meta_kms_plane_assignment_free); g_list_free_full (update->mode_sets, diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 9e69c5334..aa3cbb11d 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -69,6 +69,9 @@ typedef struct _MetaKmsPlaneFeedback GError *error; } MetaKmsPlaneFeedback; +typedef void (* MetaKmsResultListenerFunc) (const MetaKmsFeedback *feedback, + gpointer user_data); + void meta_kms_feedback_free (MetaKmsFeedback *feedback); MetaKmsFeedbackResult meta_kms_feedback_get_result (const MetaKmsFeedback *feedback); @@ -130,6 +133,10 @@ void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane int x, int y); +void meta_kms_update_add_result_listener (MetaKmsUpdate *update, + MetaKmsResultListenerFunc func, + gpointer user_data); + static inline MetaFixed16 meta_fixed_16_from_int (int16_t d) { diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index f4c2b6848..bcbf4ed7c 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -251,6 +251,8 @@ meta_kms_post_pending_update_sync (MetaKms *kms, { MetaKmsUpdate *update; MetaKmsFeedback *feedback; + GList *result_listeners; + GList *l; COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, "KMS (post update)"); @@ -266,6 +268,17 @@ meta_kms_post_pending_update_sync (MetaKms *kms, update, NULL); + result_listeners = meta_kms_update_take_result_listeners (update); + + for (l = result_listeners; l; l = l->next) + { + MetaKmsResultListener *listener = l->data; + + meta_kms_result_listener_notify (listener, feedback); + meta_kms_result_listener_free (listener); + } + g_list_free (result_listeners); + meta_kms_update_free (update); return feedback;