[gnome-session] tools: Add a gnome-session-is-accelerated helper tool
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session] tools: Add a gnome-session-is-accelerated helper tool
- Date: Mon, 29 Nov 2010 19:09:50 +0000 (UTC)
commit f8d340652f597cfef6e06aef1e271ab7fde24f27
Author: Vincent Untz <vuntz gnome org>
Date: Mon Nov 29 19:31:02 2010 +0100
tools: Add a gnome-session-is-accelerated helper tool
This small tool does various checks, and it will be used to know if we
can run GNOME Shell or not.
configure.ac | 1 +
tools/Makefile.am | 25 +++-
tools/gnome-session-is-accelerated.c | 293 ++++++++++++++++++++++++++++++++++
3 files changed, 313 insertions(+), 6 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 7a2181b..53d7b5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,7 @@ PKG_CHECK_MODULES(GCONF, gconf-2.0)
PKG_CHECK_MODULES(EGG_SMCLIENT, gtk+-$GTK_API_VERSION)
+PKG_CHECK_MODULES(GL_TEST, xcomposite gl)
dnl ====================================================================
dnl Option to set the default window manager
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 7110543..7808cc8 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,17 +1,21 @@
bin_PROGRAMS = gnome-session-save
+libexec_PROGRAMS = gnome-session-is-accelerated
-AM_CPPFLAGS = \
- $(GNOME_SESSION_CFLAGS) \
- $(DBUS_GLIB_CFLAGS) \
- $(GCONF_FLAGS) \
- -DLOCALE_DIR=\""$(datadir)/locale"\" \
- $(DISABLE_DEPRECATED_CFLAGS)
+AM_CPPFLAGS =
AM_CFLAGS = $(WARN_CFLAGS)
gnome_session_save_SOURCES = \
gnome-session-save.c
+gnome_session_save_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ $(GNOME_SESSION_CFLAGS) \
+ $(DBUS_GLIB_CFLAGS) \
+ $(GCONF_FLAGS) \
+ -DLOCALE_DIR=\""$(datadir)/locale"\" \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
gnome_session_save_LDADD = \
$(SM_LIBS) \
$(ICE_LIBS) \
@@ -19,4 +23,13 @@ gnome_session_save_LDADD = \
$(DBUS_GLIB_LIBS) \
$(GCONF_LIBS)
+gnome_session_is_accelerated_SOURCES = \
+ gnome-session-is-accelerated.c
+
+gnome_session_is_accelerated_CPPFLAGS = \
+ $(GL_TEST_CFLAGS)
+
+gnome_session_is_accelerated_LDADD = \
+ $(GL_TEST_LIBS)
+
-include $(top_srcdir)/git.mk
diff --git a/tools/gnome-session-is-accelerated.c b/tools/gnome-session-is-accelerated.c
new file mode 100644
index 0000000..6b8b1a4
--- /dev/null
+++ b/tools/gnome-session-is-accelerated.c
@@ -0,0 +1,293 @@
+/* gcc -o gnome-session-accelerated `pkg-config --cflags --libs xcomposite gl` -Wall gnome-session-is-accelerated.c */
+
+/*
+ * 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 <stdio.h>
+#include <string.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+static int max_texture_size = 0;
+
+static inline void
+_print_error (const char *str)
+{
+ fprintf (stderr, "%s\n", str);
+}
+
+static int
+_has_composite (Display *display)
+{
+ int dummy1, dummy2;
+
+ if (XCompositeQueryExtension (display, &dummy1, &dummy2))
+ return 0;
+
+ return 1;
+}
+
+static int
+_has_hardware_gl (Display *display)
+{
+ int screen;
+ Window root;
+ XVisualInfo *visual = NULL;
+ GLXContext context = NULL;
+ XSetWindowAttributes cwa = { 0 };
+ Window window = None;
+ const char *renderer;
+ int ret = 1;
+
+ 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 = (const char *) glGetString (GL_RENDERER);
+ /* The current Mesa software GL renderer string is
+ * "Software Rasterizer" */
+ if (strcasestr (renderer, "software rasterizer") != NULL)
+ goto out;
+
+ /* we need to get the max texture size while we have a context,
+ * but we'll check its value later */
+ glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
+ if (glGetError() != GL_NO_ERROR)
+ max_texture_size = -1;
+
+ ret = 0;
+
+out:
+ glXMakeCurrent (display, None, None);
+ if (context)
+ glXDestroyContext (display, context);
+ if (window)
+ XDestroyWindow (display, window);
+ if (cwa.colormap)
+ XFreeColormap (display, cwa.colormap);
+
+ return ret;
+}
+
+static int
+_has_extension (const char *extension_list,
+ const char *extension)
+{
+ int s = 0, e = 0;
+ int ext_len;
+
+ /* Extension_list is one big string, containing extensions
+ * separated by spaces. We could use strstr, except that we
+ * can't know for sure that there's no extension that starts
+ * with the same string... */
+
+ if (!extension_list || extension_list[0] == 0)
+ return 1;
+ if (!extension || extension[0] == 0)
+ return 0;
+
+ ext_len = strlen (extension);
+
+ while (1) {
+ if (extension_list[e] != ' ' && extension_list[e] != 0) {
+ e++;
+ continue;
+ }
+
+ /* End of a word. Was is the extension we're looking for? */
+ if ((e - s) == ext_len &&
+ strncmp (&extension_list[s], extension, ext_len) == 0) {
+ return 0;
+ }
+
+ /* was it the end of the string? */
+ if (extension_list[e] == 0)
+ break;
+
+ /* skip the space and start looking at the next word */
+ e++;
+ s = e;
+ }
+
+ return 1;
+}
+
+static int
+_has_texture_from_pixmap (Display *display)
+{
+ int screen;
+ const char *server_extensions;
+ const char *client_extensions;
+ int ret = 1;
+
+ screen = DefaultScreen (display);
+
+ server_extensions = glXQueryServerString (display, screen,
+ GLX_EXTENSIONS);
+ if (_has_extension (server_extensions,
+ "GLX_EXT_texture_from_pixmap") != 0)
+ goto out;
+
+ client_extensions = glXGetClientString (display, GLX_EXTENSIONS);
+ if (_has_extension (client_extensions,
+ "GLX_EXT_texture_from_pixmap") != 0)
+ goto out;
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+_is_max_texture_size_big_enough (Display *display)
+{
+ int screen;
+
+ screen = DefaultScreen (display);
+ if (max_texture_size < DisplayWidth (display, screen) ||
+ max_texture_size < DisplayHeight (display, screen))
+ return 1;
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ Display *display = NULL;
+ int ret = 1;
+
+ display = XOpenDisplay (NULL);
+ if (!display) {
+ _print_error ("No X display.");
+ goto out;
+ }
+
+ if (_has_composite (display) != 0) {
+ _print_error ("No composite extension.");
+ goto out;
+ }
+
+ if (_has_hardware_gl (display) != 0) {
+ _print_error ("No hardware 3D support.");
+ goto out;
+ }
+
+ if (_has_texture_from_pixmap (display) != 0) {
+ _print_error ("No GLX_EXT_texture_from_pixmap support.");
+ goto out;
+ }
+
+ if (_is_max_texture_size_big_enough (display) != 0) {
+ _print_error ("GL_MAX_TEXTURE_SIZE is too small.");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ if (display)
+ XCloseDisplay (display);
+
+ return ret;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]