From 5416fd09eb7f24bbe6aea665435008013a1de207 Mon Sep 17 00:00:00 2001
From: Jeremy Whiting <jeremy.whiting@collabora.com>
Date: Tue, 2 Jul 2019 19:43:45 -0600
Subject: [PATCH] GL and GLES helpers initial commit.

In order to check opengl and gles on linux desktop for multiple
architectures build check-gl|gles] with architecture prefix.
Modifications from upstream sources include:
Removing kernel parameter checks for gnome.fallback, just run no need
to check for fallbacks.
Removing blacklisted renderer list support, no need for our use case.
Removing dependency on gtk+ and gdk.
Removing dependency on epoxy.
---
 COPYING                                       |  42 +-
 helpers/check-gl.c                            | 381 ++++++++++++++++++
 helpers/check-gles.c                          | 189 +++++++++
 .../gnome-session-check-accelerated-common.h  |  29 ++
 helpers/meson.build                           |  33 ++
 5 files changed, 657 insertions(+), 17 deletions(-)
 create mode 100644 helpers/check-gl.c
 create mode 100644 helpers/check-gles.c
 create mode 100644 helpers/gnome-session-check-accelerated-common.h

diff --git a/COPYING b/COPYING
index 98f72bd40..f55400336 100644
--- a/COPYING
+++ b/COPYING
@@ -1,22 +1,30 @@
 Copyright © 2019 Collabora Ltd.
 
