diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 131a687e2..e3ed02894 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -609,6 +609,7 @@ init_gpus (MetaBackendNative *native, { MetaBackend *backend = META_BACKEND (native); MetaUdev *udev = meta_backend_native_get_udev (native); + MetaKms *kms = meta_backend_native_get_kms (native); g_autoptr (GError) local_error = NULL; MetaUdevDeviceType device_type = 0; GList *devices; @@ -669,6 +670,8 @@ init_gpus (MetaBackendNative *native, g_list_free_full (devices, g_object_unref); + meta_kms_notify_probed (kms); + if (!meta_backend_is_headless (backend) && g_list_length (meta_backend_get_gpus (backend)) == 0) { diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 6758982a6..f73aecac7 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -108,6 +108,8 @@ typedef struct _MetaKmsImplDevicePrivate GHashTable *crtc_frames; + gboolean realtime_inhibited_pending_mode_set; + MetaDeadlineTimerState deadline_timer_state; gboolean sync_file_retrieved; @@ -1734,6 +1736,12 @@ process_mode_set_update (MetaKmsImplDevice *impl_device, feedback = do_process (impl_device, NULL, update, flags); meta_thread_uninhibit_realtime_in_impl (thread); + if (priv->realtime_inhibited_pending_mode_set) + { + priv->realtime_inhibited_pending_mode_set = FALSE; + meta_thread_uninhibit_realtime_in_impl (thread); + } + return feedback; } @@ -1924,6 +1932,15 @@ meta_kms_impl_device_finalize (GObject *object) MetaKmsImplDevicePrivate *priv = meta_kms_impl_device_get_instance_private (impl_device); + if (priv->realtime_inhibited_pending_mode_set) + { + MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl); + MetaThread *thread = meta_thread_impl_get_thread (thread_impl); + + priv->realtime_inhibited_pending_mode_set = FALSE; + meta_thread_uninhibit_realtime_in_impl (thread); + } + meta_kms_impl_remove_impl_device (priv->impl, impl_device); g_list_free_full (priv->planes, g_object_unref); @@ -1973,6 +1990,16 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device, update_connectors (impl_device, drm_resources, 0); + if (!priv->crtcs) + { + MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl); + MetaThread *thread = meta_thread_impl_get_thread (thread_impl); + + g_warn_if_fail (priv->realtime_inhibited_pending_mode_set); + meta_thread_uninhibit_realtime_in_impl (thread); + priv->realtime_inhibited_pending_mode_set = FALSE; + } + drmModeFreeResources (drm_resources); return TRUE; @@ -2050,6 +2077,8 @@ meta_kms_impl_device_initable_init (GInitable *initable, MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable); MetaKmsImplDevicePrivate *priv = meta_kms_impl_device_get_instance_private (impl_device); + MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl); + MetaThread *thread = meta_thread_impl_get_thread (thread_impl); int fd; if (!ensure_device_file (impl_device, error)) @@ -2075,6 +2104,9 @@ meta_kms_impl_device_initable_init (GInitable *initable, priv->sync_file = -1; + meta_thread_inhibit_realtime_in_impl (thread); + priv->realtime_inhibited_pending_mode_set = TRUE; + return TRUE; } diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c index 99019ca85..e34af9820 100644 --- a/src/backends/native/meta-kms-impl.c +++ b/src/backends/native/meta-kms-impl.c @@ -172,12 +172,32 @@ meta_kms_impl_finalize (GObject *object) G_OBJECT_CLASS (meta_kms_impl_parent_class)->finalize (object); } +static void +meta_kms_impl_setup (MetaThreadImpl *thread_impl) +{ + MetaThread *thread = meta_thread_impl_get_thread (thread_impl); + + meta_thread_inhibit_realtime_in_impl (thread); +} + +void +meta_kms_impl_notify_probed (MetaKmsImpl *impl) +{ + MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl); + MetaThread *thread = meta_thread_impl_get_thread (thread_impl); + + meta_thread_uninhibit_realtime_in_impl (thread); +} + static void meta_kms_impl_class_init (MetaKmsImplClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaThreadImplClass *thread_impl_class = META_THREAD_IMPL_CLASS (klass); object_class->finalize = meta_kms_impl_finalize; + + thread_impl_class->setup = meta_kms_impl_setup; } MetaKmsUpdateFilter * diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h index f8379fab2..582bebf5e 100644 --- a/src/backends/native/meta-kms-impl.h +++ b/src/backends/native/meta-kms-impl.h @@ -53,6 +53,8 @@ void meta_kms_impl_notify_modes_set (MetaKmsImpl *impl); MetaKmsImpl * meta_kms_impl_new (MetaKms *kms); +void meta_kms_impl_notify_probed (MetaKmsImpl *impl); + MetaKmsUpdateFilter * meta_kms_impl_add_update_filter (MetaKmsImpl *impl, MetaKmsUpdateFilterFunc func, gpointer user_data); diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index d41fcefb5..d989337a1 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -413,6 +413,23 @@ meta_kms_new (MetaBackend *backend, return kms; } +static gpointer +notify_probed_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) +{ + meta_kms_impl_notify_probed (META_KMS_IMPL (thread_impl)); + return NULL; +} + +void +meta_kms_notify_probed (MetaKms *kms) +{ + meta_thread_post_impl_task (META_THREAD (kms), + notify_probed_in_impl, + NULL, NULL, NULL, NULL); +} + static void meta_kms_finalize (GObject *object) { diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h index 743401406..057c7a234 100644 --- a/src/backends/native/meta-kms.h +++ b/src/backends/native/meta-kms.h @@ -64,6 +64,8 @@ MetaKms * meta_kms_new (MetaBackend *backend, MetaKmsFlags flags, GError **error); +void meta_kms_notify_probed (MetaKms *kms); + META_EXPORT_TEST void meta_kms_inhibit_kernel_thread (MetaKms *kms); diff --git a/src/backends/native/meta-thread-impl.c b/src/backends/native/meta-thread-impl.c index 28ef349f7..d02d49203 100644 --- a/src/backends/native/meta-thread-impl.c +++ b/src/backends/native/meta-thread-impl.c @@ -568,6 +568,15 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl) return 1; } +void +meta_thread_impl_setup (MetaThreadImpl *thread_impl) +{ + MetaThreadImplClass *klass = META_THREAD_IMPL_GET_CLASS (thread_impl); + + if (klass->setup) + klass->setup (thread_impl); +} + void meta_thread_impl_run (MetaThreadImpl *thread_impl, MetaThreadImplRunFlags flags) diff --git a/src/backends/native/meta-thread-impl.h b/src/backends/native/meta-thread-impl.h index 2083b3bf1..1837c465c 100644 --- a/src/backends/native/meta-thread-impl.h +++ b/src/backends/native/meta-thread-impl.h @@ -38,6 +38,8 @@ G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl, struct _MetaThreadImplClass { GObjectClass parent_class; + + void (* setup) (MetaThreadImpl *thread_impl); }; typedef enum _MetaThreadTaskFeedbackType @@ -70,6 +72,8 @@ void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl, void meta_thread_impl_terminate (MetaThreadImpl *thread_impl); +void meta_thread_impl_setup (MetaThreadImpl *thread_impl); + void meta_thread_impl_run (MetaThreadImpl *thread_impl, MetaThreadImplRunFlags flags); diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c index 08bd9b8fe..5dcdb05eb 100644 --- a/src/backends/native/meta-thread.c +++ b/src/backends/native/meta-thread.c @@ -333,22 +333,28 @@ request_normal_scheduling (MetaThread *thread, } static gboolean -should_use_realtime_scheduling_in_impl (MetaThread *thread) +can_use_realtime_scheduling_in_impl (MetaThread *thread) { MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - gboolean should_use_realtime_scheduling = FALSE; switch (priv->thread_type) { case META_THREAD_TYPE_USER: - break; + return FALSE; case META_THREAD_TYPE_KERNEL: - if (priv->wants_realtime && priv->kernel.realtime_inhibit_count == 0) - should_use_realtime_scheduling = TRUE; - break; + return priv->wants_realtime; } - return should_use_realtime_scheduling; + g_assert_not_reached (); +} + +static gboolean +should_use_realtime_scheduling_in_impl (MetaThread *thread) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + return (can_use_realtime_scheduling_in_impl (thread) && + priv->kernel.realtime_inhibit_count == 0); } static void @@ -417,11 +423,13 @@ thread_impl_func (gpointer user_data) priv->kernel.realtime_inhibit_count = 0; priv->kernel.is_realtime = FALSE; + meta_thread_impl_setup (impl); + sync_realtime_scheduling_in_impl (thread); - if (priv->kernel.is_realtime) + if (can_use_realtime_scheduling_in_impl (thread)) { - g_message ("Made thread '%s' realtime scheduled", priv->name); + g_message ("Thread '%s' will be using real time scheduling", priv->name); run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME; }