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
This commit is contained in:
Bastien Nocera 2019-10-24 14:39:25 +02:00
parent 33c10e9180
commit 0223d38602

View File

@ -19,6 +19,7 @@
#include "st.h"
#include "gtkactionmuxer.h"
#include "org-gtk-application.h"
#include "switcheroo-control.h"
#ifdef HAVE_SYSTEMD
#include <systemd/sd-journal.h>
@ -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