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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-10-02 16:35:42 +02:00 committed by Marge Bot
parent 5c7e2bfe22
commit afd0a272cd
4 changed files with 72 additions and 0 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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)
{

View File

@ -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;