From 0223d38602424e5293305ea57e4523505d9935ee Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 Oct 2019 14:39:25 +0200 Subject: [PATCH] shell-app: Add discrete GPU support for NVidia drivers Use data from switcheroo-control to know which environment variables to use to launch an application on the discrete GPU. switcheroo-control version 2.0 or newer should be installed on Linux platforms. Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1810 --- src/shell-app.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/shell-app.c b/src/shell-app.c index c237a225e..5704f75b1 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -19,6 +19,7 @@ #include "st.h" #include "gtkactionmuxer.h" #include "org-gtk-application.h" +#include "switcheroo-control.h" #ifdef HAVE_SYSTEMD #include @@ -1255,6 +1256,60 @@ wait_pid (GDesktopAppInfo *appinfo, g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL); } +static void +apply_discrete_gpu_env (GAppLaunchContext *context, + ShellGlobal *global) +{ + GDBusProxy *proxy; + GVariant* variant; + guint num_children, i; + + proxy = _shell_global_get_switcheroo_control (global); + if (!proxy) + { + g_warning ("Could not apply discrete GPU environment, switcheroo-control not available"); + return; + } + + variant = shell_net_hadess_switcheroo_control_get_gpus (SHELL_NET_HADESS_SWITCHEROO_CONTROL (proxy)); + if (!variant) + { + g_warning ("Could not apply discrete GPU environment, no GPUs in list"); + return; + } + + num_children = g_variant_n_children (variant); + for (i = 0; i < num_children; i++) + { + g_autoptr(GVariant) gpu; + g_autoptr(GVariant) env = NULL; + g_autoptr(GVariant) default_variant = NULL; + g_autofree const char **env_s = NULL; + guint j; + + gpu = g_variant_get_child_value (variant, i); + if (!gpu || + !g_variant_is_of_type (gpu, G_VARIANT_TYPE ("a{s*}"))) + continue; + + /* Skip over the default GPU */ + default_variant = g_variant_lookup_value (gpu, "Default", NULL); + if (!default_variant || g_variant_get_boolean (default_variant)) + continue; + + env = g_variant_lookup_value (gpu, "Environment", NULL); + if (!env) + continue; + + env_s = g_variant_get_strv (env, NULL); + for (j = 0; env_s[j] != NULL; j = j + 2) + g_app_launch_context_setenv (context, env_s[j], env_s[j+1]); + return; + } + + g_warning ("Could not find discrete GPU data in switcheroo-control"); +} + /** * shell_app_launch: * @timestamp: Event timestamp, or 0 for current event timestamp @@ -1290,7 +1345,7 @@ shell_app_launch (ShellApp *app, global = shell_global_get (); context = shell_global_create_app_launch_context (global, timestamp, workspace); if (discrete_gpu) - g_app_launch_context_setenv (context, "DRI_PRIME", "1"); + apply_discrete_gpu_env (context, global); /* Set LEAVE_DESCRIPTORS_OPEN in order to use an optimized gspawn * codepath. The shell's open file descriptors should be marked CLOEXEC