File compiz-ldpreload-indirect.diff of Package compiz
diff --git a/src/display.c b/src/display.c
index 72515b6..99d3e96 100644
--- a/src/display.c
+++ b/src/display.c
@@ -30,6 +30,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <sys/poll.h>
#include <assert.h>
@@ -44,6 +46,8 @@
#include <compiz-core.h>
+extern int libGLFallback;
+
static unsigned int virtualModMask[] = {
CompAltMask, CompMetaMask, CompSuperMask, CompHyperMask,
CompModeSwitchMask, CompNumLockMask, CompScrollLockMask
@@ -2048,6 +2052,29 @@ addDisplay (const char *name)
COMP_DISPLAY_OPTION_NUM))
return FALSE;
+ if (strstr (ServerVendor (dpy), "DMX"))
+ libGLFallback = 0;
+
+ if (libGLFallback)
+ {
+ const char *vendor;
+ if (! (vendor = glXGetClientString (dpy, GLX_VENDOR)))
+ return FALSE;
+ if (strstr (vendor, "NVIDIA") != NULL) {
+ if ((vendor = glXQueryServerString (dpy, DefaultScreen (dpy),
+ GLX_VENDOR)) &&
+ (strstr (vendor, "NVIDIA") == NULL)) {
+ /* Remove CLOSE_ON_EXEC flag to avoid server resets during
+ * re-exec with LD_PRELOAD */
+ fcntl (ConnectionNumber(dpy), F_SETFD,
+ fcntl (ConnectionNumber(dpy), F_GETFD) & ~FD_CLOEXEC);
+ /* dpy is never closed, in this case this is a blessing */
+ libGLFallback = 2;
+ return FALSE;
+ }
+ }
+ }
+
d->opt[COMP_DISPLAY_OPTION_ABI].value.i = CORE_ABIVERSION;
snprintf (d->displayString, 255, "DISPLAY=%s", DisplayString (dpy));
diff --git a/src/main.c b/src/main.c
index ec76311..20893b3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -71,6 +71,8 @@ Bool useCow = TRUE;
Bool windowManagement = FALSE;
Bool manualCompositeManagement = FALSE;
+int libGLFallback = 1; /* 0: --no-*fallback 1: possible 2: do it */
+
CompMetadata coreMetadata;
static void
@@ -266,6 +268,11 @@ main (int argc, char **argv)
signal (SIGINT, signalHandler);
signal (SIGTERM, signalHandler);
+ /* Except for native NVidia libGL (which doesn't know this ENV var),
+ * GLX_EXT_texture_from_pixmap is only available on purely indirect
+ * contexts. Specifying indirect rendering per context isn't enough. */
+ putenv ("LIBGL_ALWAYS_INDIRECT=1");
+
emptyRegion.rects = &emptyRegion.extents;
emptyRegion.numRects = 0;
emptyRegion.extents.x1 = 0;
@@ -361,6 +368,10 @@ main (int argc, char **argv)
if (i + 1 < argc)
backgroundImage = argv[++i];
}
+ else if (!strcmp (argv[i], "--no-libgl-fallback"))
+ {
+ libGLFallback = 0;
+ }
else if (*argv[i] == '-')
{
compLogMessage ("core", CompLogLevelWarn,
@@ -445,7 +456,23 @@ main (int argc, char **argv)
}
if (!manageDisplay (core.displays))
+ {
+ if (libGLFallback == 2)
+ {
+ char *arg[argc + 2];
+ static const char *libindirect_libgl = "/usr/$LIB/libIndirectGL.so.1";
+ memcpy (arg, argv, sizeof (char *) * argc);
+
+ arg[argc] = "--no-libgl-fallback";
+ arg[argc + 1] = NULL;
+
+ fprintf (stderr, "%s: Trying '%s'\n", programName, libindirect_libgl);
+
+ setenv ("LD_PRELOAD", libindirect_libgl, TRUE);
+ execvp (arg[0], arg);
+ }
return 1;
+ }
eventLoop ();