File project.diff of Package Mesa
--- Mesa.changes.orig
+++ Mesa.changes
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Thu Mar 12 14:34:53 EDT 2009 - davidr@novell.com
+
+- Chromium DRI support.
+- Avoid non 32-bit ARGB visuals when LIBGL_ONLY_ARGB_VISUALS is set.
+
+-------------------------------------------------------------------
Sat Mar 7 04:17:18 CET 2009 - sndirsch@suse.de
- mesa-commit-954dfba.diff
--- Mesa.spec.orig
+++ Mesa.spec
@@ -19,7 +19,7 @@
Name: Mesa
-BuildRequires: gcc-c++ libdrm-devel libexpat-devel pkgconfig xorg-x11-devel
+BuildRequires: gcc-c++ libdrm-devel libexpat-devel pkgconfig xorg-x11-devel cr-devel
Url: http://www.mesa3d.org
License: X11/MIT
Group: System/Libraries
@@ -47,6 +47,8 @@ Patch9: mesa-commit-954dfba.diff
Patch10: mesa-commit-88b702e.diff
Patch14: intel_release_static_region.patch
Patch15: Mesa_indirect_old_xserver_compatibility.diff
+Patch16: mesa-chromium.diff
+Patch17: mesa-only-argb-visuals.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
@@ -141,11 +143,13 @@ sed -i 's/REPLACE/%_lib/g' src/glx/x11/M
%patch10 -p1
%patch14 -p1
%patch15 -p1
+%patch16 -p1
+%patch17 -p1
%build
%install
-#autoreconf -fi
+autoreconf -fi
### libGL (disable savage/mga, bnc #402132/#403071)
%configure --disable-glw \
--with-driver=dri \
@@ -155,7 +159,8 @@ sed -i 's/REPLACE/%_lib/g' src/glx/x11/M
%ifarch s390 s390x
--with-dri-drivers=swrast \
%endif
- --disable-glut
+ --disable-glut \
+ --enable-chromium
gmake
make install DESTDIR=$RPM_BUILD_ROOT
# build and install Indirect Rendering only libGL
--- mesa-chromium.diff.orig
+++ mesa-chromium.diff
@@ -0,0 +1,774 @@
+commit 664865d747b47409b04f13fbeb8402400e1e2046
+Author: David Reveman <davidr@novell.com>
+Date: Wed Mar 11 13:36:53 2009 -0400
+
+ Chromium DRI support.
+
+diff --git a/configure.ac b/configure.ac
+index 46070fd..87b1e8c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1180,6 +1180,20 @@ if test "x$enable_gallium_nouveau" = xyes; then
+ GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nv04 nv10 nv20 nv30 nv40 nv50"
+ fi
+
++dnl CHROMIUM
++AC_ARG_ENABLE([chromium],
++ [AS_HELP_STRING([--enable-chromium],
++ [use CHROMIUM for GLX @<:@default=disabled@:>@])],
++ [enable_cr="$enableval"],
++ [enable_cr=no])
++if test "x$enable_cr" = xyes; then
++ PKG_CHECK_MODULES([CHROMIUM], [cr])
++ X11_INCLUDES="$X11_INCLUDES $CHROMIUM_CFLAGS"
++ GL_LIB_DEPS="$GL_LIB_DEPS $CHROMIUM_LIBS"
++ DEFINES="$DEFINES -DCHROMIUM"
++else
++ enable_cr=no
++fi
+
+ dnl Restore LDFLAGS and CPPFLAGS
+ LDFLAGS="$_SAVE_LDFLAGS"
+@@ -1226,6 +1240,7 @@ fi
+ echo " DRI driver dir: $DRI_DRIVER_INSTALL_DIR"
+ fi
+ echo " Use XCB: $enable_xcb"
++echo " Use CHROMIUM: $enable_cr"
+
+ echo ""
+ if echo "$SRC_DIRS" | grep 'gallium' >/dev/null 2>&1; then
+diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile
+index 86d84d4..f81a5c7 100644
+--- a/src/glx/x11/Makefile
++++ b/src/glx/x11/Makefile
+@@ -32,6 +32,7 @@ SOURCES = \
+ glx_pbuffer.c \
+ glx_query.c \
+ drisw_glx.c \
++ dricr_glx.c \
+ dri_common.c \
+ dri_glx.c \
+ XF86dri.c \
+diff --git a/src/glx/x11/dricr_glx.c b/src/glx/x11/dricr_glx.c
+new file mode 100644
+index 0000000..6211cd1
+--- /dev/null
++++ b/src/glx/x11/dricr_glx.c
+@@ -0,0 +1,653 @@
++/*
++ * Copyright © 2009 Novell, Inc.
++ *
++ * Permission to use, copy, modify, distribute, and sell this software
++ * and its documentation for any purpose is hereby granted without
++ * fee, provided that the above copyright notice appear in all copies
++ * and that both that copyright notice and this permission notice
++ * appear in supporting documentation, and that the name of
++ * Novell, Inc. not be used in advertising or publicity pertaining to
++ * distribution of the software without specific, written prior permission.
++ * Novell, Inc. makes no representations about the suitability of this
++ * software for any purpose. It is provided "as is" without express or
++ * implied warranty.
++ *
++ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
++ * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
++ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
++ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: David Reveman <davidr@novell.com>
++ */
++
++#ifdef GLX_DIRECT_RENDERING
++#ifdef CHROMIUM
++
++#include <stdarg.h>
++#include <X11/Xlib.h>
++#include <X11/Xatom.h>
++#include "glxclient.h"
++#include "glcontextmodes.h"
++#include "dri_common.h"
++#include "cr_spu.h"
++#include "cr_net.h"
++#include "cr_error.h"
++#include "cr_mem.h"
++#include "cr_string.h"
++#include "cr_mothership.h"
++#include "cr_net.h"
++#include "cr_environment.h"
++#include "cr_process.h"
++
++#include "glapi.h"
++#include "glapioffsets.h"
++#include "glapitable.h"
++
++#define KEYWORD1 static
++#define KEYWORD1_ALT static
++#define KEYWORD2 GLAPIENTRY
++#define NAME(func) NoOp##func
++
++#define F NULL
++
++#define DISPATCH(func, args, msg) \
++ crErrorMessage (F, "unimplemented GL dispatch function call: "); \
++ crErrorMessage msg
++
++#define RETURN_DISPATCH(func, args, msg) \
++ crErrorMessage (F, "unimplemented GL dispatch function call: "); \
++ crErrorMessage msg; \
++ return 0
++
++#define DISPATCH_TABLE_NAME __glapi_table
++#define UNUSED_TABLE_NAME __unused_functions
++
++#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name
++
++static void crErrorMessage (void *d, const char *f, ...)
++{
++ va_list args;
++ const char *env;
++
++ if ((env = getenv ("LIBGL_DEBUG")) && !strstr (env, "quiet"))
++ {
++ fprintf (stderr, "libGL error: ");
++ va_start (args, f);
++ vfprintf (stderr, f, args);
++ va_end (args);
++ }
++}
++
++static GLint NoOpUnused (void)
++{
++ crErrorMessage (F, "unused GL dispatch function call\n");
++ return 0;
++}
++
++#include "glapitemp.h"
++
++typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
++typedef struct __GLXDRIscreenPrivateRec __GLXDRIscreenPrivate;
++typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
++typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
++
++struct __GLXDRIdisplayPrivateRec
++{
++ __GLXDRIdisplay base;
++ SPU *spu;
++};
++
++struct __GLXDRIscreenPrivateRec
++{
++ __GLXDRIscreen base;
++ struct __GLXDRIdisplayPrivateRec *pdp;
++};
++
++struct __GLXDRIcontextPrivateRec
++{
++ __GLXDRIcontext base;
++ __GLXscreenConfigs *psc;
++ GLint spuContext;
++};
++
++struct __GLXDRIdrawablePrivateRec
++{
++ __GLXDRIdrawable base;
++ GLint spuDrawable;
++};
++
++static void
++driGetConfigurationOptions (CRConnection *conn,
++ char **spuDir)
++{
++ char response[1024];
++ int myRank = 0;
++ int lowContext = CR_QUADRICS_DEFAULT_LOW_CONTEXT;
++ int highContext = CR_QUADRICS_DEFAULT_HIGH_CONTEXT;
++ char *lowNode = "none";
++ char *highNode = "none";
++ unsigned char key[16]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
++
++ if (crMothershipGetFakerParam (conn, response, "spu_dir") &&
++ crStrlen (response) > 0)
++ {
++ *spuDir = crStrdup (response);
++ }
++ else
++ {
++ *spuDir = NULL;
++ }
++
++ if (crMothershipGetRank (conn, response))
++ myRank = crStrToInt (response);
++
++ crNetSetRank (myRank);
++
++ if (crMothershipGetParam (conn, "low_context", response))
++ lowContext = crStrToInt (response);
++ if (crMothershipGetParam (conn, "high_context", response))
++ highContext = crStrToInt (response);
++
++ crNetSetContextRange (lowContext, highContext);
++
++ if (crMothershipGetParam (conn, "low_node", response))
++ lowNode = crStrdup (response);
++ if (crMothershipGetParam (conn, "high_node", response))
++ highNode = crStrdup (response);
++
++ crNetSetNodeRange (lowNode, highNode);
++
++ if (crMothershipGetParam (conn, "comm_key", response))
++ {
++ unsigned int a;
++ char **words, *found;
++
++ /* remove the silly []'s */
++ while ((found = crStrchr (response, '[')) != NULL)
++ *found = ' ';
++ while ((found = crStrchr (response, ']')) != NULL)
++ *found = ' ';
++
++ words = crStrSplit(response, ",");
++
++ a = 0;
++ while (words[a] != NULL && a < sizeof (key))
++ {
++ key[a]= crStrToInt (words[a]);
++ a++;
++ }
++
++ crFreeStrings (words);
++ }
++
++ crNetSetKey (key, sizeof (key));
++}
++
++static const void *
++__cr_lookup_func (const char *name, SPU *spu)
++{
++ SPUNamedFunctionTable *temp;
++
++ if (spu == NULL)
++ return NULL;
++
++ for (temp = spu->function_table->table; temp->name != NULL; temp++)
++ if (!strcmp (name, temp->name))
++ return temp->fn;
++
++ return __cr_lookup_func (name, spu->superSPU);
++}
++
++static const void *
++__cr_fuzzy_lookup_func (const char *name, SPU *spu)
++{
++ SPUNamedFunctionTable *temp;
++
++ if (spu == NULL)
++ return NULL;
++
++ for (temp = spu->function_table->table; temp->name != NULL; temp++)
++ {
++ static const char *suffix[] = {
++ "EXT", "ARB", "NV", "ATI", "SGIS", "MESA", "IBM", "APPLE"
++ };
++ int i, j;
++
++ for (i = 0; temp->name[i] == name[i]; i++)
++ if (name[i] == '\0')
++ return temp->fn;
++
++ j = 0;
++ if (name[i] != '\0')
++ for (; j < sizeof (suffix) / sizeof (suffix[0]); j++)
++ if (strcmp (&name[i], suffix[j]) == 0)
++ break;
++
++ if (j < sizeof (suffix) / sizeof (suffix[0]))
++ {
++ if (temp->name[i] == '\0')
++ return temp->fn;
++
++ for (j = 0; j < sizeof (suffix) / sizeof (suffix[0]); j++)
++ if (strcmp (&temp->name[i], suffix[j]) == 0)
++ return temp->fn;
++ }
++ }
++
++ return __cr_fuzzy_lookup_func (name, spu->superSPU);
++}
++
++static const void *
++__cr_reverse_lookup_func (int offset, SPU *spu)
++{
++ SPUNamedFunctionTable *temp;
++ char name[1024];
++
++ if (spu == NULL)
++ return NULL;
++
++ name[0] = 'g';
++ name[1] = 'l';
++
++ for (temp = spu->function_table->table; temp->name != NULL; temp++)
++ {
++ strcpy (&name[2], temp->name);
++
++ if (_glapi_get_proc_offset (name) == offset)
++ return temp->fn;
++ }
++
++ return __cr_reverse_lookup_func (offset, spu->superSPU);
++}
++
++static SPU *
++driCreateSPUChain (Display *dpy)
++{
++ CRConnection *conn;
++ char response[1024];
++ char *spuDir = NULL;
++ char **spuChain;
++ int numSpus;
++ int *spuIds;
++ char **spuNames;
++ SPU *spu = NULL;
++ int i;
++ char *env;
++ Atom actual;
++ int result, format;
++ unsigned long n, left;
++ unsigned char *data = NULL;
++ static Display *display = 0;
++
++ if (display)
++ return NULL;
++
++ display = dpy;
++
++ env = getenv ("CRMOTHERSHIP");
++ if (env)
++ env = strdup (env);
++
++ result = XGetWindowProperty (dpy, DefaultRootWindow (dpy),
++ XInternAtom (dpy, "CRMOTHERSHIP", False),
++ 0L, 1024L, False,
++ XA_STRING,
++ &actual, &format,
++ &n, &left, &data);
++
++ if (result == Success && n && data)
++ {
++ char str[1025];
++
++ strncpy (str, (const char *) data, n);
++ str[n] = '\0';
++
++ InfoMessageF ("Found CRMOTHERSHIP property on root window\n");
++ setenv ("CRMOTHERSHIP", str, 1);
++ }
++ else if (env)
++ {
++ InfoMessageF ("Found CRMOTHERSHIP environment variable\n");
++ }
++ else
++ {
++ return NULL;
++ }
++
++ InfoMessageF ("Connecting to CHROMIUM mothership: %s\n",
++ getenv ("CRMOTHERSHIP"));
++
++ conn = crMothershipConnect ();
++ if (conn)
++ {
++ char *appId = getenv ("CR_APPLICATION_ID_NUMBER");
++
++ if (!appId)
++ appId = "-1";
++
++ InfoMessageF ("Using CHROMIUM application ID: %s\n", appId);
++
++ crMothershipIdentifyOpenGL (conn, response, appId);
++
++ spuChain = crStrSplit (response, " ");
++ numSpus = crStrToInt (spuChain[0]);
++ spuIds = (int *) crAlloc (numSpus * sizeof (*spuIds));
++ spuNames = (char **) crAlloc (numSpus * sizeof (*spuNames));
++
++ for (i = 0; i < numSpus; i++)
++ {
++ spuIds[i] = crStrToInt (spuChain[2 * i + 1]);
++ spuNames[i] = crStrdup (spuChain[2 * i + 2]);
++ }
++
++ driGetConfigurationOptions (conn, &spuDir);
++
++ crMothershipDisconnect (conn);
++
++ if (spuDir)
++ InfoMessageF ("Using CHROMIUM SPU directory: %s\n", spuDir);
++
++ InfoMessageF ("Loading CHROMIUM SPU chain:\n");
++
++ for (i = 0; i < numSpus; i++)
++ InfoMessageF (" SPU %d/%d: (%d) \"%s\"\n",
++ i + 1, numSpus, spuIds[i], spuNames[i]);
++
++ spu = crSPULoadChain (numSpus, spuIds, spuNames, spuDir, NULL);
++
++ crFree (spuChain);
++ crFree (spuIds);
++ for (i = 0; i < numSpus; i++)
++ crFree (spuNames[i]);
++ crFree (spuNames);
++
++ if (spuDir)
++ crFree (spuDir);
++
++ if (spu)
++ {
++ const int entries = sizeof (__glapi_table) / sizeof (void *);
++ const void **tab = (const void **) __glapi_table;
++ int i, count = 0, missing = 0;
++
++ for (i = 0; i < entries; i++)
++ {
++ const char *name = _glapi_get_proc_name (i);
++
++ if (name && name[0] == 'g' && name[1] == 'l')
++ {
++ const void *proc;
++
++ count++;
++
++ proc = __cr_lookup_func (&name[2], spu);
++ if (proc)
++ {
++ tab[i] = proc;
++ continue;
++ }
++
++ proc = __cr_reverse_lookup_func (i, spu);
++ if (proc)
++ {
++ tab[i] = proc;
++ continue;
++ }
++
++ proc = __cr_fuzzy_lookup_func (&name[2], spu);
++ if (proc)
++ {
++ tab[i] = proc;
++ continue;
++ }
++
++ missing++;
++ }
++ }
++
++ InfoMessageF ("CHROMIUM dispatch table completeness: "
++ "%d/%d (%d missing)\n",
++ count - missing, count, missing);
++
++ _glapi_set_dispatch ((struct _glapi_table *) __glapi_table);
++ }
++ }
++ else
++ {
++ ErrorMessageF ("Unable to connect to CHROMIUM mothership");
++ }
++
++ if (env)
++ {
++ setenv ("CRMOTHERSHIP", env, 1);
++ free (env);
++ }
++
++ if (data)
++ XFree (data);
++
++ return spu;
++}
++
++static GLint
++visBitsFromMode (const __GLcontextModes *mode)
++{
++ GLint visBits = 0;
++
++ if (mode->rgbMode)
++ visBits |= CR_RGB_BIT;
++
++ if (mode->doubleBufferMode)
++ visBits |= CR_DOUBLE_BIT;
++
++ if (mode->haveDepthBuffer)
++ visBits |= CR_DEPTH_BIT;
++
++ if (mode->haveStencilBuffer)
++ visBits |= CR_STENCIL_BIT;
++
++ return visBits;
++}
++
++static void
++driDestroyContext (__GLXDRIcontext *context,
++ __GLXscreenConfigs *psc,
++ Display *dpy)
++{
++ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
++ __GLXDRIscreenPrivate *psp = (__GLXDRIscreenPrivate *)
++ pcp->psc->driScreen;
++
++ (*psp->pdp->spu->dispatch_table.DestroyContext) (pcp->spuContext);
++
++ Xfree (pcp);
++}
++
++static Bool
++driBindContext (__GLXDRIcontext *context,
++ __GLXDRIdrawable *draw,
++ __GLXDRIdrawable *read)
++{
++ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
++ __GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) draw;
++ __GLXDRIscreenPrivate *psp = (__GLXDRIscreenPrivate *)
++ pcp->psc->driScreen;
++
++ if (draw != read)
++ return False;
++
++ (*psp->pdp->spu->dispatch_table.MakeCurrent) (pdp->spuDrawable,
++ draw->xDrawable,
++ pcp->spuContext);
++
++ return True;
++}
++
++static void
++driUnbindContext (__GLXDRIcontext *context)
++{
++}
++
++static __GLXDRIcontext *
++driCreateContext (__GLXscreenConfigs *psc,
++ const __GLcontextModes *mode,
++ GLXContext gc,
++ GLXContext shareList,
++ int renderType)
++{
++ __GLXDRIcontextPrivate *pcp, *pcp_shared;
++ __GLXDRIscreenPrivate *psp = (__GLXDRIscreenPrivate *) psc->driScreen;
++ GLint spuShareContext = 0;
++
++ if (!psc || !psp)
++ return NULL;
++
++ if (shareList)
++ {
++ pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
++ spuShareContext = pcp_shared->spuContext;
++ }
++
++ pcp = Xmalloc (sizeof *pcp);
++ if (pcp == NULL)
++ return NULL;
++
++ pcp->base.destroyContext = driDestroyContext;
++ pcp->base.bindContext = driBindContext;
++ pcp->base.unbindContext = driUnbindContext;
++
++ pcp->psc = psc;
++ pcp->spuContext =
++ (*psp->pdp->spu->dispatch_table.CreateContext) (DisplayString (psc->dpy),
++ visBitsFromMode (mode),
++ spuShareContext);
++ if (pcp->spuContext == -1)
++ {
++ Xfree (pcp);
++ return NULL;
++ }
++
++ return &pcp->base;
++}
++
++static void
++driDestroyDrawable (__GLXDRIdrawable *pdraw)
++{
++ __GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
++ __GLXDRIscreenPrivate *psp = (__GLXDRIscreenPrivate *)
++ pdraw->psc->driScreen;
++
++ (*psp->pdp->spu->dispatch_table.WindowDestroy) (pdp->spuDrawable);
++
++ Xfree (pdp);
++}
++
++static __GLXDRIdrawable *
++driCreateDrawable (__GLXscreenConfigs *psc,
++ XID xDrawable,
++ GLXDrawable drawable,
++ const __GLcontextModes *mode)
++{
++ __GLXDRIdrawablePrivate *pdp;
++ __GLXDRIscreenPrivate *psp = (__GLXDRIscreenPrivate *) psc->driScreen;
++
++ pdp = Xmalloc (sizeof *pdp);
++ if (!pdp)
++ return NULL;
++
++ pdp->base.destroyDrawable = driDestroyDrawable;
++ pdp->base.xDrawable = xDrawable;
++ pdp->base.drawable = drawable;
++ pdp->base.psc = psc;
++ pdp->base.textureTarget = 0;
++ pdp->base.driDrawable = NULL;
++
++ XSync (psc->dpy, False);
++
++ pdp->spuDrawable =
++ (*psp->pdp->spu->dispatch_table.WindowCreate) (DisplayString (psc->dpy),
++ visBitsFromMode (mode));
++ if (pdp->spuDrawable == -1)
++ {
++ Xfree (pdp);
++ return NULL;
++ }
++
++ return &pdp->base;
++}
++
++static void
++driSwapBuffers (__GLXDRIdrawable *pdraw)
++{
++ __GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
++ __GLXDRIscreenPrivate *psp = (__GLXDRIscreenPrivate *)
++ pdraw->psc->driScreen;
++
++ (*psp->pdp->spu->dispatch_table.SwapBuffers) (pdp->spuDrawable, 0);
++}
++
++static void
++driDestroyScreen (__GLXscreenConfigs *psc)
++{
++}
++
++static __GLXDRIscreen *
++driCreateScreen (__GLXscreenConfigs *psc,
++ int screen,
++ __GLXdisplayPrivate *pd)
++{
++ __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *) pd->dricrDisplay;
++ __GLXDRIscreenPrivate *psp;
++
++ psp = Xmalloc (sizeof *psp);
++ if (psp == NULL)
++ return NULL;
++
++ /* Initialize per screen dynamic client GLX extensions */
++ psc->ext_list_first_time = GL_TRUE;
++
++ psp->base.destroyScreen = driDestroyScreen;
++ psp->base.createContext = driCreateContext;
++ psp->base.createDrawable = driCreateDrawable;
++ psp->base.swapBuffers = driSwapBuffers;
++
++ psp->pdp = pdp;
++
++ return &psp->base;
++}
++
++static void
++driDestroyDisplay (__GLXDRIdisplay *pd)
++{
++ Xfree (pd);
++}
++
++_X_HIDDEN __GLXDRIdisplay *
++dricrCreateDisplay (Display *dpy)
++{
++ __GLXDRIdisplayPrivate *pdp;
++
++ pdp = Xmalloc (sizeof *pdp);
++ if (pdp == NULL)
++ return NULL;
++
++ pdp->spu = driCreateSPUChain (dpy);
++ if (pdp->spu == NULL)
++ {
++ Xfree (pdp);
++ return NULL;
++ }
++
++ pdp->base.destroyDisplay = driDestroyDisplay;
++ pdp->base.createScreen = driCreateScreen;
++
++ (void) __unused_functions;
++
++ return &pdp->base;
++}
++
++#endif /* CHROMIUM */
++#endif /* GLX_DIRECT_RENDERING */
+diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
+index caf58bb..18e032f 100644
+--- a/src/glx/x11/glxclient.h
++++ b/src/glx/x11/glxclient.h
+@@ -170,6 +170,9 @@ struct __GLXDRIdrawableRec {
+ extern __GLXDRIdisplay *driswCreateDisplay(Display *dpy);
+ extern __GLXDRIdisplay *driCreateDisplay(Display *dpy);
+ extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy);
++#ifdef CHROMIUM
++extern __GLXDRIdisplay *dricrCreateDisplay(Display *dpy);
++#endif
+
+ extern void DRI_glXUseXFont( Font font, int first, int count, int listbase );
+
+@@ -594,6 +597,9 @@ struct __GLXdisplayPrivateRec {
+ __GLXDRIdisplay *driswDisplay;
+ __GLXDRIdisplay *driDisplay;
+ __GLXDRIdisplay *dri2Display;
++#ifdef CHROMIUM
++ __GLXDRIdisplay *dricrDisplay;
++#endif
+ #endif
+ };
+
+diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
+index b296b7c..af7de7c 100644
+--- a/src/glx/x11/glxext.c
++++ b/src/glx/x11/glxext.c
+@@ -183,6 +183,12 @@ __glXFreeDisplayPrivate(XExtData * extension)
+
+ #ifdef GLX_DIRECT_RENDERING
+ /* Free the direct rendering per display data */
++#ifdef CHROMIUM
++ if (priv->dricrDisplay)
++ (*priv->dricrDisplay->destroyDisplay) (priv->dricrDisplay);
++ priv->dricrDisplay = NULL;
++#endif
++
+ if (priv->driswDisplay)
+ (*priv->driswDisplay->destroyDisplay) (priv->driswDisplay);
+ priv->driswDisplay = NULL;
+@@ -618,6 +624,11 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+ if (psc->driScreen == NULL && priv->driDisplay)
+ psc->driScreen = (*priv->driDisplay->createScreen) (psc, i, priv);
+
++#ifdef CHROMIUM
++ if (psc->driScreen == NULL && priv->dricrDisplay)
++ psc->driScreen = (*priv->dricrDisplay->createScreen) (psc, i, priv);
++#endif
++
+ if (psc->driScreen == NULL && priv->driswDisplay)
+ psc->driScreen = (*priv->driswDisplay->createScreen) (psc, i, priv);
+
+@@ -719,6 +730,10 @@ __glXInitialize(Display * dpy)
+ ** Note: This _must_ be done before calling any other DRI routines
+ ** (e.g., those called in AllocAndFetchScreenConfigs).
+ */
++#ifdef CHROMIUM
++ if (glx_direct)
++ dpyPriv->dricrDisplay = dricrCreateDisplay(dpy);
++#endif
+ if (glx_direct && glx_accel) {
+ dpyPriv->dri2Display = dri2CreateDisplay(dpy);
+ dpyPriv->driDisplay = driCreateDisplay(dpy);
--- mesa-only-argb-visuals.diff.orig
+++ mesa-only-argb-visuals.diff
@@ -0,0 +1,61 @@
+commit ebd2fd61610ba8df669f1e6638d1ca5f5422b22c
+Author: David Reveman <davidr@novell.com>
+Date: Thu Mar 12 14:13:08 2009 -0400
+
+ Avoid non 32-bit ARGB visuals when LIBGL_ONLY_ARGB_VISUALS is set.
+
+diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
+index af7de7c..283a2b8 100644
+--- a/src/glx/x11/glxext.c
++++ b/src/glx/x11/glxext.c
+@@ -504,6 +504,32 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
+ return modes;
+ }
+
++static __GLcontextModes *
++disableNonArgbVisuals (Display * dpy, int screen, __GLcontextModes *modes)
++{
++ __GLcontextModes *m;
++
++ for (m = modes; m != NULL; m = m->next) {
++ XVisualInfo *vi, tmpl;
++ int i;
++
++ tmpl.screen = screen;
++ tmpl.visualid = m->visualID;
++ vi = XGetVisualInfo( dpy, VisualScreenMask | VisualIDMask, &tmpl, &i );
++ if (vi) {
++ if (vi->depth != 32) {
++ m->visualID = GLX_DONT_CARE;
++ m->fbconfigID = GLX_DONT_CARE;
++ m->drawableType = 0;
++ m->renderType = 0;
++ }
++ XFree (vi);
++ }
++ }
++
++ return modes;
++}
++
+ static GLboolean
+ getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+ {
+@@ -530,6 +556,8 @@ getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+
+ out:
+ UnlockDisplay(dpy);
++ if ((getenv("LIBGL_ONLY_ARGB_VISUALS") != NULL))
++ psc->visuals = disableNonArgbVisuals (dpy, screen, psc->visuals);
+ return psc->visuals != NULL;
+ }
+
+@@ -577,6 +605,8 @@ getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+
+ out:
+ UnlockDisplay(dpy);
++ if ((getenv("LIBGL_ONLY_ARGB_VISUALS") != NULL))
++ psc->visuals = disableNonArgbVisuals (dpy, screen, psc->visuals);
+ return psc->configs != NULL;
+ }
+