diff --git a/.gitignore b/.gitignore index 672eb74..9c430a8 100644 --- a/.gitignore +++ b/.gitignore @@ -213,3 +213,4 @@ mutter-2.31.5.tar.bz2 /mutter-45.beta.1.tar.xz /mutter-45.rc.tar.xz /mutter-45.0.tar.xz +/mutter-45.1.tar.xz diff --git a/0001-thread-For-consistency-s-real_time-realtime.patch b/0001-thread-For-consistency-s-real_time-realtime.patch deleted file mode 100644 index a26ec8c..0000000 --- a/0001-thread-For-consistency-s-real_time-realtime.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 01c01a221a7dabb2382a44b71dcf06649ee193d6 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 10 Oct 2023 14:35:46 -0400 -Subject: [PATCH 1/4] thread: For consistency, s/real_time/realtime/ - -Most of the code writes "real-time" as "realtime" not "real_time". - -The only exception is one function `request_real_time_scheduling`. - -This commit changes that function for consistency. ---- - src/backends/native/meta-thread.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c -index 08d01144d..93a84a8a5 100644 ---- a/src/backends/native/meta-thread.c -+++ b/src/backends/native/meta-thread.c -@@ -175,62 +175,62 @@ get_rtkit_property (MetaDBusRealtimeKit1 *rtkit_proxy, - { - GDBusConnection *connection; - g_autoptr (GVariant) prop_value = NULL; - g_autoptr (GVariant) property_variant = NULL; - - /* The following is a fall back path for a RTKit daemon that doesn't support - * org.freedesktop.DBus.Properties.GetAll. See - * . - */ - connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (rtkit_proxy)); - prop_value = - g_dbus_connection_call_sync (connection, - "org.freedesktop.RealtimeKit1", - "/org/freedesktop/RealtimeKit1", - "org.freedesktop.DBus.Properties", - "Get", - g_variant_new ("(ss)", - "org.freedesktop.RealtimeKit1", - property_name), - G_VARIANT_TYPE ("(v)"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, NULL, error); - if (!prop_value) - return NULL; - - g_variant_get (prop_value, "(v)", &property_variant); - return g_steal_pointer (&property_variant); - } - - static gboolean --request_real_time_scheduling (MetaThread *thread, -- GError **error) -+request_realtime_scheduling (MetaThread *thread, -+ GError **error) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - g_autoptr (MetaDBusRealtimeKit1) rtkit_proxy = NULL; - g_autoptr (GError) local_error = NULL; - int64_t rttime; - struct rlimit rl; - uint32_t priority; - - rtkit_proxy = - meta_dbus_realtime_kit1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - "org.freedesktop.RealtimeKit1", - "/org/freedesktop/RealtimeKit1", - NULL, - &local_error); - if (!rtkit_proxy) - { - g_dbus_error_strip_remote_error (local_error); - g_propagate_prefixed_error (error, g_steal_pointer (&local_error), - "Failed to acquire RTKit D-Bus proxy: "); - return FALSE; - } - - priority = meta_dbus_realtime_kit1_get_max_realtime_priority (rtkit_proxy); - if (priority == 0) - { - g_autoptr (GVariant) priority_variant = NULL; - - priority_variant = get_rtkit_property (rtkit_proxy, -@@ -286,61 +286,61 @@ request_real_time_scheduling (MetaThread *thread, - - return TRUE; - } - - static gpointer - thread_impl_func (gpointer user_data) - { - MetaThread *thread = META_THREAD (user_data); - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - MetaThreadImpl *impl = priv->impl; - MetaThreadImplRunFlags run_flags = META_THREAD_IMPL_RUN_FLAG_NONE; - GMainContext *thread_context = meta_thread_impl_get_main_context (impl); - #ifdef HAVE_PROFILER - MetaContext *context = meta_backend_get_context (priv->backend); - MetaProfiler *profiler = meta_context_get_profiler (context); - #endif - - g_mutex_lock (&priv->kernel.init_mutex); - g_mutex_unlock (&priv->kernel.init_mutex); - - g_main_context_push_thread_default (thread_context); - - #ifdef HAVE_PROFILER - meta_profiler_register_thread (profiler, thread_context, priv->name); - #endif - - if (priv->wants_realtime) - { - g_autoptr (GError) error = NULL; - -- if (!request_real_time_scheduling (thread, &error)) -+ if (!request_realtime_scheduling (thread, &error)) - { - g_warning ("Failed to make thread '%s' realtime scheduled: %s", - priv->name, error->message); - } - else - { - g_message ("Made thread '%s' realtime scheduled", priv->name); - run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME; - } - } - - meta_thread_impl_run (impl, run_flags); - - #ifdef HAVE_PROFILER - meta_profiler_unregister_thread (profiler, thread_context); - #endif - - g_main_context_pop_thread_default (thread_context); - - return GINT_TO_POINTER (TRUE); - } - - typedef struct _WrapperSource - { - GSource base; - - GMainContext *thread_main_context; - - GPollFD fds[256]; - gpointer fd_tags[256]; --- -2.41.0 - diff --git a/0002-tests-dbusmock-templates-rtkit-Add-MakeThreadHighPri.patch b/0002-tests-dbusmock-templates-rtkit-Add-MakeThreadHighPri.patch deleted file mode 100644 index 6ea63a5..0000000 --- a/0002-tests-dbusmock-templates-rtkit-Add-MakeThreadHighPri.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 742316746d50084dda4ebda5ad081e59451e3256 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 11 Oct 2023 09:37:54 -0400 -Subject: [PATCH 2/4] tests/dbusmock-templates/rtkit: Add - MakeThreadHighPriority - -mutter will soon need to call an additional method in RTKit, -MakeThreadHighPriority. - -In preparation for that, this commit stubs it out in the -dbusmock template. ---- - src/tests/dbusmock-templates/rtkit.py | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/tests/dbusmock-templates/rtkit.py b/src/tests/dbusmock-templates/rtkit.py -index 168582de8..766bd681e 100644 ---- a/src/tests/dbusmock-templates/rtkit.py -+++ b/src/tests/dbusmock-templates/rtkit.py -@@ -1,38 +1,42 @@ - # This program is free software; you can redistribute it and/or modify it under - # the terms of the GNU Lesser General Public License as published by the Free - # Software Foundation; either version 3 of the License, or (at your option) any - # later version. See http://www.gnu.org/copyleft/lgpl.html for the full text - # of the license. - - __author__ = 'Jonas Ådahl' - __copyright__ = '(c) 2022 Red Hat Inc.' - - import dbus - from dbusmock import MOCK_IFACE, mockobject - - BUS_NAME = 'org.freedesktop.RealtimeKit1' - MAIN_OBJ = '/org/freedesktop/RealtimeKit1' - MAIN_IFACE = 'org.freedesktop.RealtimeKit1' - SYSTEM_BUS = True - - - def load(mock, parameters): - mock.AddProperty(MAIN_IFACE, 'RTTimeUSecMax', dbus.Int64(200000)) - mock.AddProperty(MAIN_IFACE, 'MaxRealtimePriority', dbus.Int32(20)) - mock.AddProperty(MAIN_IFACE, 'MinNiceLevel', dbus.Int32(-15)) - mock.priorities = dict() - - @dbus.service.method(MAIN_IFACE, in_signature='tu') - def MakeThreadRealtime(self, thread, priority): - self.priorities[thread] = priority - -+@dbus.service.method(MAIN_IFACE, in_signature='tu') -+def MakeThreadHighPriority(self, thread, priority): -+ self.priorities[thread] = priority -+ - @dbus.service.method(MOCK_IFACE) - def Reset(self): - self.priorities = dict() - - @dbus.service.method(MOCK_IFACE, in_signature='t', out_signature='u') - def GetThreadPriority(self, thread): - if thread in self.priorities: - return self.priorities[thread] - else: - return 0 --- -2.41.0 - diff --git a/0003-thread-Allow-turning-off-rt-scheduling-for-running-t.patch b/0003-thread-Allow-turning-off-rt-scheduling-for-running-t.patch deleted file mode 100644 index c400c6f..0000000 --- a/0003-thread-Allow-turning-off-rt-scheduling-for-running-t.patch +++ /dev/null @@ -1,580 +0,0 @@ -From a7c0f106b30137e1fc6159eaecee8e61b8dc48a9 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 10 Oct 2023 14:39:13 -0400 -Subject: [PATCH 3/4] thread: Allow turning off rt scheduling for running - thread - -At the moment if a thread is made real-time there's no going back, -it stays real-time for the duration of its life. - -That's suboptimal because real-time threads are expected by RTKit to -have an rlimit on their CPU time and certain GPU drivers in the kernel -can exceed that CPU time during certain operations like DPMS off. - -This commit adds two new ref counted functions: - - meta_thread_{un,}inhibit_realtime_in_impl - -that allow turning a thread real-time or normally scheduled. At the same -time, this commit stores the RTKit proxy as private data on the thread -so that it can be reused by the above apis. - -A subsequent commit will use the new APIs. ---- - src/backends/native/meta-thread.c | 189 ++++++++++++++++++++++++++---- - src/backends/native/meta-thread.h | 3 + - 2 files changed, 168 insertions(+), 24 deletions(-) - -diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c -index 93a84a8a5..1ed30441d 100644 ---- a/src/backends/native/meta-thread.c -+++ b/src/backends/native/meta-thread.c -@@ -56,62 +56,66 @@ typedef struct _MetaThreadCallbackSource - - GMutex mutex; - GCond cond; - - MetaThread *thread; - GMainContext *main_context; - GList *callbacks; - gboolean needs_flush; - } MetaThreadCallbackSource; - - typedef struct _MetaThreadPrivate - { - MetaBackend *backend; - char *name; - - GMainContext *main_context; - - MetaThreadImpl *impl; - gboolean wants_realtime; - gboolean waiting_for_impl_task; - GSource *wrapper_source; - - GMutex callbacks_mutex; - GHashTable *callback_sources; - - MetaThreadType thread_type; - - GThread *main_thread; - - struct { -+ MetaDBusRealtimeKit1 *rtkit_proxy; - GThread *thread; -+ pid_t thread_id; - GMutex init_mutex; -+ int realtime_inhibit_count; -+ gboolean is_realtime; - } kernel; - } MetaThreadPrivate; - - typedef struct _MetaThreadClassPrivate - { - GType impl_type; - } MetaThreadClassPrivate; - - static void initable_iface_init (GInitableIface *initable_iface); - - G_DEFINE_TYPE_WITH_CODE (MetaThread, meta_thread, G_TYPE_OBJECT, - G_ADD_PRIVATE (MetaThread) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - initable_iface_init) - g_type_add_class_private (g_define_type_id, - sizeof (MetaThreadClassPrivate))) - - static void - meta_thread_callback_data_free (MetaThreadCallbackData *callback_data) - { - if (callback_data->user_data_destroy) - callback_data->user_data_destroy (callback_data->user_data); - g_free (callback_data); - } - - static void - meta_thread_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -@@ -175,181 +179,278 @@ get_rtkit_property (MetaDBusRealtimeKit1 *rtkit_proxy, - { - GDBusConnection *connection; - g_autoptr (GVariant) prop_value = NULL; - g_autoptr (GVariant) property_variant = NULL; - - /* The following is a fall back path for a RTKit daemon that doesn't support - * org.freedesktop.DBus.Properties.GetAll. See - * . - */ - connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (rtkit_proxy)); - prop_value = - g_dbus_connection_call_sync (connection, - "org.freedesktop.RealtimeKit1", - "/org/freedesktop/RealtimeKit1", - "org.freedesktop.DBus.Properties", - "Get", - g_variant_new ("(ss)", - "org.freedesktop.RealtimeKit1", - property_name), - G_VARIANT_TYPE ("(v)"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, NULL, error); - if (!prop_value) - return NULL; - - g_variant_get (prop_value, "(v)", &property_variant); - return g_steal_pointer (&property_variant); - } - - static gboolean --request_realtime_scheduling (MetaThread *thread, -- GError **error) -+ensure_realtime_kit_proxy (MetaThread *thread, -+ GError **error) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - g_autoptr (MetaDBusRealtimeKit1) rtkit_proxy = NULL; - g_autoptr (GError) local_error = NULL; -- int64_t rttime; -- struct rlimit rl; -- uint32_t priority; -+ -+ if (priv->kernel.rtkit_proxy) -+ return TRUE; - - rtkit_proxy = - meta_dbus_realtime_kit1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - "org.freedesktop.RealtimeKit1", - "/org/freedesktop/RealtimeKit1", - NULL, - &local_error); - if (!rtkit_proxy) - { - g_dbus_error_strip_remote_error (local_error); - g_propagate_prefixed_error (error, g_steal_pointer (&local_error), - "Failed to acquire RTKit D-Bus proxy: "); - return FALSE; - } - -- priority = meta_dbus_realtime_kit1_get_max_realtime_priority (rtkit_proxy); -+ priv->kernel.rtkit_proxy = g_steal_pointer (&rtkit_proxy); -+ return TRUE; -+} -+ -+static gboolean -+request_realtime_scheduling (MetaThread *thread, -+ GError **error) -+{ -+ MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); -+ g_autoptr (GError) local_error = NULL; -+ int64_t rttime; -+ struct rlimit rl; -+ uint32_t priority; -+ -+ if (!ensure_realtime_kit_proxy (thread, error)) -+ return FALSE; -+ -+ priority = meta_dbus_realtime_kit1_get_max_realtime_priority (priv->kernel.rtkit_proxy); - if (priority == 0) - { - g_autoptr (GVariant) priority_variant = NULL; - -- priority_variant = get_rtkit_property (rtkit_proxy, -+ priority_variant = get_rtkit_property (priv->kernel.rtkit_proxy, - "MaxRealtimePriority", - error); - if (!priority_variant) - return FALSE; - - priority = g_variant_get_int32 (priority_variant); - } - - if (priority == 0) - g_warning ("Maximum real time scheduling priority is 0"); - -- rttime = meta_dbus_realtime_kit1_get_rttime_usec_max (rtkit_proxy); -+ rttime = meta_dbus_realtime_kit1_get_rttime_usec_max (priv->kernel.rtkit_proxy); - if (rttime == 0) - { - g_autoptr (GVariant) rttime_variant = NULL; - -- rttime_variant = get_rtkit_property (rtkit_proxy, -+ rttime_variant = get_rtkit_property (priv->kernel.rtkit_proxy, - "RTTimeUSecMax", - error); - if (!rttime_variant) - return FALSE; - - rttime = g_variant_get_int64 (rttime_variant); - } - - meta_topic (META_DEBUG_BACKEND, - "Setting soft and hard RLIMIT_RTTIME limit to %lu", rttime); - rl.rlim_cur = rttime; - rl.rlim_max = rttime; - - if (setrlimit (RLIMIT_RTTIME, &rl) != 0) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "Failed to set RLIMIT_RTTIME: %s", g_strerror (errno)); - return FALSE; - } - - meta_topic (META_DEBUG_BACKEND, "Setting '%s' thread real time priority to %d", - priv->name, priority); -- if (!meta_dbus_realtime_kit1_call_make_thread_realtime_sync (rtkit_proxy, -- gettid (), -+ if (!meta_dbus_realtime_kit1_call_make_thread_realtime_sync (priv->kernel.rtkit_proxy, -+ priv->kernel.thread_id, - priority, - NULL, - &local_error)) - { - g_dbus_error_strip_remote_error (local_error); - g_propagate_error (error, g_steal_pointer (&local_error)); - return FALSE; - } - - return TRUE; - } - -+static gboolean -+request_normal_scheduling (MetaThread *thread, -+ GError **error) -+{ -+ MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); -+ g_autoptr (GError) local_error = NULL; -+ -+ if (!ensure_realtime_kit_proxy (thread, error)) -+ return FALSE; -+ -+ meta_topic (META_DEBUG_BACKEND, "Setting '%s' thread to normal priority", priv->name); -+ if (!meta_dbus_realtime_kit1_call_make_thread_high_priority_sync (priv->kernel.rtkit_proxy, -+ priv->kernel.thread_id, -+ 0 /* "normal" nice value */, -+ NULL, -+ &local_error)) -+ { -+ g_dbus_error_strip_remote_error (local_error); -+ g_propagate_error (error, g_steal_pointer (&local_error)); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+static gboolean -+should_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; -+ case META_THREAD_TYPE_KERNEL: -+ if (priv->wants_realtime && priv->kernel.realtime_inhibit_count == 0) -+ should_use_realtime_scheduling = TRUE; -+ break; -+ } -+ -+ return should_use_realtime_scheduling; -+} -+ -+static void -+sync_realtime_scheduling_in_impl (MetaThread *thread) -+{ -+ MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); -+ g_autoptr (GError) error = NULL; -+ gboolean should_be_realtime; -+ -+ should_be_realtime = should_use_realtime_scheduling_in_impl (thread); -+ -+ if (should_be_realtime == priv->kernel.is_realtime) -+ return; -+ -+ if (should_be_realtime) -+ { -+ if (!request_realtime_scheduling (thread, &error)) -+ { -+ g_warning ("Failed to make thread '%s' realtime scheduled: %s", -+ priv->name, error->message); -+ } -+ else -+ { -+ meta_topic (META_DEBUG_BACKEND, "Made thread '%s' real-time scheduled", priv->name); -+ priv->kernel.is_realtime = TRUE; -+ } -+ } -+ else -+ { -+ if (!request_normal_scheduling (thread, &error)) -+ { -+ g_warning ("Failed to make thread '%s' normally scheduled: %s", -+ priv->name, error->message); -+ } -+ else -+ { -+ meta_topic (META_DEBUG_BACKEND, "Made thread '%s' normally scheduled", priv->name); -+ priv->kernel.is_realtime = FALSE; -+ } -+ } -+} -+ - static gpointer - thread_impl_func (gpointer user_data) - { - MetaThread *thread = META_THREAD (user_data); - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - MetaThreadImpl *impl = priv->impl; - MetaThreadImplRunFlags run_flags = META_THREAD_IMPL_RUN_FLAG_NONE; - GMainContext *thread_context = meta_thread_impl_get_main_context (impl); - #ifdef HAVE_PROFILER - MetaContext *context = meta_backend_get_context (priv->backend); - MetaProfiler *profiler = meta_context_get_profiler (context); - #endif - - g_mutex_lock (&priv->kernel.init_mutex); - g_mutex_unlock (&priv->kernel.init_mutex); - - g_main_context_push_thread_default (thread_context); - - #ifdef HAVE_PROFILER - meta_profiler_register_thread (profiler, thread_context, priv->name); - #endif - -- if (priv->wants_realtime) -- { -- g_autoptr (GError) error = NULL; -+ priv->kernel.thread_id = gettid (); -+ priv->kernel.realtime_inhibit_count = 0; -+ priv->kernel.is_realtime = FALSE; - -- if (!request_realtime_scheduling (thread, &error)) -- { -- g_warning ("Failed to make thread '%s' realtime scheduled: %s", -- priv->name, error->message); -- } -- else -- { -- g_message ("Made thread '%s' realtime scheduled", priv->name); -- run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME; -- } -+ sync_realtime_scheduling_in_impl (thread); -+ -+ if (priv->kernel.is_realtime) -+ { -+ g_message ("Made thread '%s' realtime scheduled", priv->name); -+ run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME; - } - - meta_thread_impl_run (impl, run_flags); - - #ifdef HAVE_PROFILER - meta_profiler_unregister_thread (profiler, thread_context); - #endif - - g_main_context_pop_thread_default (thread_context); - - return GINT_TO_POINTER (TRUE); - } - - typedef struct _WrapperSource - { - GSource base; - - GMainContext *thread_main_context; - - GPollFD fds[256]; - gpointer fd_tags[256]; - int n_fds; - int priority; - } WrapperSource; - - static gboolean - wrapper_source_prepare (GSource *source, - int *timeout) - { - WrapperSource *wrapper_source = (WrapperSource *) source; -@@ -522,60 +623,64 @@ meta_thread_initable_init (GInitable *initable, - - start_thread (thread); - - return TRUE; - } - - static void - initable_iface_init (GInitableIface *initable_iface) - { - initable_iface->init = meta_thread_initable_init; - } - - static void - finalize_thread_user (MetaThread *thread) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - meta_thread_impl_terminate (priv->impl); - while (meta_thread_impl_dispatch (priv->impl) > 0); - unwrap_main_context (thread, meta_thread_impl_get_main_context (priv->impl)); - } - - static void - finalize_thread_kernel (MetaThread *thread) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - meta_thread_impl_terminate (priv->impl); - g_thread_join (priv->kernel.thread); - priv->kernel.thread = NULL; -+ priv->kernel.thread_id = 0; -+ -+ g_clear_object (&priv->kernel.rtkit_proxy); -+ - g_mutex_clear (&priv->kernel.init_mutex); - } - - static void - tear_down_thread (MetaThread *thread) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - switch (priv->thread_type) - { - case META_THREAD_TYPE_USER: - finalize_thread_user (thread); - break; - case META_THREAD_TYPE_KERNEL: - finalize_thread_kernel (thread); - break; - } - - meta_thread_flush_callbacks (thread); - } - - static void - meta_thread_finalize (GObject *object) - { - MetaThread *thread = META_THREAD (object); - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - tear_down_thread (thread); - - meta_thread_unregister_callback_context (thread, priv->main_context); -@@ -1134,30 +1239,66 @@ meta_thread_get_thread_type (MetaThread *thread) - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - return priv->thread_type; - } - - GThread * - meta_thread_get_thread (MetaThread *thread) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - g_assert (priv->thread_type == META_THREAD_TYPE_KERNEL); - - return priv->kernel.thread; - } - - gboolean - meta_thread_is_in_impl_task (MetaThread *thread) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - return meta_thread_impl_is_in_impl (priv->impl); - } - - gboolean - meta_thread_is_waiting_for_impl_task (MetaThread *thread) - { - MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); - - return priv->waiting_for_impl_task; - } -+ -+void -+meta_thread_inhibit_realtime_in_impl (MetaThread *thread) -+{ -+ MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); -+ -+ switch (priv->thread_type) -+ { -+ case META_THREAD_TYPE_KERNEL: -+ priv->kernel.realtime_inhibit_count++; -+ -+ if (priv->kernel.realtime_inhibit_count == 1) -+ sync_realtime_scheduling_in_impl (thread); -+ break; -+ case META_THREAD_TYPE_USER: -+ break; -+ } -+} -+ -+void -+meta_thread_uninhibit_realtime_in_impl (MetaThread *thread) -+{ -+ MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); -+ -+ switch (priv->thread_type) -+ { -+ case META_THREAD_TYPE_KERNEL: -+ priv->kernel.realtime_inhibit_count--; -+ -+ if (priv->kernel.realtime_inhibit_count == 0) -+ sync_realtime_scheduling_in_impl (thread); -+ break; -+ case META_THREAD_TYPE_USER: -+ break; -+ } -+} -diff --git a/src/backends/native/meta-thread.h b/src/backends/native/meta-thread.h -index f6c5c94f5..4765719ec 100644 ---- a/src/backends/native/meta-thread.h -+++ b/src/backends/native/meta-thread.h -@@ -71,36 +71,39 @@ void meta_thread_queue_callback (MetaThread *thread, - GDestroyNotify user_data_destroy); - - META_EXPORT_TEST - void meta_thread_flush_callbacks (MetaThread *thread); - - META_EXPORT_TEST - gpointer meta_thread_run_impl_task_sync (MetaThread *thread, - MetaThreadTaskFunc func, - gpointer user_data, - GError **error); - - META_EXPORT_TEST - void meta_thread_post_impl_task (MetaThread *thread, - MetaThreadTaskFunc func, - gpointer user_data, - GDestroyNotify user_data_destroy, - MetaThreadTaskFeedbackFunc feedback_func, - gpointer feedback_user_data); - - META_EXPORT_TEST - MetaBackend * meta_thread_get_backend (MetaThread *thread); - - META_EXPORT_TEST - const char * meta_thread_get_name (MetaThread *thread); - - META_EXPORT_TEST - gboolean meta_thread_is_in_impl_task (MetaThread *thread); - - gboolean meta_thread_is_waiting_for_impl_task (MetaThread *thread); - -+void meta_thread_inhibit_realtime_in_impl (MetaThread *thread); -+void meta_thread_uninhibit_realtime_in_impl (MetaThread *thread); -+ - #define meta_assert_in_thread_impl(thread) \ - g_assert (meta_thread_is_in_impl_task (thread)) - #define meta_assert_not_in_thread_impl(thread) \ - g_assert (!meta_thread_is_in_impl_task (thread)) - #define meta_assert_is_waiting_for_thread_impl_task(thread) \ - g_assert (meta_thread_is_waiting_for_impl_task (thread)) --- -2.41.0 - diff --git a/0004-kms-impl-device-Inhibit-real-time-scheduling-when-mo.patch b/0004-kms-impl-device-Inhibit-real-time-scheduling-when-mo.patch deleted file mode 100644 index fa9c1d2..0000000 --- a/0004-kms-impl-device-Inhibit-real-time-scheduling-when-mo.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 105a3d60df5df74fd7ea78cacc0d9ca30607b45a Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 10 Oct 2023 14:48:55 -0400 -Subject: [PATCH 4/4] kms/impl-device: Inhibit real-time scheduling when mode - setting - -Certain kernel drivers can take an unreasonably long time to -complete mode setting operations. That excessive CPU time is charged -to the process's rlimits which can lead to the process getting killed -if the thread is a real-time thread. - -This commit inhibits real-time scheduling around mode setting -commits, since those commits are the ones currently presenting as -excessively slow. - -Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3037 ---- - src/backends/native/meta-kms-impl-device.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c -index da372383d..d53552704 100644 ---- a/src/backends/native/meta-kms-impl-device.c -+++ b/src/backends/native/meta-kms-impl-device.c -@@ -1554,141 +1554,154 @@ meta_kms_impl_device_schedule_process (MetaKmsImplDevice *impl_device, - - if (crtc_frame->await_flush) - return; - - if (!is_using_deadline_timer (impl_device)) - goto needs_flush; - - if (crtc_frame->pending_page_flip) - return; - - if (ensure_deadline_timer_armed (impl_device, crtc_frame, &error)) - return; - - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - g_warning ("Failed to determine deadline: %s", error->message); - - priv = meta_kms_impl_device_get_instance_private (impl_device); - priv->deadline_timer_inhibited = TRUE; - - needs_flush: - meta_kms_device_set_needs_flush (meta_kms_crtc_get_device (crtc), crtc); - } - - static MetaKmsFeedback * - process_mode_set_update (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update, - MetaKmsUpdateFlag flags) - { - MetaKmsImplDevicePrivate *priv = - meta_kms_impl_device_get_instance_private (impl_device); -+ MetaKmsImpl *kms_impl = meta_kms_impl_device_get_impl (impl_device); -+ MetaThreadImpl *thread_impl = META_THREAD_IMPL (kms_impl); -+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl); -+ MetaKmsFeedback *feedback; - CrtcFrame *crtc_frame; - GList *l; - GHashTableIter iter; - - for (l = meta_kms_update_get_mode_sets (update); l; l = l->next) - { - MetaKmsModeSet *mode_set = l->data; - MetaKmsCrtc *crtc = mode_set->crtc; - - crtc_frame = get_crtc_frame (impl_device, crtc); - if (!crtc_frame) - continue; - - if (!crtc_frame->pending_update) - continue; - - meta_kms_update_merge_from (update, crtc_frame->pending_update); - g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free); - } - - g_hash_table_iter_init (&iter, priv->crtc_frames); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &crtc_frame)) - { - crtc_frame->deadline.is_deadline_page_flip = FALSE; - crtc_frame->await_flush = FALSE; - crtc_frame->pending_page_flip = FALSE; - g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free); - disarm_crtc_frame_deadline_timer (crtc_frame); - } - -- return do_process (impl_device, NULL, update, flags); -+ meta_thread_inhibit_realtime_in_impl (thread); -+ feedback = do_process (impl_device, NULL, update, flags); -+ meta_thread_uninhibit_realtime_in_impl (thread); -+ -+ return feedback; - } - - MetaKmsFeedback * - meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device, - MetaKmsUpdate *update, - MetaKmsUpdateFlag flags) - { - g_autoptr (GError) error = NULL; - - if (!ensure_device_file (impl_device, &error)) - { - MetaKmsFeedback *feedback = NULL; - - feedback = meta_kms_feedback_new_failed (NULL, g_steal_pointer (&error)); - queue_result_feedback (impl_device, update, feedback); - - meta_kms_update_free (update); - return feedback; - } - - meta_kms_update_realize (update, impl_device); - - if (flags & META_KMS_UPDATE_FLAG_TEST_ONLY) - { - return do_process (impl_device, - meta_kms_update_get_latch_crtc (update), - update, flags); - } - else if (flags & META_KMS_UPDATE_FLAG_MODE_SET) - { - return process_mode_set_update (impl_device, update, flags); - } - else - { - g_assert_not_reached (); - } - } - - void - meta_kms_impl_device_disable (MetaKmsImplDevice *impl_device) - { - MetaKmsImplDevicePrivate *priv = - meta_kms_impl_device_get_instance_private (impl_device); -+ MetaKmsImpl *kms_impl = meta_kms_impl_device_get_impl (impl_device); -+ MetaThreadImpl *thread_impl = META_THREAD_IMPL (kms_impl); -+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl); - MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device); - - if (!priv->device_file) - return; - - meta_kms_impl_device_hold_fd (impl_device); -+ meta_thread_inhibit_realtime_in_impl (thread); - klass->disable (impl_device); -+ meta_thread_uninhibit_realtime_in_impl (thread); - g_list_foreach (priv->crtcs, - (GFunc) meta_kms_crtc_disable_in_impl, NULL); - g_list_foreach (priv->connectors, - (GFunc) meta_kms_connector_disable_in_impl, NULL); - meta_kms_impl_device_unhold_fd (impl_device); - } - - void - meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device, - MetaKmsPageFlipData *page_flip_data) - { - MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device); - - klass->handle_page_flip_callback (impl_device, page_flip_data); - } - - void - meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device) - { - MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device); - - klass->discard_pending_page_flips (impl_device); - } - - void - meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device) - { - MetaKmsImplDevicePrivate *priv = - meta_kms_impl_device_get_instance_private (impl_device); - MetaKms *kms = meta_kms_device_get_kms (priv->device); --- -2.41.0 - diff --git a/3299.patch b/3299.patch deleted file mode 100644 index 920389b..0000000 --- a/3299.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 4008ed2f55d4621a4ed2230799c1ab2d012b3545 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Wed, 27 Sep 2023 22:59:13 +0800 -Subject: [PATCH] monitor-config-store: Discard config with fractional scale - when unusable - -When a configuration has a fractional scale, but we're using a physical -monitor layout, we can't use the scale, but if we do, we end up with -wierd issues down the line. Just discard the config if we run into this. - -Eventually we probably want to store the layout mode in the -configuration so we can handle more seamless switching between physical -and logical layout mode, but first do this. - -Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3057 ---- - src/backends/meta-monitor-config-store.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c -index fe9406fd3f7..53a32cd2aaf 100644 ---- a/src/backends/meta-monitor-config-store.c -+++ b/src/backends/meta-monitor-config-store.c -@@ -653,6 +653,7 @@ derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_conf - MetaMonitorConfig *monitor_config; - int mode_width, mode_height; - int width = 0, height = 0; -+ float scale; - GList *l; - - monitor_config = logical_monitor_config->monitor_configs->data; -@@ -683,13 +684,21 @@ derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_conf - height = mode_height; - } - -+ scale = logical_monitor_config->scale; -+ - switch (layout_mode) - { - case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: -- width = roundf (width / logical_monitor_config->scale); -- height = roundf (height / logical_monitor_config->scale); -+ width = roundf (width / scale); -+ height = roundf (height / scale); - break; - case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: -+ if (!G_APPROX_VALUE (scale, roundf (scale), FLT_EPSILON)) -+ { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -+ "A fractional scale with physical layout mode not allowed"); -+ return FALSE; -+ } - break; - } - --- -GitLab - diff --git a/3306.patch b/3306.patch deleted file mode 100644 index 1ee69ac..0000000 --- a/3306.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 6fe1b3145f840d39240046c0812b1406d23fe569 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho -Date: Fri, 29 Sep 2023 13:14:14 +0200 -Subject: [PATCH] backends/native: Translate keycodes with - xkb_key_state_get_one_sym() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There's two aspects from its documentation -(https://xkbcommon.org/doc/current/group__state.html#gae56031a8c1d48e7802da32f5f39f5738) -affecting us here: - -1. "This function is similar to xkb_state_key_get_syms(), but intended for - users which cannot or do not want to handle the case where multiple - keysyms are returned (in which case this function is preferred)." - - We are indeed in that field, and have been for a long time. - -2. "This function performs Capitalization Keysym Transformations." - - This is unlike the xkb_key_get_syms() function that we use, and - convenient here for parity with X11 since it behaves exactly that - way. - -Fixes cases where the keysym for some keys is not properly capitalized -when caps lock is toggled, due to the output of capslock+key being -different from shift+key. An example of this is 'é' in french(azerty) -layout (bound to the '2' key). Even though shift+2 outputs '2', -capslock+é should output 'É'. - -Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3058 -Part-of: ---- - src/backends/native/meta-xkb-utils.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/src/backends/native/meta-xkb-utils.c b/src/backends/native/meta-xkb-utils.c -index 1ec12a37bea..7f80cca2e2a 100644 ---- a/src/backends/native/meta-xkb-utils.c -+++ b/src/backends/native/meta-xkb-utils.c -@@ -50,7 +50,6 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device, - { - ClutterEvent *event; - xkb_keysym_t sym; -- const xkb_keysym_t *syms; - char buffer[8]; - gunichar unicode_value; - ClutterModifierType modifiers; -@@ -62,11 +61,7 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device, - * upwards by 8. */ - key = meta_xkb_evdev_to_keycode (key); - -- n = xkb_key_get_syms (xkb_state, key, &syms); -- if (n == 1) -- sym = syms[0]; -- else -- sym = XKB_KEY_NoSymbol; -+ sym = xkb_state_key_get_one_sym (xkb_state, key); - - modifiers = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE) | - button_state; --- -GitLab - diff --git a/3311.patch b/3311.patch deleted file mode 100644 index 8b2ede3..0000000 --- a/3311.patch +++ /dev/null @@ -1,460 +0,0 @@ -From b258e1f7eefa67006da72172d2a61389a58b7630 Mon Sep 17 00:00:00 2001 -From: Robert Mader -Date: Mon, 9 Oct 2023 22:47:38 +0200 -Subject: [PATCH 1/2] screen-cast/stream-src: Various code cleanups - -No functional changes. - -Part-of: ---- - src/backends/meta-screen-cast-stream-src.c | 117 ++++++++++----------- - 1 file changed, 57 insertions(+), 60 deletions(-) - -diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c -index 8d4e32ef60e..acb5e9a1da1 100644 ---- a/src/backends/meta-screen-cast-stream-src.c -+++ b/src/backends/meta-screen-cast-stream-src.c -@@ -555,17 +555,16 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src, - } - - static gboolean --do_record_frame (MetaScreenCastStreamSrc *src, -- MetaScreenCastRecordFlag flags, -- struct spa_buffer *spa_buffer, -- uint8_t *data, -- GError **error) -+do_record_frame (MetaScreenCastStreamSrc *src, -+ MetaScreenCastRecordFlag flags, -+ struct spa_buffer *spa_buffer, -+ GError **error) - { - MetaScreenCastStreamSrcPrivate *priv = - meta_screen_cast_stream_src_get_instance_private (src); -+ struct spa_data *spa_data = &spa_buffer->datas[0]; - -- if (spa_buffer->datas[0].data || -- spa_buffer->datas[0].type == SPA_DATA_MemFd) -+ if (spa_data->data || spa_data->type == SPA_DATA_MemFd) - { - int width = priv->video_format.size.width; - int height = priv->video_format.size.height; -@@ -575,14 +574,14 @@ do_record_frame (MetaScreenCastStreamSrc *src, - width, - height, - stride, -- data, -+ spa_data->data, - error); - } -- else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) -+ else if (spa_data->type == SPA_DATA_DmaBuf) - { - CoglDmaBufHandle *dmabuf_handle = - g_hash_table_lookup (priv->dmabuf_handles, -- GINT_TO_POINTER (spa_buffer->datas[0].fd)); -+ GINT_TO_POINTER (spa_data->fd)); - CoglFramebuffer *dmabuf_fbo = - cogl_dma_buf_handle_get_framebuffer (dmabuf_handle); - -@@ -592,7 +591,7 @@ do_record_frame (MetaScreenCastStreamSrc *src, - } - - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -- "Unknown SPA buffer type %u", spa_buffer->datas[0].type); -+ "Unknown SPA buffer type %u", spa_data->type); - return FALSE; - } - -@@ -745,12 +744,12 @@ meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStr - MetaScreenCastStreamSrcPrivate *priv = - meta_screen_cast_stream_src_get_instance_private (src); - MetaScreenCastRecordResult record_result = -- META_SCREEN_CAST_RECORD_RESULT_RECORDED_NOTHING; -+ META_SCREEN_CAST_RECORD_RESULT_RECORDED_NOTHING; - MtkRectangle crop_rect; - struct pw_buffer *buffer; - struct spa_buffer *spa_buffer; - struct spa_meta_header *header; -- uint8_t *data = NULL; -+ struct spa_data *spa_data; - - /* Accumulate the damaged region since we might not schedule a frame capture - * eventually but once we do, we should report all the previous damaged areas. -@@ -817,13 +816,13 @@ meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStr - } - - spa_buffer = buffer->buffer; -- data = spa_buffer->datas[0].data; -+ spa_data = &spa_buffer->datas[0]; - - header = spa_buffer_find_meta_data (spa_buffer, - SPA_META_Header, - sizeof (*header)); - -- if (spa_buffer->datas[0].type != SPA_DATA_DmaBuf && !data) -+ if (spa_data->type != SPA_DATA_DmaBuf && !spa_data->data) - { - g_critical ("Invalid buffer data"); - if (header) -@@ -838,10 +837,9 @@ meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStr - g_autoptr (GError) error = NULL; - - g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove); -- if (do_record_frame (src, flags, spa_buffer, data, &error)) -+ if (do_record_frame (src, flags, spa_buffer, &error)) - { - maybe_add_damaged_regions_metadata (src, spa_buffer); -- struct spa_data *spa_data = &spa_buffer->datas[0]; - struct spa_meta_region *spa_meta_video_crop; - - spa_data->chunk->size = spa_data->maxsize; -@@ -879,14 +877,14 @@ meta_screen_cast_stream_src_maybe_record_frame_with_timestamp (MetaScreenCastStr - { - if (error) - g_warning ("Failed to record screen cast frame: %s", error->message); -- spa_buffer->datas[0].chunk->size = 0; -- spa_buffer->datas[0].chunk->flags = SPA_CHUNK_FLAG_CORRUPTED; -+ spa_data->chunk->size = 0; -+ spa_data->chunk->flags = SPA_CHUNK_FLAG_CORRUPTED; - } - } - else - { -- spa_buffer->datas[0].chunk->size = 0; -- spa_buffer->datas[0].chunk->flags = SPA_CHUNK_FLAG_CORRUPTED; -+ spa_data->chunk->size = 0; -+ spa_data->chunk->flags = SPA_CHUNK_FLAG_CORRUPTED; - } - - record_result |= maybe_record_cursor (src, spa_buffer); -@@ -1091,7 +1089,7 @@ on_stream_add_buffer (void *data, - meta_screen_cast_session_get_screen_cast (session); - CoglDmaBufHandle *dmabuf_handle; - struct spa_buffer *spa_buffer = buffer->buffer; -- struct spa_data *spa_data = spa_buffer->datas; -+ struct spa_data *spa_data = &spa_buffer->datas[0]; - const int bpp = 4; - int stride; - -@@ -1099,11 +1097,11 @@ on_stream_add_buffer (void *data, - - stride = SPA_ROUND_UP_N (priv->video_format.size.width * bpp, 4); - -- spa_data[0].mapoffset = 0; -- spa_data[0].maxsize = stride * priv->video_format.size.height; -- spa_data[0].data = NULL; -+ spa_data->mapoffset = 0; -+ spa_data->maxsize = stride * priv->video_format.size.height; -+ spa_data->data = NULL; - -- if (spa_data[0].type & (1 << SPA_DATA_DmaBuf)) -+ if (spa_data->type & (1 << SPA_DATA_DmaBuf)) - { - CoglPixelFormat cogl_format; - -@@ -1141,19 +1139,19 @@ on_stream_add_buffer (void *data, - "Allocating DMA buffer for pw_stream %u", - pw_stream_get_node_id (priv->pipewire_stream)); - -- spa_data[0].type = SPA_DATA_DmaBuf; -- spa_data[0].flags = SPA_DATA_FLAG_READWRITE; -- spa_data[0].fd = cogl_dma_buf_handle_get_fd (dmabuf_handle); -+ spa_data->type = SPA_DATA_DmaBuf; -+ spa_data->flags = SPA_DATA_FLAG_READWRITE; -+ spa_data->fd = cogl_dma_buf_handle_get_fd (dmabuf_handle); - - g_hash_table_insert (priv->dmabuf_handles, -- GINT_TO_POINTER (spa_data[0].fd), -+ GINT_TO_POINTER (spa_data->fd), - dmabuf_handle); - } - else - { - unsigned int seals; - -- if (!(spa_data[0].type & (1 << SPA_DATA_MemFd))) -+ if (!(spa_data->type & (1 << SPA_DATA_MemFd))) - { - g_critical ("No supported PipeWire stream buffer data type could " - "be negotiated"); -@@ -1165,40 +1163,39 @@ on_stream_add_buffer (void *data, - pw_stream_get_node_id (priv->pipewire_stream)); - - /* Fallback to a memfd buffer */ -- spa_data[0].type = SPA_DATA_MemFd; -- spa_data[0].flags = SPA_DATA_FLAG_READWRITE; -- spa_data[0].fd = memfd_create ("mutter-screen-cast-memfd", -- MFD_CLOEXEC | MFD_ALLOW_SEALING); -- if (spa_data[0].fd == -1) -+ spa_data->type = SPA_DATA_MemFd; -+ spa_data->flags = SPA_DATA_FLAG_READWRITE; -+ spa_data->fd = memfd_create ("mutter-screen-cast-memfd", -+ MFD_CLOEXEC | MFD_ALLOW_SEALING); -+ if (spa_data->fd == -1) - { - g_critical ("Can't create memfd: %m"); - return; - } -- spa_data[0].mapoffset = 0; -- spa_data[0].maxsize = stride * priv->video_format.size.height; -+ spa_data->maxsize = stride * priv->video_format.size.height; - -- if (ftruncate (spa_data[0].fd, spa_data[0].maxsize) < 0) -+ if (ftruncate (spa_data->fd, spa_data->maxsize) < 0) - { -- close (spa_data[0].fd); -- spa_data[0].fd = -1; -- g_critical ("Can't truncate to %d: %m", spa_data[0].maxsize); -+ close (spa_data->fd); -+ spa_data->fd = -1; -+ g_critical ("Can't truncate to %d: %m", spa_data->maxsize); - return; - } - - seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL; -- if (fcntl (spa_data[0].fd, F_ADD_SEALS, seals) == -1) -+ if (fcntl (spa_data->fd, F_ADD_SEALS, seals) == -1) - g_warning ("Failed to add seals: %m"); - -- spa_data[0].data = mmap (NULL, -- spa_data[0].maxsize, -- PROT_READ | PROT_WRITE, -- MAP_SHARED, -- spa_data[0].fd, -- spa_data[0].mapoffset); -- if (spa_data[0].data == MAP_FAILED) -+ spa_data->data = mmap (NULL, -+ spa_data->maxsize, -+ PROT_READ | PROT_WRITE, -+ MAP_SHARED, -+ spa_data->fd, -+ spa_data->mapoffset); -+ if (spa_data->data == MAP_FAILED) - { -- close (spa_data[0].fd); -- spa_data[0].fd = -1; -+ close (spa_data->fd); -+ spa_data->fd = -1; - g_critical ("Failed to mmap memory: %m"); - return; - } -@@ -1219,23 +1216,23 @@ on_stream_remove_buffer (void *data, - MetaScreenCastStreamSrcPrivate *priv = - meta_screen_cast_stream_src_get_instance_private (src); - struct spa_buffer *spa_buffer = buffer->buffer; -- struct spa_data *spa_data = spa_buffer->datas; -+ struct spa_data *spa_data = &spa_buffer->datas[0]; - - priv->buffer_count--; - -- if (spa_data[0].type == SPA_DATA_DmaBuf) -+ if (spa_data->type == SPA_DATA_DmaBuf) - { -- if (!g_hash_table_remove (priv->dmabuf_handles, GINT_TO_POINTER (spa_data[0].fd))) -+ if (!g_hash_table_remove (priv->dmabuf_handles, GINT_TO_POINTER (spa_data->fd))) - g_critical ("Failed to remove non-exported DMA buffer"); - } -- else if (spa_data[0].type == SPA_DATA_MemFd) -+ else if (spa_data->type == SPA_DATA_MemFd) - { -- g_warn_if_fail (spa_data[0].fd > 0 || !spa_data[0].data); -+ g_warn_if_fail (spa_data->fd > 0 || !spa_data->data); - -- if (spa_data[0].fd > 0) -+ if (spa_data->fd > 0) - { -- munmap (spa_data[0].data, spa_data[0].maxsize); -- close (spa_data[0].fd); -+ munmap (spa_data->data, spa_data->maxsize); -+ close (spa_data->fd); - } - } - } --- -GitLab - - -From 9b663f44e6044ece52c38b3ee23bbc2b55328b47 Mon Sep 17 00:00:00 2001 -From: Robert Mader -Date: Thu, 5 Oct 2023 08:36:31 +0200 -Subject: [PATCH 2/2] screen-cast/strieam-src: Fix stride and max buffer size - calculation - -1. Centralize stride calculation in one function. -2. For dmabufs query the stride instead of assuming a certain value. -3. For system memory buffers use the pixel format to calculate the - stride. -4. Stop negotiating `SPA_PARAM_BUFFERS_size` and - `SPA_PARAM_BUFFERS_stride`. - -2. fixes an actual bug where we reported wrong max buffer sizes, -resulting in crashes in Gstreamer when doing area screencasts on AMD -GPUs. - -The reasoning for 4. is that the values were possibly wrong for -dmabufs as the negotiation happens before we create any buffers. -Further more neither Mutter nor the common consumers required it. -The later either ignore the values (OBS), always accept (gstpipewiresrc) -them or calculate the exact same possibly wrong values (libwebrtc). - -Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6747 -Part-of: ---- - src/backends/meta-screen-cast-stream-src.c | 70 ++++++++++------------ - 1 file changed, 33 insertions(+), 37 deletions(-) - -diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c -index acb5e9a1da1..cf198cf6472 100644 ---- a/src/backends/meta-screen-cast-stream-src.c -+++ b/src/backends/meta-screen-cast-stream-src.c -@@ -102,7 +102,6 @@ typedef struct _MetaScreenCastStreamSrcPrivate - uint32_t node_id; - - struct spa_video_info_raw video_format; -- int video_stride; - - int64_t last_frame_timestamp_us; - guint follow_up_frame_source_id; -@@ -554,6 +553,33 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src, - g_assert_not_reached (); - } - -+static int32_t -+meta_screen_cast_stream_src_calculate_stride (MetaScreenCastStreamSrc *src, -+ struct spa_data *spa_data) -+{ -+ MetaScreenCastStreamSrcPrivate *priv = -+ meta_screen_cast_stream_src_get_instance_private (src); -+ CoglPixelFormat cogl_format; -+ int bpp; -+ -+ if (spa_data->type == SPA_DATA_DmaBuf) -+ { -+ CoglDmaBufHandle *dmabuf_handle = NULL; -+ -+ dmabuf_handle = g_hash_table_lookup (priv->dmabuf_handles, -+ GINT_TO_POINTER (spa_data->fd)); -+ if (dmabuf_handle) -+ return cogl_dma_buf_handle_get_stride (dmabuf_handle); -+ } -+ -+ if (!cogl_pixel_format_from_spa_video_format (priv->video_format.format, -+ &cogl_format)) -+ g_assert_not_reached (); -+ -+ bpp = cogl_pixel_format_get_bytes_per_pixel (cogl_format, 0); -+ return SPA_ROUND_UP_N (priv->video_format.size.width * bpp, 4); -+} -+ - static gboolean - do_record_frame (MetaScreenCastStreamSrc *src, - MetaScreenCastRecordFlag flags, -@@ -568,7 +594,7 @@ do_record_frame (MetaScreenCastStreamSrc *src, - { - int width = priv->video_format.size.width; - int height = priv->video_format.size.height; -- int stride = priv->video_stride; -+ int stride = meta_screen_cast_stream_src_calculate_stride (src, spa_data); - - return meta_screen_cast_stream_src_record_to_buffer (src, - width, -@@ -632,26 +658,6 @@ maybe_schedule_follow_up_frame (MetaScreenCastStreamSrc *src, - src); - } - --static int32_t --meta_screen_cast_stream_src_calculate_stride (MetaScreenCastStreamSrc *src, -- struct spa_data *spa_data) --{ -- MetaScreenCastStreamSrcPrivate *priv = -- meta_screen_cast_stream_src_get_instance_private (src); -- CoglDmaBufHandle *dmabuf_handle = NULL; -- -- if (spa_data->type == SPA_DATA_DmaBuf) -- { -- dmabuf_handle = g_hash_table_lookup (priv->dmabuf_handles, -- GINT_TO_POINTER (spa_data->fd)); -- } -- -- if (dmabuf_handle) -- return cogl_dma_buf_handle_get_stride (dmabuf_handle); -- else -- return priv->video_stride; --} -- - static void - maybe_add_damaged_regions_metadata (MetaScreenCastStreamSrc *src, - struct spa_buffer *spa_buffer) -@@ -1014,11 +1020,9 @@ on_stream_param_changed (void *data, - MetaScreenCastStreamSrcClass *klass = - META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); - uint8_t params_buffer[1024]; -- int32_t width, height, stride, size; - struct spa_pod_builder pod_builder; - const struct spa_pod *params[5]; - int n_params = 0; -- const int bpp = 4; - int buffer_types; - - if (!format || id != SPA_PARAM_Format) -@@ -1027,13 +1031,6 @@ on_stream_param_changed (void *data, - spa_format_video_raw_parse (format, - &priv->video_format); - -- width = priv->video_format.size.width; -- height = priv->video_format.size.height; -- stride = SPA_ROUND_UP_N (width * bpp, 4); -- size = height * stride; -- -- priv->video_stride = stride; -- - pod_builder = SPA_POD_BUILDER_INIT (params_buffer, sizeof (params_buffer)); - - buffer_types = 1 << SPA_DATA_MemFd; -@@ -1045,8 +1042,6 @@ on_stream_param_changed (void *data, - SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int (16, 2, 16), - SPA_PARAM_BUFFERS_blocks, SPA_POD_Int (1), -- SPA_PARAM_BUFFERS_size, SPA_POD_Int (size), -- SPA_PARAM_BUFFERS_stride, SPA_POD_Int (stride), - SPA_PARAM_BUFFERS_align, SPA_POD_Int (16), - SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int (buffer_types)); - -@@ -1090,15 +1085,11 @@ on_stream_add_buffer (void *data, - CoglDmaBufHandle *dmabuf_handle; - struct spa_buffer *spa_buffer = buffer->buffer; - struct spa_data *spa_data = &spa_buffer->datas[0]; -- const int bpp = 4; - int stride; - - priv->buffer_count++; - -- stride = SPA_ROUND_UP_N (priv->video_format.size.width * bpp, 4); -- - spa_data->mapoffset = 0; -- spa_data->maxsize = stride * priv->video_format.size.height; - spa_data->data = NULL; - - if (spa_data->type & (1 << SPA_DATA_DmaBuf)) -@@ -1143,6 +1134,9 @@ on_stream_add_buffer (void *data, - spa_data->flags = SPA_DATA_FLAG_READWRITE; - spa_data->fd = cogl_dma_buf_handle_get_fd (dmabuf_handle); - -+ stride = meta_screen_cast_stream_src_calculate_stride (src, spa_data); -+ spa_data->maxsize = stride * priv->video_format.size.height; -+ - g_hash_table_insert (priv->dmabuf_handles, - GINT_TO_POINTER (spa_data->fd), - dmabuf_handle); -@@ -1172,6 +1166,8 @@ on_stream_add_buffer (void *data, - g_critical ("Can't create memfd: %m"); - return; - } -+ -+ stride = meta_screen_cast_stream_src_calculate_stride (src, spa_data); - spa_data->maxsize = stride * priv->video_format.size.height; - - if (ftruncate (spa_data->fd, spa_data->maxsize) < 0) --- -GitLab - diff --git a/3326.patch b/3326.patch deleted file mode 100644 index 37f3b61..0000000 --- a/3326.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 5809ef62f5e8b12a9cbaf8ec8efac814563bf13e Mon Sep 17 00:00:00 2001 -From: Robert Mader -Date: Fri, 13 Oct 2023 15:37:27 +0200 -Subject: [PATCH 1/2] screen-cast/stream-src: Calculate stride after adding - handle to hash table - -`calculate_stride()` looks up the dmabuf handle from the hash table so -we need to add it first. - -Fixes 9b663f44e6044ece52c38b3ee23bbc2b55328b47 - -Part-of: ---- - src/backends/meta-screen-cast-stream-src.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c -index cf198cf6472..fd49c533930 100644 ---- a/src/backends/meta-screen-cast-stream-src.c -+++ b/src/backends/meta-screen-cast-stream-src.c -@@ -1134,12 +1134,12 @@ on_stream_add_buffer (void *data, - spa_data->flags = SPA_DATA_FLAG_READWRITE; - spa_data->fd = cogl_dma_buf_handle_get_fd (dmabuf_handle); - -- stride = meta_screen_cast_stream_src_calculate_stride (src, spa_data); -- spa_data->maxsize = stride * priv->video_format.size.height; -- - g_hash_table_insert (priv->dmabuf_handles, - GINT_TO_POINTER (spa_data->fd), - dmabuf_handle); -+ -+ stride = meta_screen_cast_stream_src_calculate_stride (src, spa_data); -+ spa_data->maxsize = stride * priv->video_format.size.height; - } - else - { --- -GitLab - - -From 8d3d8b86e517c97accf11eb243078faf31dd72bb Mon Sep 17 00:00:00 2001 -From: Robert Mader -Date: Fri, 13 Oct 2023 18:29:19 +0200 -Subject: [PATCH 2/2] screen-cast/stream-src: Assert that dmabuf handle lookup - succeeds - -To prevent issues like the one fixed in the previous commit. - -Also remove a redundant variable assignment. - -Part-of: ---- - src/backends/meta-screen-cast-stream-src.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c -index fd49c533930..273c085d5b8 100644 ---- a/src/backends/meta-screen-cast-stream-src.c -+++ b/src/backends/meta-screen-cast-stream-src.c -@@ -564,12 +564,12 @@ meta_screen_cast_stream_src_calculate_stride (MetaScreenCastStreamSrc *src, - - if (spa_data->type == SPA_DATA_DmaBuf) - { -- CoglDmaBufHandle *dmabuf_handle = NULL; -+ CoglDmaBufHandle *dmabuf_handle; - - dmabuf_handle = g_hash_table_lookup (priv->dmabuf_handles, - GINT_TO_POINTER (spa_data->fd)); -- if (dmabuf_handle) -- return cogl_dma_buf_handle_get_stride (dmabuf_handle); -+ g_assert (dmabuf_handle != NULL); -+ return cogl_dma_buf_handle_get_stride (dmabuf_handle); - } - - if (!cogl_pixel_format_from_spa_video_format (priv->video_format.format, --- -GitLab - diff --git a/mutter.spec b/mutter.spec index 755307d..1898113 100644 --- a/mutter.spec +++ b/mutter.spec @@ -13,7 +13,7 @@ %global tarball_version %%(echo %{version} | tr '~' '.') Name: mutter -Version: 45.0 +Version: 45.1 Release: %autorelease Summary: Window and compositing manager based on Clutter @@ -32,39 +32,18 @@ Patch: 0001-place-Always-center-initial-setup-fedora-welcome.patch Patch: 0001-gschema-Enable-scale-monitor-framebuffer-experimenta.patch -# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3299 -Patch: 3299.patch - -# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3306 -Patch: 3306.patch - # https://bugzilla.redhat.com/show_bug.cgi?id=2239128 # https://gitlab.gnome.org/GNOME/mutter/-/issues/3068 # not upstreamed because for upstream we'd really want to find a way # to fix *both* problems Patch: 0001-Revert-x11-Use-input-region-from-frame-window-for-de.patch -# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3324 -Patch: 0001-thread-For-consistency-s-real_time-realtime.patch -Patch: 0002-tests-dbusmock-templates-rtkit-Add-MakeThreadHighPri.patch -Patch: 0003-thread-Allow-turning-off-rt-scheduling-for-running-t.patch -Patch: 0004-kms-impl-device-Inhibit-real-time-scheduling-when-mo.patch - # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3329 # Modified to add the change from # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3329#note_1874837 # which solves the problems reported with #3329 alone Patch: 0001-modified-3329.patch -# https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7148 -# https://bugzilla.redhat.com/show_bug.cgi?id=2247033 -# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3311 -# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3326 -# Fix problems with screen captures being corrupted or not working on -# certain hardware -Patch: 3311.patch -Patch: 3326.patch - BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.41.0 BuildRequires: pkgconfig(sm) BuildRequires: pkgconfig(libwacom) diff --git a/sources b/sources index f6bdb01..13e2f53 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (mutter-45.0.tar.xz) = bbf813a720a3d8545969d089790f6e4c19cd5c8eb3079ba028945e4728446c78aa7540061ea87e43151c2ef359ea986b0e7a45f56f0eb6a33ca2c3979955bb43 +SHA512 (mutter-45.1.tar.xz) = 87a629e941eb231d05fc24dbb905acb12236c971a02dd000fdd6cc6e7686544b5796ce57d10b34e096dc956578a373d5a73e89760bcc6beb292e9a25ce2faaf4