-SPDX-License-Identifier: MIT
+SPDX-License-Identifier: MIT and GPL-2.0-or-later
 
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
+See individual source files for details.
 
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
+The shared library is under the MIT/X11 license:
+
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    "Software"), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Separate helper executables in the helpers/ directory are under various
+licenses including MIT/X11 and GPL-2.0-or-later.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/helpers/check-gl.c b/helpers/check-gl.c
new file mode 100644
index 000000000..c5029b263
--- /dev/null
+++ b/helpers/check-gl.c
@@ -0,0 +1,381 @@
+/*
+ * check-gl - OpenGL functional check helper for steam-runtime-tools
+ * Based on gnome-session-check-accelerated-gl-helper from gnome-session.
+ *
+ * Copyright (C) 2019      Collabora Ltd.
+ * Copyright (C) 2010      Novell, Inc.
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author:
+ *   Vincent Untz <vuntz@gnome.org>
+ *
+ * Most of the code comes from desktop-effects [1], released under GPLv2+.
+ * desktop-effects was written by:
+ *   Soren Sandmann <sandmann@redhat.com>
+ *
+ * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
+ */
+
+/*
+ * Here's the rationale behind this helper, quoting Owen, in his mail to the
+ * release team:
+ * (http://mail.gnome.org/archives/release-team/2010-June/msg00079.html)
+ *
+ * """
+ * There are some limits to what we can do here automatically without
+ * knowing anything about the driver situation on the system. The basic
+ * problem is that there are all sorts of suck:
+ *
+ *  * No GL at all. This typically only happens if a system is
+ *    misconfigured.
+ *
+ *  * Only software GL. This one is easy to detect. We have code in
+ *    the Fedora desktop-effects tool, etc.
+ *
+ *  * GL that isn't featureful enough. (Tiny texture size limits, no
+ *    texture-from-pixmap, etc.) Possible to detect with more work, but
+ *    largely a fringe case.
+ *
+ *  * Buggy GL. This isn't possible to detect. Except for the case where
+ *    all GL programs crash. For that reason, we probably don't want
+ *    gnome-session to directly try and do any GL detection; better to
+ *    use a helper binary.
+ *
+ *  * Horribly slow hardware GL. We could theoretically develop some sort
+ *    of benchmark, but it's a tricky area. And how slow is too slow?
+ * """
+ *
+ * Some other tools are doing similar checks:
+ *  - desktop-effects (Fedora Config Tool) [1]
+ *  - drak3d (Mandriva Config Tool) [2]
+ *  - compiz-manager (Compiz wrapper) [3]
+ *
+ * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
+ * [2] http://svn.mandriva.com/cgi-bin/viewvc.cgi/soft/drak3d/trunk/lib/Xconfig/glx.pm?view=markup
+ * [3] http://git.compiz.org/fusion/misc/compiz-manager/tree/compiz-manager
+ */
+
+/* for strcasestr */
+#define _GNU_SOURCE
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include <regex.h>
+
+#ifdef __FreeBSD__
+#include <kenv.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xcomposite.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+#include "gnome-session-check-accelerated-common.h"
+
+#define SIZE_UNSET 0
+#define SIZE_ERROR -1
+static int max_texture_size = SIZE_UNSET;
+static int max_renderbuffer_size = SIZE_UNSET;
+static gboolean has_llvmpipe = FALSE;
+
+static inline void
+_print_error (const char *str)
+{
+        fprintf (stderr, "gnome-session-is-accelerated: %s\n", str);
+}
+
+static gboolean
+_is_comment (const char *line)
+{
+        while (*line && isspace(*line))
+                line++;
+
+        if (*line == '#' || *line == '\0')
+                return TRUE;
+        return FALSE;
+}
+
+static gboolean
+_is_gl_renderer_blacklisted (const char *renderer)
+{
+        return FALSE;
+#if 0
+        FILE *blacklist;
+        char *line = NULL;
+        size_t line_len = 0;
+        gboolean ret = TRUE;
+
+        blacklist = fopen(PKGDATADIR "/hardware-compatibility", "r");
+        if (blacklist == NULL)
+                goto out;
+
+        while (getline (&line, &line_len, blacklist) != -1) {
+                int whitelist = 0;
+                const char *re_str;
+                regex_t re;
+                int status;
+
+                if (line == NULL)
+                        break;
+
+                /* Drop trailing \n */
+                line[strlen(line) - 1] = '\0';
+
+                if (_is_comment (line)) {
+                        free (line);
+                        line = NULL;
+                        continue;
+                }
+
+                if (line[0] == '+')
+                        whitelist = 1;
+                else if (line[0] == '-')
+                        whitelist = 0;
+                else {
+                        _print_error ("Invalid syntax in this line for hardware compatibility:");
+                        _print_error (line);
+                        free (line);
+                        line = NULL;
+                        continue;
+                }
+
+                re_str = line + 1;
+
+                if (regcomp (&re, re_str, REG_EXTENDED|REG_ICASE|REG_NOSUB) != 0) {
+                        _print_error ("Cannot use this regular expression for hardware compatibility:");
+                        _print_error (re_str);
+                } else {
+                        status = regexec (&re, renderer, 0, NULL, 0);
+                        regfree(&re);
+
+                        if (status == 0) {
+                                if (whitelist)
+                                        ret = FALSE;
+                                goto out;
+                        }
+                }
+
+                free (line);
+                line = NULL;
+        }
+
+        ret = FALSE;
+
+out:
+        if (line != NULL)
+                free (line);
+
+        if (blacklist != NULL)
+                fclose (blacklist);
+
+        return ret;
+#endif
+}
+
+static char *
+_get_hardware_gl (Display *display)
+{
+        int screen;
+        Window root;
+        XVisualInfo *visual = NULL;
+        GLXContext context = NULL;
+        XSetWindowAttributes cwa = { 0 };
+        Window window = None;
+        char *renderer = NULL;
+
+        int attrlist[] = {
+                GLX_RGBA,
+                GLX_RED_SIZE, 1,
+                GLX_GREEN_SIZE, 1,
+                GLX_BLUE_SIZE, 1,
+                GLX_DOUBLEBUFFER,
+                None
+        };
+
+        screen = DefaultScreen (display);
+        root = RootWindow (display, screen);
+
+        visual = glXChooseVisual (display, screen, attrlist);
+        if (!visual)
+                goto out;
+
+        context = glXCreateContext (display, visual, NULL, True);
+        if (!context)
+                goto out;
+
+        cwa.colormap = XCreateColormap (display, root,
+                                        visual->visual, AllocNone);
+        cwa.background_pixel = 0;
+        cwa.border_pixel = 0;
+        window = XCreateWindow (display, root,
+                                0, 0, 1, 1, 0,
+                                visual->depth, InputOutput, visual->visual,
+                                CWColormap | CWBackPixel | CWBorderPixel,
+                                &cwa);
+
+        if (!glXMakeCurrent (display, window, context))
+                goto out;
+
+        renderer = g_strdup ((const char *) glGetString (GL_RENDERER));
+        if (_is_gl_renderer_blacklisted (renderer)) {
+                g_clear_pointer (&renderer, g_free);
+                goto out;
+        }
+        if (renderer && strcasestr (renderer, "llvmpipe"))
+		has_llvmpipe = TRUE;
+
+        /* we need to get the max texture and renderbuffer sizes while we have
+         * a context, but we'll check their values later */
+
+        glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
+        if (glGetError() != GL_NO_ERROR)
+                max_texture_size = SIZE_ERROR;
+
+        glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE_EXT, &max_renderbuffer_size);
+        if (glGetError() != GL_NO_ERROR)
+                max_renderbuffer_size = SIZE_ERROR;
+
+out:
+        glXMakeCurrent (display, None, None);
+        if (context)
+                glXDestroyContext (display, context);
+        if (window)
+                XDestroyWindow (display, window);
+        if (cwa.colormap)
+                XFreeColormap (display, cwa.colormap);
+
+        return renderer;
+}
+
+static gboolean
+_has_extension (const char *extension_list,
+                const char *extension)
+{
+        char **extensions;
+        guint i;
+        gboolean ret;
+
+        g_return_val_if_fail (extension != NULL, TRUE);
+
+        /* Extension_list is one big string, containing extensions
+         * separated by spaces. */
+        if (extension_list == NULL)
+                return FALSE;
+
+        ret = FALSE;
+
+        extensions = g_strsplit (extension_list, " ", -1);
+        if (extensions == NULL)
+                return FALSE;
+
+        for (i = 0; extensions[i] != NULL; i++) {
+                if (g_str_equal (extensions[i], extension)) {
+                        ret = TRUE;
+                        break;
+                }
+        }
+
+        g_strfreev (extensions);
+
+        return ret;
+}
+
+static gboolean
+_display_has_extension (Display *display, const char *extension)
+{
+        int screen;
+        const char *server_extensions;
+        const char *client_extensions;
+        gboolean ret = FALSE;
+
+        screen = DefaultScreen (display);
+
+        server_extensions = glXQueryServerString (display, screen,
+                                                  GLX_EXTENSIONS);
+        if (!_has_extension (server_extensions,
+                            extension)) 
+                goto out;
+
+        client_extensions = glXGetClientString (display, GLX_EXTENSIONS);
+        if (!_has_extension (client_extensions,
+                            extension))
+                goto out;
+
+        ret = TRUE;
+
+out:
+        return ret;
+}
+
+static gboolean print_renderer = FALSE;
+
+static const GOptionEntry entries[] = {
+        { "print-renderer", 'p', 0, G_OPTION_ARG_NONE, &print_renderer, "Print GL renderer name", NULL },
+        { NULL },
+};
+
+int
+main (int argc, char **argv)
+{
+        Display        *display = NULL;
+        int             ret = HELPER_NO_ACCEL;
+        GOptionContext *context;
+        GError         *error = NULL;
+        char           *renderer = NULL;
+
+        setlocale (LC_ALL, "");
+
+        context = g_option_context_new (NULL);
+        g_option_context_add_main_entries (context, entries, NULL);
+
+        if (!g_option_context_parse (context, &argc, &argv, &error)) {
+                g_error ("Can't parse command line: %s\n", error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        display = XOpenDisplay (NULL);
+        if (!display) {
+                _print_error ("No X display.");
+                goto out;
+        }
+
+        renderer = _get_hardware_gl (display);
+        if (!renderer) {
+                _print_error ("No hardware 3D support.");
+                goto out;
+        }
+
+        ret = has_llvmpipe ? HELPER_SOFTWARE_RENDERING : HELPER_ACCEL;
+
+        if (print_renderer)
+                g_print ("%s", renderer);
+
+out:
+        if (display)
+                XCloseDisplay (display);
+        g_free (renderer);
+
+        return ret;
+}
diff --git a/helpers/check-gles.c b/helpers/check-gles.c
new file mode 100644
index 000000000..5a44f08d4
--- /dev/null
+++ b/helpers/check-gles.c
@@ -0,0 +1,189 @@
+/*
+ * check-gles OpenGLES functional check helper for steam-runtime-tools
+ * Based on gnome-session-check-accelerated-gles-heper from gnome-session.
+ *
+ * Copyright (C) 2019 Collabora Ltd.
+ * Copyright (C) 2016 Endless Mobile, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ *   Cosimo Cecchi <cosimo@endlessm.com>
+ */
+
+/* for strcasestr */
+#define _GNU_SOURCE
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+
+#include "gnome-session-check-accelerated-common.h"
+
+static char *
+get_gles_renderer (void)
+{
+        /* Select GLESv2 config */
+        EGLint attribs[] = {
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_RED_SIZE, 1,
+                EGL_GREEN_SIZE, 1,
+                EGL_BLUE_SIZE, 1,
+                EGL_NONE
+        };
+
+        EGLint ctx_attribs[] = {
+                EGL_CONTEXT_CLIENT_VERSION, 2,
+                EGL_NONE
+        };
+
+        gboolean egl_inited = FALSE;
+        Display *display;
+        Window win = None;
+        EGLContext egl_ctx = NULL;
+        EGLDisplay egl_dpy = NULL;
+        EGLSurface egl_surf = NULL;
+        char *renderer = NULL;
+
+        display = XOpenDisplay (NULL);
+        egl_dpy = eglGetDisplay (display);
+        if (!egl_dpy) {
+                g_warning ("eglGetDisplay() failed");
+                goto out;
+        }
+
+        EGLint egl_major, egl_minor;
+        if (!eglInitialize (egl_dpy, &egl_major, &egl_minor)) {
+                g_warning ("eglInitialize() failed");
+                goto out;
+        }
+
+        egl_inited = TRUE;
+
+        EGLint num_configs;
+        EGLConfig config;
+        if (!eglChooseConfig (egl_dpy, attribs, &config, 1, &num_configs)) {
+                g_warning ("Failed to get EGL configuration");
+                goto out;
+        }
+
+        EGLint vid;
+        if (!eglGetConfigAttrib (egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
+                g_warning ("Failed to get EGL visual");
+                goto out;
+        }
+
+        /* The X window visual must match the EGL config */
+        XVisualInfo *vis_info, vis_template;
+        int num_visuals;
+        vis_template.visualid = vid;
+        vis_info = XGetVisualInfo (display, VisualIDMask, &vis_template, &num_visuals);
+        if (!vis_info) {
+                g_warning ("Failed to get X visual");
+                goto out;
+        }
+
+        XSetWindowAttributes attr;
+        attr.colormap = XCreateColormap (display, DefaultRootWindow (display),
+                                         vis_info->visual, AllocNone);
+        win = XCreateWindow (display, DefaultRootWindow (display),
+                             0, 0, /* x, y */
+                             1, 1, /* width, height */
+                             0,    /* border_width */
+                             vis_info->depth, InputOutput,
+                             vis_info->visual, CWColormap, &attr);
+        XFree (vis_info);
+
+        eglBindAPI (EGL_OPENGL_ES_API);
+
+        egl_ctx = eglCreateContext (egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs);
+        if (!egl_ctx) {
+                g_warning ("Failed to create EGL context");
+                goto out;
+        }
+
+        egl_surf = eglCreateWindowSurface (egl_dpy, config, win, NULL);
+        if (!egl_surf) {
+                g_warning ("Failed to create EGL surface");
+                goto out;
+        }
+
+        if (!eglMakeCurrent (egl_dpy, egl_surf, egl_surf, egl_ctx)) {
+                g_warning ("eglMakeCurrent() failed");
+                goto out;
+        }
+
+        renderer = g_strdup ((const char *) glGetString (GL_RENDERER));
+
+ out:
+        if (egl_ctx)
+                eglDestroyContext (egl_dpy, egl_ctx);
+        if (egl_surf)
+                eglDestroySurface (egl_dpy, egl_surf);
+        if (egl_inited)
+                eglTerminate (egl_dpy);
+        if (win != None)
+                XDestroyWindow (display, win);
+
+        return renderer;
+}
+
+static gboolean print_renderer = FALSE;
+
+static const GOptionEntry entries[] = {
+        { "print-renderer", 'p', 0, G_OPTION_ARG_NONE, &print_renderer, "Print EGL renderer name", NULL },
+        { NULL },
+};
+
+int
+main (int argc,
+      char **argv)
+{
+        char *renderer = NULL;
+        GOptionContext *context;
+        int ret = HELPER_NO_ACCEL;
+        GError *error = NULL;
+
+        setlocale (LC_ALL, "");
+
+        context = g_option_context_new (NULL);
+        g_option_context_add_main_entries (context, entries, NULL);
+
+        if (!g_option_context_parse (context, &argc, &argv, &error)) {
+                g_error ("Can't parse command line: %s\n", error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        renderer = get_gles_renderer ();
+
+        if (renderer != NULL) {
+                if (print_renderer)
+                        g_print ("%s", renderer);
+                if (strcasestr (renderer, "llvmpipe"))
+                        ret = HELPER_SOFTWARE_RENDERING;
+                else
+                        ret = HELPER_ACCEL;
+        }
+
+out:
+        return ret;
+}
+
diff --git a/helpers/gnome-session-check-accelerated-common.h b/helpers/gnome-session-check-accelerated-common.h
new file mode 100644
index 000000000..59631d9cc
--- /dev/null
+++ b/helpers/gnome-session-check-accelerated-common.h
@@ -0,0 +1,29 @@
+/* -*- mode:c; c-basic-offset: 8; indent-tabs-mode: nil; -*- */
+/* Tool to set the property _GNOME_SESSION_ACCELERATED on the root window */
+/*
+ * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author:
+ *   Frederic Crozat <fcrozat@suse.com>
+ */
+
+/* Exit value for helper */
+#define HELPER_ACCEL 0
+#define HELPER_NO_ACCEL 1
+#define HELPER_SOFTWARE_RENDERING 2
+
diff --git a/helpers/meson.build b/helpers/meson.build
index 386c962b1..639cce39c 100644
--- a/helpers/meson.build
+++ b/helpers/meson.build
@@ -31,4 +31,37 @@ executable(
   )
 )
 
+glib_dep = dependency('glib-2.0')
+x11_dep = dependency('x11')
+
+executable(
+  multiarch + '-check-gl',
+  'check-gl.c',
+  install : true,
+  install_dir : join_paths(
+    get_option('libexecdir'),
+    'steam-runtime-tools-' + api_major,
+  ),
+  dependencies : [ glib_dep, 
+    x11_dep, 
+    dependency('gl'), 
+    dependency('xcomposite')
+  ]
+)
+
+executable(
+  multiarch + '-check-gles',
+  'check-gles.c',
+  install : true,
+  install_dir : join_paths(
+    get_option('libexecdir'),
+    'steam-runtime-tools-' + api_major,
+  ),
+  dependencies: [ glib_dep,
+    x11_dep,
+    dependency('egl'),
+    dependency('glesv2')
+  ]
+)
+
 # vim:set sw=2 sts=2 et:
-- 
GitLab