diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index f1b7459fe..f9dcee470 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -361,6 +361,7 @@ assign_cursor_plane (MetaCursorRendererNative *native, cursor_hotspot_y); meta_kms_update_add_result_listener (kms_update, + NULL, on_kms_update_result, native); diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 962117a92..477b2dd53 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -128,6 +128,7 @@ typedef struct _MetaKmsPageFlipListener struct _MetaKmsResultListener { + GMainContext *main_context; MetaKmsResultListenerFunc func; gpointer user_data; @@ -191,8 +192,11 @@ MetaKmsCustomPageFlip * meta_kms_update_take_custom_page_flip_func (MetaKmsUpdat void meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update, MetaKmsPlane *plane); +META_EXPORT_TEST GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update); +GMainContext * meta_kms_result_listener_get_main_context (MetaKmsResultListener *listener); + void meta_kms_result_listener_set_feedback (MetaKmsResultListener *listener, MetaKmsFeedback *feedback); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index d7588124e..0c9cdf22b 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -607,6 +607,7 @@ meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assi void meta_kms_update_add_result_listener (MetaKmsUpdate *update, + GMainContext *main_context, MetaKmsResultListenerFunc func, gpointer user_data) { @@ -614,6 +615,7 @@ meta_kms_update_add_result_listener (MetaKmsUpdate *update, listener = g_new0 (MetaKmsResultListener, 1); *listener = (MetaKmsResultListener) { + .main_context = main_context, .func = func, .user_data = user_data, }; @@ -628,6 +630,12 @@ meta_kms_update_take_result_listeners (MetaKmsUpdate *update) return g_steal_pointer (&update->result_listeners); } +GMainContext * +meta_kms_result_listener_get_main_context (MetaKmsResultListener *listener) +{ + return listener->main_context; +} + void meta_kms_result_listener_set_feedback (MetaKmsResultListener *listener, MetaKmsFeedback *feedback) diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 8024a3f33..f98bcceaf 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -92,6 +92,7 @@ GList * meta_kms_feedback_get_failed_planes (const MetaKmsFeedback *feedback); const GError * meta_kms_feedback_get_error (const MetaKmsFeedback *feedback); +META_EXPORT_TEST void meta_kms_feedback_dispatch_result (MetaKmsFeedback *feedback, MetaKms *kms, GList *result_listeners); @@ -183,6 +184,7 @@ void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane META_EXPORT_TEST void meta_kms_update_add_result_listener (MetaKmsUpdate *update, + GMainContext *main_context, MetaKmsResultListenerFunc func, gpointer user_data); diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 158e34aaa..48915814a 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -169,8 +169,11 @@ void meta_kms_queue_result_callback (MetaKms *kms, MetaKmsResultListener *listener) { + GMainContext *main_context = + meta_kms_result_listener_get_main_context (listener); + meta_kms_queue_callback (kms, - NULL, + main_context, invoke_result_listener, listener, (GDestroyNotify) meta_kms_result_listener_free); diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 850fadf6d..a7e463bb5 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -1171,6 +1171,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); meta_kms_update_add_result_listener (kms_update, + NULL, on_swap_buffer_update_result, onscreen_native); @@ -1389,6 +1390,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); meta_kms_update_add_result_listener (kms_update, + NULL, on_scanout_update_result, onscreen_native); @@ -1542,6 +1544,7 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, } meta_kms_update_add_result_listener (kms_update, + NULL, on_finish_frame_update_result, onscreen_native); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 4da361e2b..10fb7bbba 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -865,6 +865,7 @@ post_mode_set_updates (MetaRendererNative *renderer_native) g_hash_table_iter_steal (&iter); meta_kms_update_add_result_listener (kms_update, + NULL, on_mode_sets_update_result, NULL); diff --git a/src/tests/native-kms-render.c b/src/tests/native-kms-render.c index 1557b764e..b19035237 100644 --- a/src/tests/native-kms-render.c +++ b/src/tests/native-kms-render.c @@ -376,6 +376,7 @@ on_scanout_fallback_before_paint (ClutterStage *stage, kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); meta_kms_update_add_result_listener (kms_update, + NULL, on_scanout_fallback_result, test); test->scanout_fallback.scanout_failed_view = stage_view; diff --git a/src/tests/native-kms-updates.c b/src/tests/native-kms-updates.c index 3ce063d74..6f09b0143 100644 --- a/src/tests/native-kms-updates.c +++ b/src/tests/native-kms-updates.c @@ -22,6 +22,7 @@ #include +#include "backends/native/meta-backend-native.h" #include "backends/native/meta-kms-connector.h" #include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-device.h" @@ -744,6 +745,110 @@ meta_test_kms_update_off_thread_page_flip (void) g_mutex_clear (&data.init_mutex); } +typedef struct +{ + GMutex init_mutex; + GCond init_cond; + gboolean initialized; + + GMainContext *thread_main_context; + GMainLoop *thread_loop; + GThread *thread; + + GMainLoop *main_thread_loop; +} CallbackData; + +static gpointer +off_thread_callback_thread_func (gpointer user_data) +{ + CallbackData *data = user_data; + MetaBackend *backend = meta_context_get_backend (test_context); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + + meta_thread_register_callback_context (META_THREAD (kms), + data->thread_main_context); + + data->thread_loop = g_main_loop_new (data->thread_main_context, FALSE); + + g_mutex_lock (&data->init_mutex); + data->initialized = TRUE; + g_cond_signal (&data->init_cond); + g_mutex_unlock (&data->init_mutex); + + g_assert (data->thread == g_thread_self ()); + + g_main_loop_run (data->thread_loop); + g_main_loop_unref (data->thread_loop); + + meta_thread_unregister_callback_context (META_THREAD (kms), + data->thread_main_context); + + return GINT_TO_POINTER (TRUE); +} + +static void +on_main_thread_result (const MetaKmsFeedback *feedback, + gpointer user_data) +{ + CallbackData *data = user_data; + + g_main_loop_quit (data->main_thread_loop); +} + +static void +on_callback_thread_result (const MetaKmsFeedback *feedback, + gpointer user_data) +{ + CallbackData *data = user_data; + + g_main_loop_quit (data->thread_loop); +} + +static void +meta_test_kms_update_feedback (void) +{ + CallbackData data = {}; + MetaKmsDevice *device; + MetaKmsUpdate *update; + g_autoptr (MetaDrmBuffer) buffer = NULL; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + + data.main_thread_loop = g_main_loop_new (NULL, FALSE); + + g_mutex_init (&data.init_mutex); + g_cond_init (&data.init_cond); + g_mutex_lock (&data.init_mutex); + data.thread_main_context = g_main_context_new (); + data.thread = g_thread_new ("Callback test thread", + off_thread_callback_thread_func, + &data); + while (!data.initialized) + g_cond_wait (&data.init_cond, &data.init_mutex); + g_mutex_unlock (&data.init_mutex); + + device = meta_get_test_kms_device (test_context); + update = meta_kms_update_new (device); + populate_update (update, &buffer, POPULATE_UPDATE_FLAG_MODE); + + meta_kms_update_add_result_listener (update, NULL, + on_main_thread_result, + &data); + meta_kms_update_add_result_listener (update, data.thread_main_context, + on_callback_thread_result, + &data); + + kms_feedback = meta_kms_device_process_update_sync (device, update, + META_KMS_UPDATE_FLAG_NONE); + + g_main_loop_run (data.main_thread_loop); + + g_assert_cmpint (GPOINTER_TO_INT (g_thread_join (data.thread)), ==, TRUE); + g_main_context_unref (data.thread_main_context); + g_mutex_clear (&data.init_mutex); + g_cond_clear (&data.init_cond); +} + static void init_tests (void) { @@ -761,6 +866,8 @@ init_tests (void) meta_test_kms_update_merge); g_test_add_func ("/backends/native/kms/update/off-thread-page-flip", meta_test_kms_update_off_thread_page_flip); + g_test_add_func ("/backends/native/kms/update/feedback", + meta_test_kms_update_feedback); } int