summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2016-04-03 19:08:41 -0700
committerCosimo Cecchi <cosimoc@gnome.org>2016-04-08 20:49:22 -0700
commit143dfdcc3999ef861978bdb0c34ec04ae6ea5aca (patch)
tree4a7fce84cc75e248ff6b13602f2bdb6be8198112 /tools
parent00b382c5d3b81a7412352cfcdff7fabd5f1b38a8 (diff)
downloadgnome-session-143dfdcc3999ef861978bdb0c34ec04ae6ea5aca.tar.gz
Add a helper to check if session can run on GLES
This is needed on platforms where GLX is not typically available, such as when running on an ARM Mali chipset. The helper is currently not wired, but it will be in a later commit. https://bugzilla.gnome.org/show_bug.cgi?id=686806
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am19
-rw-r--r--tools/gnome-session-check-accelerated-gles-helper.c191
2 files changed, 209 insertions, 1 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 599c891e..23cafc91 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,5 +1,8 @@
bin_PROGRAMS = gnome-session-quit gnome-session-inhibit
-libexec_PROGRAMS = gnome-session-check-accelerated gnome-session-check-accelerated-gl-helper
+libexec_PROGRAMS = \
+ gnome-session-check-accelerated \
+ gnome-session-check-accelerated-gl-helper \
+ gnome-session-check-accelerated-gles-helper
if BUILD_SESSION_SELECTOR
bin_PROGRAMS += gnome-session-selector
@@ -41,6 +44,20 @@ gnome_session_inhibit_CPPFLAGS = \
gnome_session_inhibit_LDADD = \
$(GNOME_SESSION_LIBS)
+gnome_session_check_accelerated_gles_helper_SOURCES = \
+ gnome-session-check-accelerated-common.h \
+ gnome-session-check-accelerated-gles-helper.c
+
+gnome_session_check_accelerated_gles_helper_CPPFLAGS = \
+ -DPKGDATADIR=\""$(pkgdatadir)"\" \
+ $(GLES_TEST_CFLAGS) \
+ $(GTK3_CFLAGS)
+
+gnome_session_check_accelerated_gles_helper_LDADD = \
+ $(GLES_TEST_LIBS) \
+ $(GTK3_LIBS) \
+ $(X11_LIBS)
+
gnome_session_check_accelerated_gl_helper_SOURCES = \
gnome-session-check-accelerated-common.h \
gnome-session-check-accelerated-gl-helper.c
diff --git a/tools/gnome-session-check-accelerated-gles-helper.c b/tools/gnome-session-check-accelerated-gles-helper.c
new file mode 100644
index 00000000..4a6b6a27
--- /dev/null
+++ b/tools/gnome-session-check-accelerated-gles-helper.c
@@ -0,0 +1,191 @@
+/* -*- mode:c; c-basic-offset: 8; indent-tabs-mode: nil; -*- */
+/*
+ *
+ * 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>
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <stdlib.h>
+
+#ifdef GDK_WINDOWING_X11
+#define GL_GLEXT_PROTOTYPES
+
+#include <gdk/gdkx.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+#endif
+
+#include "gnome-session-check-accelerated-common.h"
+
+#ifdef GDK_WINDOWING_X11
+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;
+
+ gdk_error_trap_push ();
+
+ display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+ 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);
+
+ gdk_error_trap_pop_ignored ();
+ return renderer;
+}
+#endif
+
+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;
+
+ context = g_option_context_new (NULL);
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ 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;
+ }
+
+#ifdef GDK_WINDOWING_X11
+ renderer = get_gles_renderer ();
+#endif
+
+ if (renderer != NULL) {
+ if (print_renderer)
+ g_print ("%s", renderer);
+ ret = HELPER_ACCEL;
+ }
+
+out:
+ return ret;
+}